Whamcloud - gitweb
LU-17015 gss: support large kerberos token for rpc sec ctxt
[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 run_test 27ga "$LFS getstripe with missing file (should return error)"
1804
1805 test_27i() {
1806         test_mkdir $DIR/$tdir
1807         touch $DIR/$tdir/$tfile || error "touch failed"
1808         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1809                 error "missing objects"
1810 }
1811 run_test 27i "$LFS getstripe with some objects"
1812
1813 test_27j() {
1814         test_mkdir $DIR/$tdir
1815         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1816                 error "setstripe failed" || true
1817 }
1818 run_test 27j "setstripe with bad stripe offset (should return error)"
1819
1820 test_27k() { # bug 2844
1821         test_mkdir $DIR/$tdir
1822         local file=$DIR/$tdir/$tfile
1823         local ll_max_blksize=$((4 * 1024 * 1024))
1824         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1825         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1826         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1827         dd if=/dev/zero of=$file bs=4k count=1
1828         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1829         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1830 }
1831 run_test 27k "limit i_blksize for broken user apps"
1832
1833 test_27l() {
1834         mcreate $DIR/$tfile || error "creating file"
1835         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1836                 error "setstripe should have failed" || true
1837 }
1838 run_test 27l "check setstripe permissions (should return error)"
1839
1840 test_27m() {
1841         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1842
1843         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1844                 skip_env "multiple clients -- skipping"
1845
1846         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1847                    head -n1)
1848         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1849                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1850         fi
1851         stack_trap simple_cleanup_common
1852         test_mkdir $DIR/$tdir
1853         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1854         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1855                 error "dd should fill OST0"
1856         i=2
1857         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1858                 i=$((i + 1))
1859                 [ $i -gt 256 ] && break
1860         done
1861         i=$((i + 1))
1862         touch $DIR/$tdir/$tfile.$i
1863         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1864             awk '{print $1}'| grep -w "0") ] &&
1865                 error "OST0 was full but new created file still use it"
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" || true
1871 }
1872 run_test 27m "create file while OST0 was full"
1873
1874 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1875 # if the OST isn't full anymore.
1876 reset_enospc() {
1877         local ostidx=${1:-""}
1878         local delay
1879         local ready
1880         local get_prealloc
1881
1882         local list=$(comma_list $(osts_nodes))
1883         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1884
1885         do_nodes $list lctl set_param fail_loc=0
1886         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1887         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1888                 awk '{print $1 * 2;exit;}')
1889         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1890                         grep -v \"^0$\""
1891         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1892 }
1893
1894 test_27n() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_precreations 0 0x80000215
1903         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1904         touch $DIR/$tdir/$tfile || error "touch failed"
1905         $LFS getstripe $DIR/$tdir/$tfile
1906         reset_enospc
1907 }
1908 run_test 27n "create file with some full OSTs"
1909
1910 test_27o() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_all_precreations 0x215
1919
1920         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1921
1922         reset_enospc
1923         rm -rf $DIR/$tdir/*
1924 }
1925 run_test 27o "create file with all full OSTs (should error)"
1926
1927 function create_and_checktime() {
1928         local fname=$1
1929         local loops=$2
1930         local i
1931
1932         for ((i=0; i < $loops; i++)); do
1933                 local start=$SECONDS
1934                 multiop $fname-$i Oc
1935                 ((SECONDS-start < TIMEOUT)) ||
1936                         error "creation took " $((SECONDS-$start)) && return 1
1937         done
1938 }
1939
1940 test_27oo() {
1941         local mdts=$(comma_list $(mdts_nodes))
1942
1943         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1944                 skip "Need MDS version at least 2.13.57"
1945
1946         local f0=$DIR/${tfile}-0
1947         local f1=$DIR/${tfile}-1
1948
1949         wait_delete_completed
1950
1951         # refill precreated objects
1952         $LFS setstripe -i0 -c1 $f0
1953
1954         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1955         # force QoS allocation policy
1956         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1957         stack_trap "do_nodes $mdts $LCTL set_param \
1958                 lov.*.qos_threshold_rr=$saved" EXIT
1959         sleep_maxage
1960
1961         # one OST is unavailable, but still have few objects preallocated
1962         stop ost1
1963         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1964                 rm -rf $f1 $DIR/$tdir*" EXIT
1965
1966         for ((i=0; i < 7; i++)); do
1967                 mkdir $DIR/$tdir$i || error "can't create dir"
1968                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1969                         error "can't set striping"
1970         done
1971         for ((i=0; i < 7; i++)); do
1972                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1973         done
1974         wait
1975 }
1976 run_test 27oo "don't let few threads to reserve too many objects"
1977
1978 test_27p() {
1979         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1981         remote_mds_nodsh && skip "remote MDS with nodsh"
1982         remote_ost_nodsh && skip "remote OST with nodsh"
1983
1984         reset_enospc
1985         rm -f $DIR/$tdir/$tfile
1986         test_mkdir $DIR/$tdir
1987
1988         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1989         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1990         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1991
1992         exhaust_precreations 0 0x80000215
1993         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1994         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1995         $LFS getstripe $DIR/$tdir/$tfile
1996
1997         reset_enospc
1998 }
1999 run_test 27p "append to a truncated file with some full OSTs"
2000
2001 test_27q() {
2002         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2004         remote_mds_nodsh && skip "remote MDS with nodsh"
2005         remote_ost_nodsh && skip "remote OST with nodsh"
2006
2007         reset_enospc
2008         rm -f $DIR/$tdir/$tfile
2009
2010         mkdir_on_mdt0 $DIR/$tdir
2011         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2012         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2013                 error "truncate $DIR/$tdir/$tfile failed"
2014         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2015
2016         exhaust_all_precreations 0x215
2017
2018         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2019         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27q "append to truncated file with all OSTs full (should error)"
2024
2025 test_27r() {
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2028         remote_mds_nodsh && skip "remote MDS with nodsh"
2029         remote_ost_nodsh && skip "remote OST with nodsh"
2030
2031         reset_enospc
2032         rm -f $DIR/$tdir/$tfile
2033         exhaust_precreations 0 0x80000215
2034
2035         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2040
2041 test_27s() { # bug 10725
2042         test_mkdir $DIR/$tdir
2043         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2044         local stripe_count=0
2045         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2046         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2047                 error "stripe width >= 2^32 succeeded" || true
2048
2049 }
2050 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2051
2052 test_27t() { # bug 10864
2053         WDIR=$(pwd)
2054         WLFS=$(which lfs)
2055         cd $DIR
2056         touch $tfile
2057         $WLFS getstripe $tfile
2058         cd $WDIR
2059 }
2060 run_test 27t "check that utils parse path correctly"
2061
2062 test_27u() { # bug 4900
2063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2064         remote_mds_nodsh && skip "remote MDS with nodsh"
2065
2066         local index
2067         local list=$(comma_list $(mdts_nodes))
2068
2069 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2070         do_nodes $list $LCTL set_param fail_loc=0x139
2071         test_mkdir -p $DIR/$tdir
2072         stack_trap "simple_cleanup_common 1000"
2073         createmany -o $DIR/$tdir/$tfile 1000
2074         do_nodes $list $LCTL set_param fail_loc=0
2075
2076         TLOG=$TMP/$tfile.getstripe
2077         $LFS getstripe $DIR/$tdir > $TLOG
2078         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2079         [[ $OBJS -gt 0 ]] &&
2080                 error "$OBJS objects created on OST-0. See $TLOG" ||
2081                 rm -f $TLOG
2082 }
2083 run_test 27u "skip object creation on OSC w/o objects"
2084
2085 test_27v() { # bug 4900
2086         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2088         remote_mds_nodsh && skip "remote MDS with nodsh"
2089         remote_ost_nodsh && skip "remote OST with nodsh"
2090
2091         exhaust_all_precreations 0x215
2092         reset_enospc
2093
2094         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2095
2096         touch $DIR/$tdir/$tfile
2097         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2098         # all except ost1
2099         for (( i=1; i < OSTCOUNT; i++ )); do
2100                 do_facet ost$i lctl set_param fail_loc=0x705
2101         done
2102         local START=`date +%s`
2103         createmany -o $DIR/$tdir/$tfile 32
2104
2105         local FINISH=`date +%s`
2106         local TIMEOUT=`lctl get_param -n timeout`
2107         local PROCESS=$((FINISH - START))
2108         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2109                error "$FINISH - $START >= $TIMEOUT / 2"
2110         sleep $((TIMEOUT / 2 - PROCESS))
2111         reset_enospc
2112 }
2113 run_test 27v "skip object creation on slow OST"
2114
2115 test_27w() { # bug 10997
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2118         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2119                 error "stripe size $size != 65536" || true
2120         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2121                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2122 }
2123 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2124
2125 test_27wa() {
2126         [[ $OSTCOUNT -lt 2 ]] &&
2127                 skip_env "skipping multiple stripe count/offset test"
2128
2129         test_mkdir $DIR/$tdir
2130         for i in $(seq 1 $OSTCOUNT); do
2131                 offset=$((i - 1))
2132                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2133                         error "setstripe -c $i -i $offset failed"
2134                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2135                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2136                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2137                 [ $index -ne $offset ] &&
2138                         error "stripe offset $index != $offset" || true
2139         done
2140 }
2141 run_test 27wa "check $LFS setstripe -c -i options"
2142
2143 test_27x() {
2144         remote_ost_nodsh && skip "remote OST with nodsh"
2145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2147
2148         OFFSET=$(($OSTCOUNT - 1))
2149         OSTIDX=0
2150         local OST=$(ostname_from_index $OSTIDX)
2151
2152         test_mkdir $DIR/$tdir
2153         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2154         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2155         sleep_maxage
2156         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2157         for i in $(seq 0 $OFFSET); do
2158                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2159                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2160                 error "OST0 was degraded but new created file still use it"
2161         done
2162         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2163 }
2164 run_test 27x "create files while OST0 is degraded"
2165
2166 test_27y() {
2167         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2168         remote_mds_nodsh && skip "remote MDS with nodsh"
2169         remote_ost_nodsh && skip "remote OST with nodsh"
2170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2171
2172         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2173         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2174                 osp.$mdtosc.prealloc_last_id)
2175         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2176                 osp.$mdtosc.prealloc_next_id)
2177         local fcount=$((last_id - next_id))
2178         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2179         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2180
2181         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2182                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2183         local OST_DEACTIVE_IDX=-1
2184         local OSC
2185         local OSTIDX
2186         local OST
2187
2188         for OSC in $MDS_OSCS; do
2189                 OST=$(osc_to_ost $OSC)
2190                 OSTIDX=$(index_from_ostuuid $OST)
2191                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2192                         OST_DEACTIVE_IDX=$OSTIDX
2193                 fi
2194                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2195                         echo $OSC "is Deactivated:"
2196                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2197                 fi
2198         done
2199
2200         OSTIDX=$(index_from_ostuuid $OST)
2201         test_mkdir $DIR/$tdir
2202         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2208                         echo $OST "is degraded:"
2209                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2210                                                 obdfilter.$OST.degraded=1
2211                 fi
2212         done
2213
2214         sleep_maxage
2215         createmany -o $DIR/$tdir/$tfile $fcount
2216
2217         for OSC in $MDS_OSCS; do
2218                 OST=$(osc_to_ost $OSC)
2219                 OSTIDX=$(index_from_ostuuid $OST)
2220                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2221                         echo $OST "is recovered from degraded:"
2222                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2223                                                 obdfilter.$OST.degraded=0
2224                 else
2225                         do_facet $SINGLEMDS lctl --device %$OSC activate
2226                 fi
2227         done
2228
2229         # all osp devices get activated, hence -1 stripe count restored
2230         local stripe_count=0
2231
2232         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2233         # devices get activated.
2234         sleep_maxage
2235         $LFS setstripe -c -1 $DIR/$tfile
2236         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2237         rm -f $DIR/$tfile
2238         [ $stripe_count -ne $OSTCOUNT ] &&
2239                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2240         return 0
2241 }
2242 run_test 27y "create files while OST0 is degraded and the rest inactive"
2243
2244 check_seq_oid()
2245 {
2246         log "check file $1"
2247
2248         lmm_count=$($LFS getstripe -c $1)
2249         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2250         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2251
2252         local old_ifs="$IFS"
2253         IFS=$'[:]'
2254         fid=($($LFS path2fid $1))
2255         IFS="$old_ifs"
2256
2257         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2258         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2259
2260         # compare lmm_seq and lu_fid->f_seq
2261         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2262         # compare lmm_object_id and lu_fid->oid
2263         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2264
2265         # check the trusted.fid attribute of the OST objects of the file
2266         local have_obdidx=false
2267         local stripe_nr=0
2268         $LFS getstripe $1 | while read obdidx oid hex seq; do
2269                 # skip lines up to and including "obdidx"
2270                 [ -z "$obdidx" ] && break
2271                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2272                 $have_obdidx || continue
2273
2274                 local ost=$((obdidx + 1))
2275                 local dev=$(ostdevname $ost)
2276                 local oid_hex
2277
2278                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2279
2280                 seq=$(echo $seq | sed -e "s/^0x//g")
2281                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2282                         oid_hex=$(echo $oid)
2283                 else
2284                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2285                 fi
2286                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2287
2288                 local ff=""
2289                 #
2290                 # Don't unmount/remount the OSTs if we don't need to do that.
2291                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2292                 # update too, until that use mount/ll_decode_filter_fid/mount.
2293                 # Re-enable when debugfs will understand new filter_fid.
2294                 #
2295                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2296                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2297                                 $dev 2>/dev/null" | grep "parent=")
2298                 fi
2299                 if [ -z "$ff" ]; then
2300                         stop ost$ost
2301                         mount_fstype ost$ost
2302                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2303                                 $(facet_mntpt ost$ost)/$obj_file)
2304                         unmount_fstype ost$ost
2305                         start ost$ost $dev $OST_MOUNT_OPTS
2306                         clients_up
2307                 fi
2308
2309                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2310
2311                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2312
2313                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2314                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2315                 #
2316                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2317                 #       stripe_size=1048576 component_id=1 component_start=0 \
2318                 #       component_end=33554432
2319                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2320                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2321                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2322                 local ff_pstripe
2323                 if grep -q 'stripe=' <<<$ff; then
2324                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2325                 else
2326                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2327                         # into f_ver in this case.  See comment on ff_parent.
2328                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2329                 fi
2330
2331                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2332                 [ $ff_pseq = $lmm_seq ] ||
2333                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2334                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2335                 [ $ff_poid = $lmm_oid ] ||
2336                         error "FF parent OID $ff_poid != $lmm_oid"
2337                 (($ff_pstripe == $stripe_nr)) ||
2338                         error "FF stripe $ff_pstripe != $stripe_nr"
2339
2340                 stripe_nr=$((stripe_nr + 1))
2341                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2342                         continue
2343                 if grep -q 'stripe_count=' <<<$ff; then
2344                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2345                                             -e 's/ .*//' <<<$ff)
2346                         [ $lmm_count = $ff_scnt ] ||
2347                                 error "FF stripe count $lmm_count != $ff_scnt"
2348                 fi
2349         done
2350 }
2351
2352 test_27z() {
2353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2354         remote_ost_nodsh && skip "remote OST with nodsh"
2355
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2358                 { error "setstripe -c -1 failed"; return 1; }
2359         # We need to send a write to every object to get parent FID info set.
2360         # This _should_ also work for setattr, but does not currently.
2361         # touch $DIR/$tdir/$tfile-1 ||
2362         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2363                 { error "dd $tfile-1 failed"; return 2; }
2364         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2365                 { error "setstripe -c -1 failed"; return 3; }
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2367                 { error "dd $tfile-2 failed"; return 4; }
2368
2369         # make sure write RPCs have been sent to OSTs
2370         sync; sleep 5; sync
2371
2372         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2373         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2374 }
2375 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2376
2377 test_27A() { # b=19102
2378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2379
2380         save_layout_restore_at_exit $MOUNT
2381         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2382         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2383                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2384         local default_size=$($LFS getstripe -S $MOUNT)
2385         local default_offset=$($LFS getstripe -i $MOUNT)
2386         local dsize=$(do_facet $SINGLEMDS \
2387                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2388         [ $default_size -eq $dsize ] ||
2389                 error "stripe size $default_size != $dsize"
2390         [ $default_offset -eq -1 ] ||
2391                 error "stripe offset $default_offset != -1"
2392 }
2393 run_test 27A "check filesystem-wide default LOV EA values"
2394
2395 test_27B() { # LU-2523
2396         test_mkdir $DIR/$tdir
2397         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2398         touch $DIR/$tdir/f0
2399         # open f1 with O_LOV_DELAY_CREATE
2400         # rename f0 onto f1
2401         # call setstripe ioctl on open file descriptor for f1
2402         # close
2403         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2404                 $DIR/$tdir/f0
2405
2406         rm -f $DIR/$tdir/f1
2407         # open f1 with O_LOV_DELAY_CREATE
2408         # unlink f1
2409         # call setstripe ioctl on open file descriptor for f1
2410         # close
2411         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2412
2413         # Allow multiop to fail in imitation of NFS's busted semantics.
2414         true
2415 }
2416 run_test 27B "call setstripe on open unlinked file/rename victim"
2417
2418 # 27C family tests full striping and overstriping
2419 test_27Ca() { #LU-2871
2420         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2421
2422         declare -a ost_idx
2423         local index
2424         local found
2425         local i
2426         local j
2427
2428         test_mkdir $DIR/$tdir
2429         cd $DIR/$tdir
2430         for i in $(seq 0 $((OSTCOUNT - 1))); do
2431                 # set stripe across all OSTs starting from OST$i
2432                 $LFS setstripe -i $i -c -1 $tfile$i
2433                 # get striping information
2434                 ost_idx=($($LFS getstripe $tfile$i |
2435                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2436                 echo "OST Index: ${ost_idx[*]}"
2437
2438                 # check the layout
2439                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2440                         error "${#ost_idx[@]} != $OSTCOUNT"
2441
2442                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2443                         found=0
2444                         for j in "${ost_idx[@]}"; do
2445                                 if [ $index -eq $j ]; then
2446                                         found=1
2447                                         break
2448                                 fi
2449                         done
2450                         [ $found = 1 ] ||
2451                                 error "Can not find $index in ${ost_idx[*]}"
2452                 done
2453         done
2454 }
2455 run_test 27Ca "check full striping across all OSTs"
2456
2457 test_27Cb() {
2458         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2459                 skip "server does not support overstriping"
2460         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2461                 skip_env "too many osts, skipping"
2462
2463         test_mkdir -p $DIR/$tdir
2464         local setcount=$(($OSTCOUNT * 2))
2465         [ $setcount -lt 160 ] || large_xattr_enabled ||
2466                 skip_env "ea_inode feature disabled"
2467
2468         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2469                 error "setstripe failed"
2470
2471         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2472         [ $count -eq $setcount ] ||
2473                 error "stripe count $count, should be $setcount"
2474
2475         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2476                 error "overstriped should be set in pattern"
2477
2478         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2479                 error "dd failed"
2480 }
2481 run_test 27Cb "more stripes than OSTs with -C"
2482
2483 test_27Cc() {
2484         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2485                 skip "server does not support overstriping"
2486         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2487
2488         test_mkdir -p $DIR/$tdir
2489         local setcount=$(($OSTCOUNT - 1))
2490
2491         [ $setcount -lt 160 ] || large_xattr_enabled ||
2492                 skip_env "ea_inode feature disabled"
2493
2494         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2495                 error "setstripe failed"
2496
2497         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2498         [ $count -eq $setcount ] ||
2499                 error "stripe count $count, should be $setcount"
2500
2501         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2502                 error "overstriped should not be set in pattern"
2503
2504         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2505                 error "dd failed"
2506 }
2507 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2508
2509 test_27Cd() {
2510         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2511                 skip "server does not support overstriping"
2512         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2513         large_xattr_enabled || skip_env "ea_inode feature disabled"
2514
2515         force_new_seq_all
2516
2517         test_mkdir -p $DIR/$tdir
2518         local setcount=$LOV_MAX_STRIPE_COUNT
2519
2520         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2521                 error "setstripe failed"
2522
2523         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2524         [ $count -eq $setcount ] ||
2525                 error "stripe count $count, should be $setcount"
2526
2527         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2528                 error "overstriped should be set in pattern"
2529
2530         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2531                 error "dd failed"
2532
2533         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2534 }
2535 run_test 27Cd "test maximum stripe count"
2536
2537 test_27Ce() {
2538         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2539                 skip "server does not support overstriping"
2540         test_mkdir -p $DIR/$tdir
2541
2542         pool_add $TESTNAME || error "Pool creation failed"
2543         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2544
2545         local setcount=8
2546
2547         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2548                 error "setstripe failed"
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Ce "test pool with overstriping"
2563
2564 test_27Cf() {
2565         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2566                 skip "server does not support overstriping"
2567         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2568                 skip_env "too many osts, skipping"
2569
2570         test_mkdir -p $DIR/$tdir
2571
2572         local setcount=$(($OSTCOUNT * 2))
2573         [ $setcount -lt 160 ] || large_xattr_enabled ||
2574                 skip_env "ea_inode feature disabled"
2575
2576         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2577                 error "setstripe failed"
2578
2579         echo 1 > $DIR/$tdir/$tfile
2580
2581         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2582         [ $count -eq $setcount ] ||
2583                 error "stripe count $count, should be $setcount"
2584
2585         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2586                 error "overstriped should be set in pattern"
2587
2588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2589                 error "dd failed"
2590
2591         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2592 }
2593 run_test 27Cf "test default inheritance with overstriping"
2594
2595 test_27Cg() {
2596         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2597                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2598
2599         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2600         (( $? != 0 )) || error "must be an error for not existent OST#"
2601 }
2602 run_test 27Cg "test setstripe with wrong OST idx"
2603
2604 test_27D() {
2605         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2606         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2607         remote_mds_nodsh && skip "remote MDS with nodsh"
2608
2609         local POOL=${POOL:-testpool}
2610         local first_ost=0
2611         local last_ost=$(($OSTCOUNT - 1))
2612         local ost_step=1
2613         local ost_list=$(seq $first_ost $ost_step $last_ost)
2614         local ost_range="$first_ost $last_ost $ost_step"
2615
2616         test_mkdir $DIR/$tdir
2617         pool_add $POOL || error "pool_add failed"
2618         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2619
2620         local skip27D
2621         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2622                 skip27D+="-s 29"
2623         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2624                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2625                         skip27D+=" -s 30,31"
2626         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2627           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2628                 skip27D+=" -s 32,33"
2629         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2630                 skip27D+=" -s 34"
2631         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2632                 error "llapi_layout_test failed"
2633
2634         destroy_test_pools || error "destroy test pools failed"
2635 }
2636 run_test 27D "validate llapi_layout API"
2637
2638 # Verify that default_easize is increased from its initial value after
2639 # accessing a widely striped file.
2640 test_27E() {
2641         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2642         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2643                 skip "client does not have LU-3338 fix"
2644
2645         # 72 bytes is the minimum space required to store striping
2646         # information for a file striped across one OST:
2647         # (sizeof(struct lov_user_md_v3) +
2648         #  sizeof(struct lov_user_ost_data_v1))
2649         local min_easize=72
2650         $LCTL set_param -n llite.*.default_easize $min_easize ||
2651                 error "lctl set_param failed"
2652         local easize=$($LCTL get_param -n llite.*.default_easize)
2653
2654         [ $easize -eq $min_easize ] ||
2655                 error "failed to set default_easize"
2656
2657         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2658                 error "setstripe failed"
2659         # In order to ensure stat() call actually talks to MDS we need to
2660         # do something drastic to this file to shake off all lock, e.g.
2661         # rename it (kills lookup lock forcing cache cleaning)
2662         mv $DIR/$tfile $DIR/${tfile}-1
2663         ls -l $DIR/${tfile}-1
2664         rm $DIR/${tfile}-1
2665
2666         easize=$($LCTL get_param -n llite.*.default_easize)
2667
2668         [ $easize -gt $min_easize ] ||
2669                 error "default_easize not updated"
2670 }
2671 run_test 27E "check that default extended attribute size properly increases"
2672
2673 test_27F() { # LU-5346/LU-7975
2674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2675         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2676         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2677                 skip "Need MDS version at least 2.8.51"
2678         remote_ost_nodsh && skip "remote OST with nodsh"
2679
2680         test_mkdir $DIR/$tdir
2681         rm -f $DIR/$tdir/f0
2682         $LFS setstripe -c 2 $DIR/$tdir
2683
2684         # stop all OSTs to reproduce situation for LU-7975 ticket
2685         for num in $(seq $OSTCOUNT); do
2686                 stop ost$num
2687         done
2688
2689         # open/create f0 with O_LOV_DELAY_CREATE
2690         # truncate f0 to a non-0 size
2691         # close
2692         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2693
2694         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2695         # open/write it again to force delayed layout creation
2696         cat /etc/hosts > $DIR/$tdir/f0 &
2697         catpid=$!
2698
2699         # restart OSTs
2700         for num in $(seq $OSTCOUNT); do
2701                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2702                         error "ost$num failed to start"
2703         done
2704
2705         wait $catpid || error "cat failed"
2706
2707         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2708         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2709                 error "wrong stripecount"
2710
2711 }
2712 run_test 27F "Client resend delayed layout creation with non-zero size"
2713
2714 test_27G() { #LU-10629
2715         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2716                 skip "Need MDS version at least 2.11.51"
2717         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2718         remote_mds_nodsh && skip "remote MDS with nodsh"
2719         local POOL=${POOL:-testpool}
2720         local ostrange="0 0 1"
2721
2722         test_mkdir $DIR/$tdir
2723         touch $DIR/$tdir/$tfile.nopool
2724         pool_add $POOL || error "pool_add failed"
2725         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2726         $LFS setstripe -p $POOL $DIR/$tdir
2727
2728         local pool=$($LFS getstripe -p $DIR/$tdir)
2729
2730         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2731         touch $DIR/$tdir/$tfile.default
2732         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2733         $LFS find $DIR/$tdir -type f --pool $POOL
2734         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2735         [[ "$found" == "2" ]] ||
2736                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2737
2738         $LFS setstripe -d $DIR/$tdir
2739
2740         pool=$($LFS getstripe -p -d $DIR/$tdir)
2741
2742         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2743 }
2744 run_test 27G "Clear OST pool from stripe"
2745
2746 test_27H() {
2747         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2748                 skip "Need MDS version newer than 2.11.54"
2749         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2750         test_mkdir $DIR/$tdir
2751         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2752         touch $DIR/$tdir/$tfile
2753         $LFS getstripe -c $DIR/$tdir/$tfile
2754         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2755                 error "two-stripe file doesn't have two stripes"
2756
2757         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2758         $LFS getstripe -y $DIR/$tdir/$tfile
2759         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2760              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2761                 error "expected l_ost_idx: [02]$ not matched"
2762
2763         # make sure ost list has been cleared
2764         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2765         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2766                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2767         touch $DIR/$tdir/f3
2768         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2769 }
2770 run_test 27H "Set specific OSTs stripe"
2771
2772 test_27I() {
2773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2775         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2776                 skip "Need MDS version newer than 2.12.52"
2777         local pool=$TESTNAME
2778         local ostrange="1 1 1"
2779
2780         save_layout_restore_at_exit $MOUNT
2781         $LFS setstripe -c 2 -i 0 $MOUNT
2782         pool_add $pool || error "pool_add failed"
2783         pool_add_targets $pool $ostrange ||
2784                 error "pool_add_targets failed"
2785         test_mkdir $DIR/$tdir
2786         $LFS setstripe -p $pool $DIR/$tdir
2787         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2788         $LFS getstripe $DIR/$tdir/$tfile
2789 }
2790 run_test 27I "check that root dir striping does not break parent dir one"
2791
2792 test_27J() {
2793         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2794                 skip "Need MDS version newer than 2.12.51"
2795
2796         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2797         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2798         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2799            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2800                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2801
2802         test_mkdir $DIR/$tdir
2803         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2804         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2805
2806         # create foreign file (raw way)
2807         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2808                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2809
2810         ! $LFS setstripe --foreign --flags foo \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile with '--flags foo' should fail"
2813
2814         ! $LFS setstripe --foreign --flags 0xffffffff \
2815                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2816                         error "creating $tfile w/ 0xffffffff flags should fail"
2817
2818         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2819                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2820
2821         # verify foreign file (raw way)
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2825         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_size: 73" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2830         parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_type: 1" ||
2832                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2833         parse_foreign_file -f $DIR/$tdir/$tfile |
2834                 grep "lov_foreign_flags: 0x0000DA08" ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2836         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2837                 grep "lov_foreign_value: 0x" |
2838                 sed -e 's/lov_foreign_value: 0x//')
2839         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2840         [[ $lov = ${lov2// /} ]] ||
2841                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2842
2843         # create foreign file (lfs + API)
2844         $LFS setstripe --foreign=none --flags 0xda08 \
2845                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: create failed"
2847
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2849                 grep "lfm_magic:.*0x0BD70BD0" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2851         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2854         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2856         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2857                 grep "lfm_flags:.*0x0000DA08" ||
2858                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2859         $LFS getstripe $DIR/$tdir/${tfile}2 |
2860                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2861                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2862
2863         # modify striping should fail
2864         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2865                 error "$DIR/$tdir/$tfile: setstripe should fail"
2866         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2868
2869         # R/W should fail
2870         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2871         cat $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: read should fail"
2873         cat /etc/passwd > $DIR/$tdir/$tfile &&
2874                 error "$DIR/$tdir/$tfile: write should fail"
2875         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2876                 error "$DIR/$tdir/${tfile}2: write should fail"
2877
2878         # chmod should work
2879         chmod 222 $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chmod failed"
2881         chmod 222 $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chmod failed"
2883
2884         # chown should work
2885         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2886                 error "$DIR/$tdir/$tfile: chown failed"
2887         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2888                 error "$DIR/$tdir/${tfile}2: chown failed"
2889
2890         # rename should work
2891         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2893         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2895
2896         #remove foreign file
2897         rm $DIR/$tdir/${tfile}.new ||
2898                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2899         rm $DIR/$tdir/${tfile}2.new ||
2900                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2901 }
2902 run_test 27J "basic ops on file with foreign LOV"
2903
2904 test_27K() {
2905         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2906                 skip "Need MDS version newer than 2.12.49"
2907
2908         test_mkdir $DIR/$tdir
2909         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2910         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2911
2912         # create foreign dir (raw way)
2913         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2914                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags foo \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir with '--flags foo' should fail"
2919
2920         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2921                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2922                         error "creating $tdir w/ 0xffffffff flags should fail"
2923
2924         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2925                 error "create_foreign_dir FAILED"
2926
2927         # verify foreign dir (raw way)
2928         parse_foreign_dir -d $DIR/$tdir/$tdir |
2929                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2930                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2933         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2934                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2935         parse_foreign_dir -d $DIR/$tdir/$tdir |
2936                 grep "lmv_foreign_flags: 55813$" ||
2937                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2938         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2939                 grep "lmv_foreign_value: 0x" |
2940                 sed 's/lmv_foreign_value: 0x//')
2941         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2942                 sed 's/ //g')
2943         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2944
2945         # create foreign dir (lfs + API)
2946         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2947                 $DIR/$tdir/${tdir}2 ||
2948                 error "$DIR/$tdir/${tdir}2: create failed"
2949
2950         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2951
2952         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2953                 grep "lfm_magic:.*0x0CD50CD0" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2955         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2956         # - sizeof(lfm_type) - sizeof(lfm_flags)
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2959         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2960                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2961         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2962                 grep "lfm_flags:.*0x0000DA05" ||
2963                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2964         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2965                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2966                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2967
2968         # file create in dir should fail
2969         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2970         touch $DIR/$tdir/${tdir}2/$tfile &&
2971                 error "$DIR/${tdir}2: file create should fail"
2972
2973         # chmod should work
2974         chmod 777 $DIR/$tdir/$tdir ||
2975                 error "$DIR/$tdir: chmod failed"
2976         chmod 777 $DIR/$tdir/${tdir}2 ||
2977                 error "$DIR/${tdir}2: chmod failed"
2978
2979         # chown should work
2980         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2981                 error "$DIR/$tdir: chown failed"
2982         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2983                 error "$DIR/${tdir}2: chown failed"
2984
2985         # rename should work
2986         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2987                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2988         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2989                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2990
2991         #remove foreign dir
2992         rmdir $DIR/$tdir/${tdir}.new ||
2993                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2994         rmdir $DIR/$tdir/${tdir}2.new ||
2995                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2996 }
2997 run_test 27K "basic ops on dir with foreign LMV"
2998
2999 test_27L() {
3000         remote_mds_nodsh && skip "remote MDS with nodsh"
3001
3002         local POOL=${POOL:-$TESTNAME}
3003
3004         pool_add $POOL || error "pool_add failed"
3005
3006         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3007                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3008                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3009 }
3010 run_test 27L "lfs pool_list gives correct pool name"
3011
3012 test_27M() {
3013         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3014                 skip "Need MDS version >= than 2.12.57"
3015         remote_mds_nodsh && skip "remote MDS with nodsh"
3016         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3017
3018         # Set default striping on directory
3019         local setcount=4
3020         local stripe_opt
3021         local mdts=$(comma_list $(mdts_nodes))
3022
3023         # if we run against a 2.12 server which lacks overstring support
3024         # then the connect_flag will not report overstriping, even if client
3025         # is 2.14+
3026         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3027                 stripe_opt="-C $setcount"
3028         elif (( $OSTCOUNT >= $setcount )); then
3029                 stripe_opt="-c $setcount"
3030         else
3031                 skip "server does not support overstriping"
3032         fi
3033
3034         test_mkdir $DIR/$tdir
3035
3036         # Validate existing append_* params and ensure restore
3037         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3038         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3039         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3040
3041         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3042         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3043         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3044
3045         $LFS setstripe $stripe_opt $DIR/$tdir
3046
3047         echo 1 > $DIR/$tdir/${tfile}.1
3048         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3049         (( $count == $setcount )) ||
3050                 error "(1) stripe count $count, should be $setcount"
3051
3052         local appendcount=$orig_count
3053         echo 1 >> $DIR/$tdir/${tfile}.2_append
3054         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3055         (( $count == $appendcount )) ||
3056                 error "(2)stripe count $count, should be $appendcount for append"
3057
3058         # Disable O_APPEND striping, verify it works
3059         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3060
3061         # Should now get the default striping, which is 4
3062         setcount=4
3063         echo 1 >> $DIR/$tdir/${tfile}.3_append
3064         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3065         (( $count == $setcount )) ||
3066                 error "(3) stripe count $count, should be $setcount"
3067
3068         # Try changing the stripe count for append files
3069         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3070
3071         # Append striping is now 2 (directory default is still 4)
3072         appendcount=2
3073         echo 1 >> $DIR/$tdir/${tfile}.4_append
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3075         (( $count == $appendcount )) ||
3076                 error "(4) stripe count $count, should be $appendcount for append"
3077
3078         # Test append stripe count of -1
3079         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3080         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3081                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3082                 touch $DIR/$tdir/$tfile.specific.{1..128}
3083         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3084
3085         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3086         appendcount=$OSTCOUNT
3087         echo 1 >> $DIR/$tdir/${tfile}.5
3088         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3089         (( $count == $appendcount )) ||
3090                 error "(5) stripe count $count, should be $appendcount for append"
3091
3092         # Set append striping back to default of 1
3093         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3094
3095         # Try a new default striping, PFL + DOM
3096         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3097
3098         # Create normal DOM file, DOM returns stripe count == 0
3099         setcount=0
3100         touch $DIR/$tdir/${tfile}.6
3101         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3102         (( $count == $setcount )) ||
3103                 error "(6) stripe count $count, should be $setcount"
3104
3105         # Show
3106         appendcount=1
3107         echo 1 >> $DIR/$tdir/${tfile}.7_append
3108         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3109         (( $count == $appendcount )) ||
3110                 error "(7) stripe count $count, should be $appendcount for append"
3111
3112         # Clean up DOM layout
3113         $LFS setstripe -d $DIR/$tdir
3114
3115         save_layout_restore_at_exit $MOUNT
3116         # Now test that append striping works when layout is from root
3117         $LFS setstripe -c 2 $MOUNT
3118         # Make a special directory for this
3119         mkdir $DIR/${tdir}/${tdir}.2
3120
3121         # Verify for normal file
3122         setcount=2
3123         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3124         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3125         (( $count == $setcount )) ||
3126                 error "(8) stripe count $count, should be $setcount"
3127
3128         appendcount=1
3129         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3130         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3131         (( $count == $appendcount )) ||
3132                 error "(9) stripe count $count, should be $appendcount for append"
3133
3134         # Now test O_APPEND striping with pools
3135         pool_add $TESTNAME || error "pool creation failed"
3136         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3137         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3138
3139         echo 1 >> $DIR/$tdir/${tfile}.10_append
3140
3141         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3142         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3143
3144         # Check that count is still correct
3145         appendcount=1
3146         echo 1 >> $DIR/$tdir/${tfile}.11_append
3147         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3148         (( $count == $appendcount )) ||
3149                 error "(11) stripe count $count, should be $appendcount for append"
3150
3151         # Disable O_APPEND stripe count, verify pool works separately
3152         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3153
3154         echo 1 >> $DIR/$tdir/${tfile}.12_append
3155
3156         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3157         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3158
3159         # Remove pool setting, verify it's not applied
3160         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3161
3162         echo 1 >> $DIR/$tdir/${tfile}.13_append
3163
3164         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3165         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3166 }
3167 run_test 27M "test O_APPEND striping"
3168
3169 test_27N() {
3170         combined_mgs_mds && skip "needs separate MGS/MDT"
3171
3172         pool_add $TESTNAME || error "pool_add failed"
3173         do_facet mgs "$LCTL pool_list $FSNAME" |
3174                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3175                 error "lctl pool_list on MGS failed"
3176 }
3177 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3178
3179 clean_foreign_symlink() {
3180         trap 0
3181         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3182         for i in $DIR/$tdir/* ; do
3183                 $LFS unlink_foreign $i || true
3184         done
3185 }
3186
3187 test_27O() {
3188         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3189                 skip "Need MDS version newer than 2.12.51"
3190
3191         test_mkdir $DIR/$tdir
3192         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3193         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3194
3195         trap clean_foreign_symlink EXIT
3196
3197         # enable foreign_symlink behaviour
3198         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3199
3200         # foreign symlink LOV format is a partial path by default
3201
3202         # create foreign file (lfs + API)
3203         $LFS setstripe --foreign=symlink --flags 0xda05 \
3204                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3205                 error "$DIR/$tdir/${tfile}: create failed"
3206
3207         $LFS getstripe -v $DIR/$tdir/${tfile} |
3208                 grep "lfm_magic:.*0x0BD70BD0" ||
3209                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3210         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3211                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3212         $LFS getstripe -v $DIR/$tdir/${tfile} |
3213                 grep "lfm_flags:.*0x0000DA05" ||
3214                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3215         $LFS getstripe $DIR/$tdir/${tfile} |
3216                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3217                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3218
3219         # modify striping should fail
3220         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3221                 error "$DIR/$tdir/$tfile: setstripe should fail"
3222
3223         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3224         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3225         cat /etc/passwd > $DIR/$tdir/$tfile &&
3226                 error "$DIR/$tdir/$tfile: write should fail"
3227
3228         # rename should succeed
3229         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3230                 error "$DIR/$tdir/$tfile: rename has failed"
3231
3232         #remove foreign_symlink file should fail
3233         rm $DIR/$tdir/${tfile}.new &&
3234                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3235
3236         #test fake symlink
3237         mkdir /tmp/${uuid1} ||
3238                 error "/tmp/${uuid1}: mkdir has failed"
3239         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3240                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3241         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3242         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3243                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3244         #read should succeed now
3245         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3246                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3247         #write should succeed now
3248         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3249                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3250         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3252         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3253                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3254
3255         #check that getstripe still works
3256         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3257                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3258
3259         # chmod should still succeed
3260         chmod 644 $DIR/$tdir/${tfile}.new ||
3261                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3262
3263         # chown should still succeed
3264         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3265                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3266
3267         # rename should still succeed
3268         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3269                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3270
3271         #remove foreign_symlink file should still fail
3272         rm $DIR/$tdir/${tfile} &&
3273                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3274
3275         #use special ioctl() to unlink foreign_symlink file
3276         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3277                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3278
3279 }
3280 run_test 27O "basic ops on foreign file of symlink type"
3281
3282 test_27P() {
3283         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3284                 skip "Need MDS version newer than 2.12.49"
3285
3286         test_mkdir $DIR/$tdir
3287         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3288         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3289
3290         trap clean_foreign_symlink EXIT
3291
3292         # enable foreign_symlink behaviour
3293         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3294
3295         # foreign symlink LMV format is a partial path by default
3296
3297         # create foreign dir (lfs + API)
3298         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3299                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3300                 error "$DIR/$tdir/${tdir}: create failed"
3301
3302         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3303
3304         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3305                 grep "lfm_magic:.*0x0CD50CD0" ||
3306                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3307         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3308                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3309         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3310                 grep "lfm_flags:.*0x0000DA05" ||
3311                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3312         $LFS getdirstripe $DIR/$tdir/${tdir} |
3313                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3314                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3315
3316         # file create in dir should fail
3317         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3318         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3319
3320         # rename should succeed
3321         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3322                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3323
3324         #remove foreign_symlink dir should fail
3325         rmdir $DIR/$tdir/${tdir}.new &&
3326                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3327
3328         #test fake symlink
3329         mkdir -p /tmp/${uuid1}/${uuid2} ||
3330                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3331         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3332                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3333         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3334         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3335                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3336         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3337                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3338
3339         #check that getstripe fails now that foreign_symlink enabled
3340         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3341                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3342
3343         # file create in dir should work now
3344         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3345                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3346         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3347                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3348         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3349                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3350
3351         # chmod should still succeed
3352         chmod 755 $DIR/$tdir/${tdir}.new ||
3353                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3354
3355         # chown should still succeed
3356         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3357                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3358
3359         # rename should still succeed
3360         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3361                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3362
3363         #remove foreign_symlink dir should still fail
3364         rmdir $DIR/$tdir/${tdir} &&
3365                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3366
3367         #use special ioctl() to unlink foreign_symlink file
3368         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3369                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3370
3371         #created file should still exist
3372         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3373                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3374         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3375                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3376 }
3377 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3378
3379 test_27Q() {
3380         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3381         stack_trap "rm -f $TMP/$tfile*"
3382
3383         test_mkdir $DIR/$tdir-1
3384         test_mkdir $DIR/$tdir-2
3385
3386         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3387         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3388
3389         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3390         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3391
3392         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3393         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3394
3395         # Create some bad symlinks and ensure that we don't loop
3396         # forever or something. These should return ELOOP (40) and
3397         # ENOENT (2) but I don't want to test for that because there's
3398         # always some weirdo architecture that needs to ruin
3399         # everything by defining these error numbers differently.
3400
3401         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3402         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3403
3404         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3405         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3406
3407         return 0
3408 }
3409 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3410
3411 test_27R() {
3412         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3413                 skip "need MDS 2.14.55 or later"
3414         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3415
3416         local testdir="$DIR/$tdir"
3417         test_mkdir -p $testdir
3418         stack_trap "rm -rf $testdir"
3419         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3420
3421         local f1="$testdir/f1"
3422         touch $f1 || error "failed to touch $f1"
3423         local count=$($LFS getstripe -c $f1)
3424         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3425
3426         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3427         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3428
3429         local maxcount=$(($OSTCOUNT - 1))
3430         local mdts=$(comma_list $(mdts_nodes))
3431         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3432         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3433
3434         local f2="$testdir/f2"
3435         touch $f2 || error "failed to touch $f2"
3436         local count=$($LFS getstripe -c $f2)
3437         (( $count == $maxcount )) || error "wrong stripe count"
3438 }
3439 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3440
3441 test_27T() {
3442         [ $(facet_host client) == $(facet_host ost1) ] &&
3443                 skip "need ost1 and client on different nodes"
3444
3445 #define OBD_FAIL_OSC_NO_GRANT            0x411
3446         $LCTL set_param fail_loc=0x20000411 fail_val=1
3447 #define OBD_FAIL_OST_ENOSPC              0x215
3448         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3449         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3450         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3451                 error "multiop failed"
3452 }
3453 run_test 27T "no eio on close on partial write due to enosp"
3454
3455 test_27U() {
3456         local dir=$DIR/$tdir
3457         local file=$dir/$tfile
3458         local append_pool=${TESTNAME}-append
3459         local normal_pool=${TESTNAME}-normal
3460         local pool
3461         local stripe_count
3462         local stripe_count2
3463         local mdts=$(comma_list $(mdts_nodes))
3464
3465         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3466                 skip "Need MDS version at least 2.15.51 for append pool feature"
3467
3468         # Validate existing append_* params and ensure restore
3469         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3470         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3471         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3472
3473         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3474         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3475         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3476
3477         pool_add $append_pool || error "pool creation failed"
3478         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3479
3480         pool_add $normal_pool || error "pool creation failed"
3481         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3482
3483         test_mkdir $dir
3484         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3485
3486         echo XXX >> $file.1
3487         $LFS getstripe $file.1
3488
3489         pool=$($LFS getstripe -p $file.1)
3490         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3491
3492         stripe_count2=$($LFS getstripe -c $file.1)
3493         ((stripe_count2 == stripe_count)) ||
3494                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3495
3496         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3497
3498         echo XXX >> $file.2
3499         $LFS getstripe $file.2
3500
3501         pool=$($LFS getstripe -p $file.2)
3502         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3503
3504         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3505
3506         echo XXX >> $file.3
3507         $LFS getstripe $file.3
3508
3509         stripe_count2=$($LFS getstripe -c $file.3)
3510         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3511 }
3512 run_test 27U "append pool and stripe count work with composite default layout"
3513
3514 test_27V() {
3515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3516         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3517
3518         local dir=$DIR/$tdir
3519         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3520         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3521         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3522         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3523         local pid
3524
3525         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3526
3527         do_facet mds1 $LCTL set_param $lod_param=0
3528         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3529
3530         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3531         stack_trap "rm -rf $dir"
3532
3533         # exercise race in LU-16981 with deactivating OST while creating a file
3534         (
3535                 while true; do
3536                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3537                         sleep 0.1
3538                         do_facet mds1 \
3539                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3540                 done
3541         ) &
3542
3543         pid=$!
3544         stack_trap "kill -9 $pid"
3545
3546         # errors here are OK so ignore them (just don't want to crash)
3547         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3548
3549         return 0
3550 }
3551 run_test 27V "creating widely striped file races with deactivating OST"
3552
3553 # createtest also checks that device nodes are created and
3554 # then visible correctly (#2091)
3555 test_28() { # bug 2091
3556         test_mkdir $DIR/d28
3557         $CREATETEST $DIR/d28/ct || error "createtest failed"
3558 }
3559 run_test 28 "create/mknod/mkdir with bad file types ============"
3560
3561 test_29() {
3562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3563
3564         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3565                 disable_opencache
3566                 stack_trap "restore_opencache"
3567         }
3568
3569         sync; sleep 1; sync # flush out any dirty pages from previous tests
3570         cancel_lru_locks
3571         test_mkdir $DIR/d29
3572         touch $DIR/d29/foo
3573         log 'first d29'
3574         ls -l $DIR/d29
3575
3576         local locks_orig=$(total_used_locks mdc)
3577         (( $locks_orig != 0 )) || error "No mdc lock count"
3578
3579         local locks_unused_orig=$(total_unused_locks mdc)
3580
3581         log 'second d29'
3582         ls -l $DIR/d29
3583         log 'done'
3584
3585         local locks_current=$(total_used_locks mdc)
3586
3587         local locks_unused_current=$(total_unused_locks mdc)
3588
3589         if (( $locks_current > $locks_orig )); then
3590                 $LCTL set_param -n ldlm.dump_namespaces ""
3591                 error "CURRENT: $locks_current > $locks_orig"
3592         fi
3593         if (( $locks_unused_current > $locks_unused_orig )); then
3594                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3595         fi
3596 }
3597 run_test 29 "IT_GETATTR regression  ============================"
3598
3599 test_30a() { # was test_30
3600         cp $(which ls) $DIR || cp /bin/ls $DIR
3601         $DIR/ls / || error "Can't execute binary from lustre"
3602         rm $DIR/ls
3603 }
3604 run_test 30a "execute binary from Lustre (execve) =============="
3605
3606 test_30b() {
3607         cp `which ls` $DIR || cp /bin/ls $DIR
3608         chmod go+rx $DIR/ls
3609         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3610         rm $DIR/ls
3611 }
3612 run_test 30b "execute binary from Lustre as non-root ==========="
3613
3614 test_30c() { # b=22376
3615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3616
3617         cp $(which ls) $DIR || cp /bin/ls $DIR
3618         chmod a-rw $DIR/ls
3619         cancel_lru_locks mdc
3620         cancel_lru_locks osc
3621         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3622         rm -f $DIR/ls
3623 }
3624 run_test 30c "execute binary from Lustre without read perms ===="
3625
3626 test_30d() {
3627         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3628
3629         for i in {1..10}; do
3630                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3631                 local PID=$!
3632                 sleep 1
3633                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3634                 wait $PID || error "executing dd from Lustre failed"
3635                 rm -f $DIR/$tfile
3636         done
3637
3638         rm -f $DIR/dd
3639 }
3640 run_test 30d "execute binary from Lustre while clear locks"
3641
3642 test_31a() {
3643         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3644         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3645 }
3646 run_test 31a "open-unlink file =================================="
3647
3648 test_31b() {
3649         touch $DIR/f31 || error "touch $DIR/f31 failed"
3650         ln $DIR/f31 $DIR/f31b || error "ln failed"
3651         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3652         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3653 }
3654 run_test 31b "unlink file with multiple links while open ======="
3655
3656 test_31c() {
3657         touch $DIR/f31 || error "touch $DIR/f31 failed"
3658         ln $DIR/f31 $DIR/f31c || error "ln failed"
3659         multiop_bg_pause $DIR/f31 O_uc ||
3660                 error "multiop_bg_pause for $DIR/f31 failed"
3661         MULTIPID=$!
3662         $MULTIOP $DIR/f31c Ouc
3663         kill -USR1 $MULTIPID
3664         wait $MULTIPID
3665 }
3666 run_test 31c "open-unlink file with multiple links ============="
3667
3668 test_31d() {
3669         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3670         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3671 }
3672 run_test 31d "remove of open directory ========================="
3673
3674 test_31e() { # bug 2904
3675         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3676 }
3677 run_test 31e "remove of open non-empty directory ==============="
3678
3679 test_31f() { # bug 4554
3680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3681
3682         set -vx
3683         test_mkdir $DIR/d31f
3684         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3685         cp /etc/hosts $DIR/d31f
3686         ls -l $DIR/d31f
3687         $LFS getstripe $DIR/d31f/hosts
3688         multiop_bg_pause $DIR/d31f D_c || return 1
3689         MULTIPID=$!
3690
3691         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3692         test_mkdir $DIR/d31f
3693         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3694         cp /etc/hosts $DIR/d31f
3695         ls -l $DIR/d31f
3696         $LFS getstripe $DIR/d31f/hosts
3697         multiop_bg_pause $DIR/d31f D_c || return 1
3698         MULTIPID2=$!
3699
3700         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3701         wait $MULTIPID || error "first opendir $MULTIPID failed"
3702
3703         sleep 6
3704
3705         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3706         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3707         set +vx
3708 }
3709 run_test 31f "remove of open directory with open-unlink file ==="
3710
3711 test_31g() {
3712         echo "-- cross directory link --"
3713         test_mkdir -c1 $DIR/${tdir}ga
3714         test_mkdir -c1 $DIR/${tdir}gb
3715         touch $DIR/${tdir}ga/f
3716         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3717         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3718         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3719         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3720         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3721 }
3722 run_test 31g "cross directory link==============="
3723
3724 test_31h() {
3725         echo "-- cross directory link --"
3726         test_mkdir -c1 $DIR/${tdir}
3727         test_mkdir -c1 $DIR/${tdir}/dir
3728         touch $DIR/${tdir}/f
3729         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3730         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3731         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3732         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3733         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3734 }
3735 run_test 31h "cross directory link under child==============="
3736
3737 test_31i() {
3738         echo "-- cross directory link --"
3739         test_mkdir -c1 $DIR/$tdir
3740         test_mkdir -c1 $DIR/$tdir/dir
3741         touch $DIR/$tdir/dir/f
3742         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3743         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3744         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3745         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3746         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3747 }
3748 run_test 31i "cross directory link under parent==============="
3749
3750 test_31j() {
3751         test_mkdir -c1 -p $DIR/$tdir
3752         test_mkdir -c1 -p $DIR/$tdir/dir1
3753         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3754         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3755         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3756         return 0
3757 }
3758 run_test 31j "link for directory"
3759
3760 test_31k() {
3761         test_mkdir -c1 -p $DIR/$tdir
3762         touch $DIR/$tdir/s
3763         touch $DIR/$tdir/exist
3764         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3765         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3766         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3767         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3768         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3769         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3770         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3771         return 0
3772 }
3773 run_test 31k "link to file: the same, non-existing, dir"
3774
3775 test_31l() {
3776         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3777
3778         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3779         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3780                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3781
3782         touch $DIR/$tfile || error "create failed"
3783         mkdir $DIR/$tdir || error "mkdir failed"
3784         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3785 }
3786 run_test 31l "link to file: target dir has trailing slash"
3787
3788 test_31m() {
3789         mkdir $DIR/d31m
3790         touch $DIR/d31m/s
3791         mkdir $DIR/d31m2
3792         touch $DIR/d31m2/exist
3793         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3794         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3795         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3796         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3797         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3798         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3799         return 0
3800 }
3801 run_test 31m "link to file: the same, non-existing, dir"
3802
3803 test_31n() {
3804         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3805         nlink=$(stat --format=%h $DIR/$tfile)
3806         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3807         local fd=$(free_fd)
3808         local cmd="exec $fd<$DIR/$tfile"
3809         eval $cmd
3810         cmd="exec $fd<&-"
3811         trap "eval $cmd" EXIT
3812         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3813         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3814         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3815         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3816         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3817         eval $cmd
3818 }
3819 run_test 31n "check link count of unlinked file"
3820
3821 link_one() {
3822         local tempfile=$(mktemp $1_XXXXXX)
3823         link $tempfile $1 2> /dev/null &&
3824                 echo "$BASHPID: link $tempfile to $1 succeeded"
3825         unlink $tempfile
3826 }
3827
3828 test_31o() { # LU-2901
3829         test_mkdir $DIR/$tdir
3830         for LOOP in $(seq 100); do
3831                 rm -f $DIR/$tdir/$tfile*
3832                 for THREAD in $(seq 8); do
3833                         link_one $DIR/$tdir/$tfile.$LOOP &
3834                 done
3835                 wait
3836                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3837                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3838                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3839                         break || true
3840         done
3841 }
3842 run_test 31o "duplicate hard links with same filename"
3843
3844 test_31p() {
3845         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3846
3847         test_mkdir $DIR/$tdir
3848         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3849         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3850
3851         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3852                 error "open unlink test1 failed"
3853         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3854                 error "open unlink test2 failed"
3855
3856         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3857                 error "test1 still exists"
3858         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3859                 error "test2 still exists"
3860 }
3861 run_test 31p "remove of open striped directory"
3862
3863 test_31q() {
3864         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3865
3866         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3867         index=$($LFS getdirstripe -i $DIR/$tdir)
3868         [ $index -eq 3 ] || error "first stripe index $index != 3"
3869         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3870         [ $index -eq 1 ] || error "second stripe index $index != 1"
3871
3872         # when "-c <stripe_count>" is set, the number of MDTs specified after
3873         # "-i" should equal to the stripe count
3874         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3875 }
3876 run_test 31q "create striped directory on specific MDTs"
3877
3878 #LU-14949
3879 test_31r() {
3880         touch $DIR/$tfile.target
3881         touch $DIR/$tfile.source
3882
3883         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3884         $LCTL set_param fail_loc=0x1419 fail_val=3
3885         cat $DIR/$tfile.target &
3886         CATPID=$!
3887
3888         # Guarantee open is waiting before we get here
3889         sleep 1
3890         mv $DIR/$tfile.source $DIR/$tfile.target
3891
3892         wait $CATPID
3893         RC=$?
3894         if [[ $RC -ne 0 ]]; then
3895                 error "open with cat failed, rc=$RC"
3896         fi
3897 }
3898 run_test 31r "open-rename(replace) race"
3899
3900 cleanup_test32_mount() {
3901         local rc=0
3902         trap 0
3903         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3904         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3905         losetup -d $loopdev || true
3906         rm -rf $DIR/$tdir
3907         return $rc
3908 }
3909
3910 test_32a() {
3911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3912
3913         echo "== more mountpoints and symlinks ================="
3914         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3915         trap cleanup_test32_mount EXIT
3916         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3917         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3918                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3919         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3920                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3921         cleanup_test32_mount
3922 }
3923 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3924
3925 test_32b() {
3926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3927
3928         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3929         trap cleanup_test32_mount EXIT
3930         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3931         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3932                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3933         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3934                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3935         cleanup_test32_mount
3936 }
3937 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3938
3939 test_32c() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3943         trap cleanup_test32_mount EXIT
3944         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3945         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3946                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3947         test_mkdir -p $DIR/$tdir/d2/test_dir
3948         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3949                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3950         cleanup_test32_mount
3951 }
3952 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3953
3954 test_32d() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         test_mkdir -p $DIR/$tdir/d2/test_dir
3963         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3964                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3965         cleanup_test32_mount
3966 }
3967 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3968
3969 test_32e() {
3970         rm -fr $DIR/$tdir
3971         test_mkdir -p $DIR/$tdir/tmp
3972         local tmp_dir=$DIR/$tdir/tmp
3973         ln -s $DIR/$tdir $tmp_dir/symlink11
3974         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3975         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3976         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3977 }
3978 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3979
3980 test_32f() {
3981         rm -fr $DIR/$tdir
3982         test_mkdir -p $DIR/$tdir/tmp
3983         local tmp_dir=$DIR/$tdir/tmp
3984         ln -s $DIR/$tdir $tmp_dir/symlink11
3985         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3986         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3987         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3988 }
3989 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3990
3991 test_32g() {
3992         local tmp_dir=$DIR/$tdir/tmp
3993         test_mkdir -p $tmp_dir
3994         test_mkdir $DIR/${tdir}2
3995         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3996         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3997         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3998         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3999         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4000         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4001 }
4002 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4003
4004 test_32h() {
4005         rm -fr $DIR/$tdir $DIR/${tdir}2
4006         tmp_dir=$DIR/$tdir/tmp
4007         test_mkdir -p $tmp_dir
4008         test_mkdir $DIR/${tdir}2
4009         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4010         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4011         ls $tmp_dir/symlink12 || error "listing symlink12"
4012         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4013 }
4014 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4015
4016 test_32i() {
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4020         trap cleanup_test32_mount EXIT
4021         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4022         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4023                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4024         touch $DIR/$tdir/test_file
4025         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4026                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4027         cleanup_test32_mount
4028 }
4029 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4030
4031 test_32j() {
4032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4033
4034         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4035         trap cleanup_test32_mount EXIT
4036         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4037         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4038                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4039         touch $DIR/$tdir/test_file
4040         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4041                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4042         cleanup_test32_mount
4043 }
4044 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4045
4046 test_32k() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048
4049         rm -fr $DIR/$tdir
4050         trap cleanup_test32_mount EXIT
4051         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         test_mkdir -p $DIR/$tdir/d2
4055         touch $DIR/$tdir/d2/test_file || error "touch failed"
4056         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4057                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4058         cleanup_test32_mount
4059 }
4060 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4061
4062 test_32l() {
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064
4065         rm -fr $DIR/$tdir
4066         trap cleanup_test32_mount EXIT
4067         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4068         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4069                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4070         test_mkdir -p $DIR/$tdir/d2
4071         touch $DIR/$tdir/d2/test_file || error "touch failed"
4072         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4073                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4074         cleanup_test32_mount
4075 }
4076 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4077
4078 test_32m() {
4079         rm -fr $DIR/d32m
4080         test_mkdir -p $DIR/d32m/tmp
4081         TMP_DIR=$DIR/d32m/tmp
4082         ln -s $DIR $TMP_DIR/symlink11
4083         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4084         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4085                 error "symlink11 not a link"
4086         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4087                 error "symlink01 not a link"
4088 }
4089 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4090
4091 test_32n() {
4092         rm -fr $DIR/d32n
4093         test_mkdir -p $DIR/d32n/tmp
4094         TMP_DIR=$DIR/d32n/tmp
4095         ln -s $DIR $TMP_DIR/symlink11
4096         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4097         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4098         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4099 }
4100 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4101
4102 test_32o() {
4103         touch $DIR/$tfile
4104         test_mkdir -p $DIR/d32o/tmp
4105         TMP_DIR=$DIR/d32o/tmp
4106         ln -s $DIR/$tfile $TMP_DIR/symlink12
4107         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4108         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4109                 error "symlink12 not a link"
4110         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4111         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4112                 error "$DIR/d32o/tmp/symlink12 not file type"
4113         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4114                 error "$DIR/d32o/symlink02 not file type"
4115 }
4116 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4117
4118 test_32p() {
4119         log 32p_1
4120         rm -fr $DIR/d32p
4121         log 32p_2
4122         rm -f $DIR/$tfile
4123         log 32p_3
4124         touch $DIR/$tfile
4125         log 32p_4
4126         test_mkdir -p $DIR/d32p/tmp
4127         log 32p_5
4128         TMP_DIR=$DIR/d32p/tmp
4129         log 32p_6
4130         ln -s $DIR/$tfile $TMP_DIR/symlink12
4131         log 32p_7
4132         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4133         log 32p_8
4134         cat $DIR/d32p/tmp/symlink12 ||
4135                 error "Can't open $DIR/d32p/tmp/symlink12"
4136         log 32p_9
4137         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4138         log 32p_10
4139 }
4140 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4141
4142 test_32q() {
4143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4144
4145         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4146         trap cleanup_test32_mount EXIT
4147         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4148         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4149         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4150                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4151         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4152         cleanup_test32_mount
4153 }
4154 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4155
4156 test_32r() {
4157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4158
4159         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4160         trap cleanup_test32_mount EXIT
4161         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4162         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4163         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4164                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4165         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4166         cleanup_test32_mount
4167 }
4168 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4169
4170 test_33aa() {
4171         rm -f $DIR/$tfile
4172         touch $DIR/$tfile
4173         chmod 444 $DIR/$tfile
4174         chown $RUNAS_ID $DIR/$tfile
4175         log 33_1
4176         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4177         log 33_2
4178 }
4179 run_test 33aa "write file with mode 444 (should return error)"
4180
4181 test_33a() {
4182         rm -fr $DIR/$tdir
4183         test_mkdir $DIR/$tdir
4184         chown $RUNAS_ID $DIR/$tdir
4185         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4186                 error "$RUNAS create $tdir/$tfile failed"
4187         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4188                 error "open RDWR" || true
4189 }
4190 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4191
4192 test_33b() {
4193         rm -fr $DIR/$tdir
4194         test_mkdir $DIR/$tdir
4195         chown $RUNAS_ID $DIR/$tdir
4196         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4197 }
4198 run_test 33b "test open file with malformed flags (No panic)"
4199
4200 test_33c() {
4201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4202         remote_ost_nodsh && skip "remote OST with nodsh"
4203
4204         local ostnum
4205         local ostname
4206         local write_bytes
4207         local all_zeros
4208
4209         all_zeros=true
4210         test_mkdir $DIR/$tdir
4211         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4212
4213         sync
4214         for ostnum in $(seq $OSTCOUNT); do
4215                 # test-framework's OST numbering is one-based, while Lustre's
4216                 # is zero-based
4217                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4218                 # check if at least some write_bytes stats are counted
4219                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4220                               obdfilter.$ostname.stats |
4221                               awk '/^write_bytes/ {print $7}' )
4222                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4223                 if (( ${write_bytes:-0} > 0 )); then
4224                         all_zeros=false
4225                         break
4226                 fi
4227         done
4228
4229         $all_zeros || return 0
4230
4231         # Write four bytes
4232         echo foo > $DIR/$tdir/bar
4233         # Really write them
4234         sync
4235
4236         # Total up write_bytes after writing.  We'd better find non-zeros.
4237         for ostnum in $(seq $OSTCOUNT); do
4238                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4239                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4240                               obdfilter/$ostname/stats |
4241                               awk '/^write_bytes/ {print $7}' )
4242                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4243                 if (( ${write_bytes:-0} > 0 )); then
4244                         all_zeros=false
4245                         break
4246                 fi
4247         done
4248
4249         if $all_zeros; then
4250                 for ostnum in $(seq $OSTCOUNT); do
4251                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4252                         echo "Check write_bytes is in obdfilter.*.stats:"
4253                         do_facet ost$ostnum lctl get_param -n \
4254                                 obdfilter.$ostname.stats
4255                 done
4256                 error "OST not keeping write_bytes stats (b=22312)"
4257         fi
4258 }
4259 run_test 33c "test write_bytes stats"
4260
4261 test_33d() {
4262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4264
4265         local MDTIDX=1
4266         local remote_dir=$DIR/$tdir/remote_dir
4267
4268         test_mkdir $DIR/$tdir
4269         $LFS mkdir -i $MDTIDX $remote_dir ||
4270                 error "create remote directory failed"
4271
4272         touch $remote_dir/$tfile
4273         chmod 444 $remote_dir/$tfile
4274         chown $RUNAS_ID $remote_dir/$tfile
4275
4276         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4277
4278         chown $RUNAS_ID $remote_dir
4279         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4280                                         error "create" || true
4281         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4282                                     error "open RDWR" || true
4283         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4284 }
4285 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4286
4287 test_33e() {
4288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4289
4290         mkdir $DIR/$tdir
4291
4292         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4293         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4294         mkdir $DIR/$tdir/local_dir
4295
4296         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4297         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4298         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4299
4300         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4301                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4302
4303         rmdir $DIR/$tdir/* || error "rmdir failed"
4304
4305         umask 777
4306         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4307         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4308         mkdir $DIR/$tdir/local_dir
4309
4310         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4311         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4312         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4313
4314         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4315                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4316
4317         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4318
4319         umask 000
4320         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4321         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4322         mkdir $DIR/$tdir/local_dir
4323
4324         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4325         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4326         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4327
4328         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4329                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4330 }
4331 run_test 33e "mkdir and striped directory should have same mode"
4332
4333 cleanup_33f() {
4334         trap 0
4335         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4336 }
4337
4338 test_33f() {
4339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4340         remote_mds_nodsh && skip "remote MDS with nodsh"
4341
4342         mkdir $DIR/$tdir
4343         chmod go+rwx $DIR/$tdir
4344         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4345         trap cleanup_33f EXIT
4346
4347         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4348                 error "cannot create striped directory"
4349
4350         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4351                 error "cannot create files in striped directory"
4352
4353         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4354                 error "cannot remove files in striped directory"
4355
4356         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4357                 error "cannot remove striped directory"
4358
4359         cleanup_33f
4360 }
4361 run_test 33f "nonroot user can create, access, and remove a striped directory"
4362
4363 test_33g() {
4364         mkdir -p $DIR/$tdir/dir2
4365
4366         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4367         echo $err
4368         [[ $err =~ "exists" ]] || error "Not exists error"
4369 }
4370 run_test 33g "nonroot user create already existing root created file"
4371
4372 sub_33h() {
4373         local hash_type=$1
4374         local count=250
4375
4376         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4377                 error "lfs mkdir -H $hash_type $tdir failed"
4378         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4379
4380         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4381         local index2
4382         local fname
4383
4384         for fname in $DIR/$tdir/$tfile.bak \
4385                      $DIR/$tdir/$tfile.SAV \
4386                      $DIR/$tdir/$tfile.orig \
4387                      $DIR/$tdir/$tfile~; do
4388                 touch $fname || error "touch $fname failed"
4389                 index2=$($LFS getstripe -m $fname)
4390                 (( $index == $index2 )) ||
4391                         error "$fname MDT index mismatch $index != $index2"
4392         done
4393
4394         local failed=0
4395         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4396         local pattern
4397
4398         for pattern in ${patterns[*]}; do
4399                 echo "pattern $pattern"
4400                 fname=$DIR/$tdir/$pattern
4401                 for (( i = 0; i < $count; i++ )); do
4402                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4403                                 error "mktemp $DIR/$tdir/$pattern failed"
4404                         index2=$($LFS getstripe -m $fname)
4405                         (( $index == $index2 )) && continue
4406
4407                         failed=$((failed + 1))
4408                         echo "$fname MDT index mismatch $index != $index2"
4409                 done
4410         done
4411
4412         echo "$failed/$count MDT index mismatches, expect ~2-4"
4413         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4414
4415         local same=0
4416         local expect
4417
4418         # verify that "crush" is still broken with all files on same MDT,
4419         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4420         [[ "$hash_type" == "crush" ]] && expect=$count ||
4421                 expect=$((count / MDSCOUNT))
4422
4423         # crush2 doesn't put all-numeric suffixes on the same MDT,
4424         # filename like $tfile.12345678 should *not* be considered temp
4425         for pattern in ${patterns[*]}; do
4426                 local base=${pattern%%X*}
4427                 local suff=${pattern#$base}
4428
4429                 echo "pattern $pattern"
4430                 for (( i = 0; i < $count; i++ )); do
4431                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4432                         touch $fname || error "touch $fname failed"
4433                         index2=$($LFS getstripe -m $fname)
4434                         (( $index != $index2 )) && continue
4435
4436                         same=$((same + 1))
4437                 done
4438         done
4439
4440         # the number of "bad" hashes is random, as it depends on the random
4441         # filenames generated by "mktemp".  Allow some margin in the results.
4442         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4443         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4444            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4445                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4446         same=0
4447
4448         # crush2 doesn't put suffixes with special characters on the same MDT
4449         # filename like $tfile.txt.1234 should *not* be considered temp
4450         for pattern in ${patterns[*]}; do
4451                 local base=${pattern%%X*}
4452                 local suff=${pattern#$base}
4453
4454                 pattern=$base...${suff/XXX}
4455                 echo "pattern=$pattern"
4456                 for (( i = 0; i < $count; i++ )); do
4457                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4458                                 error "touch $fname failed"
4459                         index2=$($LFS getstripe -m $fname)
4460                         (( $index != $index2 )) && continue
4461
4462                         same=$((same + 1))
4463                 done
4464         done
4465
4466         # the number of "bad" hashes is random, as it depends on the random
4467         # filenames generated by "mktemp".  Allow some margin in the results.
4468         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4469         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4470            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4471                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4472 }
4473
4474 test_33h() {
4475         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4476         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4477                 skip "Need MDS version at least 2.13.50"
4478
4479         sub_33h crush
4480 }
4481 run_test 33h "temp file is located on the same MDT as target (crush)"
4482
4483 test_33hh() {
4484         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4485         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4486         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4487                 skip "Need MDS version at least 2.15.0 for crush2"
4488
4489         sub_33h crush2
4490 }
4491 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4492
4493 test_33i()
4494 {
4495         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4496
4497         local FNAME=$(str_repeat 'f' 250)
4498
4499         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4500         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4501
4502         local count
4503         local total
4504
4505         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4506
4507         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4508
4509         lctl --device %$MDC deactivate
4510         stack_trap "lctl --device %$MDC activate"
4511         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4512         total=$(\ls -l $DIR/$tdir | wc -l)
4513         # "ls -l" will list total in the first line
4514         total=$((total - 1))
4515         (( total + count == 1000 )) ||
4516                 error "ls list $total files, $count files on MDT1"
4517 }
4518 run_test 33i "striped directory can be accessed when one MDT is down"
4519
4520 test_33j() {
4521         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4522
4523         mkdir -p $DIR/$tdir/
4524
4525         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4526                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4527
4528         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4529                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4530
4531         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4532                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4533
4534         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4535                 error "-D was not specified, but still failed"
4536 }
4537 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4538
4539 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4540 test_34a() {
4541         rm -f $DIR/f34
4542         $MCREATE $DIR/f34 || error "mcreate failed"
4543         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4544                 error "getstripe failed"
4545         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4546         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4547                 error "getstripe failed"
4548         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4549                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4550 }
4551 run_test 34a "truncate file that has not been opened ==========="
4552
4553 test_34b() {
4554         [ ! -f $DIR/f34 ] && test_34a
4555         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4556                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4557         $OPENFILE -f O_RDONLY $DIR/f34
4558         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4559                 error "getstripe failed"
4560         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4561                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4562 }
4563 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4564
4565 test_34c() {
4566         [ ! -f $DIR/f34 ] && test_34a
4567         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4568                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4569         $OPENFILE -f O_RDWR $DIR/f34
4570         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4571                 error "$LFS getstripe failed"
4572         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4573                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4574 }
4575 run_test 34c "O_RDWR opening file-with-size works =============="
4576
4577 test_34d() {
4578         [ ! -f $DIR/f34 ] && test_34a
4579         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4580                 error "dd failed"
4581         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4582                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4583         rm $DIR/f34
4584 }
4585 run_test 34d "write to sparse file ============================="
4586
4587 test_34e() {
4588         rm -f $DIR/f34e
4589         $MCREATE $DIR/f34e || error "mcreate failed"
4590         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4591         $CHECKSTAT -s 1000 $DIR/f34e ||
4592                 error "Size of $DIR/f34e not equal to 1000 bytes"
4593         $OPENFILE -f O_RDWR $DIR/f34e
4594         $CHECKSTAT -s 1000 $DIR/f34e ||
4595                 error "Size of $DIR/f34e not equal to 1000 bytes"
4596 }
4597 run_test 34e "create objects, some with size and some without =="
4598
4599 test_34f() { # bug 6242, 6243
4600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4601
4602         SIZE34F=48000
4603         rm -f $DIR/f34f
4604         $MCREATE $DIR/f34f || error "mcreate failed"
4605         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4606         dd if=$DIR/f34f of=$TMP/f34f
4607         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4608         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4609         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4610         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4611         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4612 }
4613 run_test 34f "read from a file with no objects until EOF ======="
4614
4615 test_34g() {
4616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4617
4618         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4619                 error "dd failed"
4620         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4621         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4622                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4623         cancel_lru_locks osc
4624         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4625                 error "wrong size after lock cancel"
4626
4627         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4628         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4629                 error "expanding truncate failed"
4630         cancel_lru_locks osc
4631         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4632                 error "wrong expanded size after lock cancel"
4633 }
4634 run_test 34g "truncate long file ==============================="
4635
4636 test_34h() {
4637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4638
4639         local gid=10
4640         local sz=1000
4641
4642         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4643         sync # Flush the cache so that multiop below does not block on cache
4644              # flush when getting the group lock
4645         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4646         MULTIPID=$!
4647
4648         # Since just timed wait is not good enough, let's do a sync write
4649         # that way we are sure enough time for a roundtrip + processing
4650         # passed + 2 seconds of extra margin.
4651         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4652         rm $DIR/${tfile}-1
4653         sleep 2
4654
4655         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4656                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4657                 kill -9 $MULTIPID
4658         fi
4659         wait $MULTIPID
4660         local nsz=`stat -c %s $DIR/$tfile`
4661         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4662 }
4663 run_test 34h "ftruncate file under grouplock should not block"
4664
4665 test_35a() {
4666         cp /bin/sh $DIR/f35a
4667         chmod 444 $DIR/f35a
4668         chown $RUNAS_ID $DIR/f35a
4669         $RUNAS $DIR/f35a && error || true
4670         rm $DIR/f35a
4671 }
4672 run_test 35a "exec file with mode 444 (should return and not leak)"
4673
4674 test_36a() {
4675         rm -f $DIR/f36
4676         utime $DIR/f36 || error "utime failed for MDS"
4677 }
4678 run_test 36a "MDS utime check (mknod, utime)"
4679
4680 test_36b() {
4681         echo "" > $DIR/f36
4682         utime $DIR/f36 || error "utime failed for OST"
4683 }
4684 run_test 36b "OST utime check (open, utime)"
4685
4686 test_36c() {
4687         rm -f $DIR/d36/f36
4688         test_mkdir $DIR/d36
4689         chown $RUNAS_ID $DIR/d36
4690         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4691 }
4692 run_test 36c "non-root MDS utime check (mknod, utime)"
4693
4694 test_36d() {
4695         [ ! -d $DIR/d36 ] && test_36c
4696         echo "" > $DIR/d36/f36
4697         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4698 }
4699 run_test 36d "non-root OST utime check (open, utime)"
4700
4701 test_36e() {
4702         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4703
4704         test_mkdir $DIR/$tdir
4705         touch $DIR/$tdir/$tfile
4706         $RUNAS utime $DIR/$tdir/$tfile &&
4707                 error "utime worked, expected failure" || true
4708 }
4709 run_test 36e "utime on non-owned file (should return error)"
4710
4711 subr_36fh() {
4712         local fl="$1"
4713         local LANG_SAVE=$LANG
4714         local LC_LANG_SAVE=$LC_LANG
4715         export LANG=C LC_LANG=C # for date language
4716
4717         DATESTR="Dec 20  2000"
4718         test_mkdir $DIR/$tdir
4719         lctl set_param fail_loc=$fl
4720         date; date +%s
4721         cp /etc/hosts $DIR/$tdir/$tfile
4722         sync & # write RPC generated with "current" inode timestamp, but delayed
4723         sleep 1
4724         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4725         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4726         cancel_lru_locks $OSC
4727         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4728         date; date +%s
4729         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4730                 echo "BEFORE: $LS_BEFORE" && \
4731                 echo "AFTER : $LS_AFTER" && \
4732                 echo "WANT  : $DATESTR" && \
4733                 error "$DIR/$tdir/$tfile timestamps changed" || true
4734
4735         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4736 }
4737
4738 test_36f() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4742         subr_36fh "0x80000214"
4743 }
4744 run_test 36f "utime on file racing with OST BRW write =========="
4745
4746 test_36g() {
4747         remote_ost_nodsh && skip "remote OST with nodsh"
4748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4749         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4750                 skip "Need MDS version at least 2.12.51"
4751
4752         local fmd_max_age
4753         local fmd
4754         local facet="ost1"
4755         local tgt="obdfilter"
4756
4757         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4758
4759         test_mkdir $DIR/$tdir
4760         fmd_max_age=$(do_facet $facet \
4761                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4762                 head -n 1")
4763
4764         echo "FMD max age: ${fmd_max_age}s"
4765         touch $DIR/$tdir/$tfile
4766         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4767                 gawk '{cnt=cnt+$1}  END{print cnt}')
4768         echo "FMD before: $fmd"
4769         [[ $fmd == 0 ]] &&
4770                 error "FMD wasn't create by touch"
4771         sleep $((fmd_max_age + 12))
4772         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4773                 gawk '{cnt=cnt+$1}  END{print cnt}')
4774         echo "FMD after: $fmd"
4775         [[ $fmd == 0 ]] ||
4776                 error "FMD wasn't expired by ping"
4777 }
4778 run_test 36g "FMD cache expiry ====================="
4779
4780 test_36h() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4784         subr_36fh "0x80000227"
4785 }
4786 run_test 36h "utime on file racing with OST BRW write =========="
4787
4788 test_36i() {
4789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4790
4791         test_mkdir $DIR/$tdir
4792         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4793
4794         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4795         local new_mtime=$((mtime + 200))
4796
4797         #change Modify time of striped dir
4798         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4799                         error "change mtime failed"
4800
4801         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4802
4803         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4804 }
4805 run_test 36i "change mtime on striped directory"
4806
4807 # test_37 - duplicate with tests 32q 32r
4808
4809 test_38() {
4810         local file=$DIR/$tfile
4811         touch $file
4812         openfile -f O_DIRECTORY $file
4813         local RC=$?
4814         local ENOTDIR=20
4815         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4816         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4817 }
4818 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4819
4820 test_39a() { # was test_39
4821         touch $DIR/$tfile
4822         touch $DIR/${tfile}2
4823 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4824 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4825 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4826         sleep 2
4827         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4828         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4829                 echo "mtime"
4830                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4831                 echo "atime"
4832                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4833                 echo "ctime"
4834                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4835                 error "O_TRUNC didn't change timestamps"
4836         fi
4837 }
4838 run_test 39a "mtime changed on create"
4839
4840 test_39b() {
4841         test_mkdir -c1 $DIR/$tdir
4842         cp -p /etc/passwd $DIR/$tdir/fopen
4843         cp -p /etc/passwd $DIR/$tdir/flink
4844         cp -p /etc/passwd $DIR/$tdir/funlink
4845         cp -p /etc/passwd $DIR/$tdir/frename
4846         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4847
4848         sleep 1
4849         echo "aaaaaa" >> $DIR/$tdir/fopen
4850         echo "aaaaaa" >> $DIR/$tdir/flink
4851         echo "aaaaaa" >> $DIR/$tdir/funlink
4852         echo "aaaaaa" >> $DIR/$tdir/frename
4853
4854         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4855         local link_new=`stat -c %Y $DIR/$tdir/flink`
4856         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4857         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4858
4859         cat $DIR/$tdir/fopen > /dev/null
4860         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4861         rm -f $DIR/$tdir/funlink2
4862         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4863
4864         for (( i=0; i < 2; i++ )) ; do
4865                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4866                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4867                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4868                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4869
4870                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4871                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4872                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4873                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4874
4875                 cancel_lru_locks $OSC
4876                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4877         done
4878 }
4879 run_test 39b "mtime change on open, link, unlink, rename  ======"
4880
4881 # this should be set to past
4882 TEST_39_MTIME=`date -d "1 year ago" +%s`
4883
4884 # bug 11063
4885 test_39c() {
4886         touch $DIR1/$tfile
4887         sleep 2
4888         local mtime0=`stat -c %Y $DIR1/$tfile`
4889
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891         local mtime1=`stat -c %Y $DIR1/$tfile`
4892         [ "$mtime1" = $TEST_39_MTIME ] || \
4893                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4894
4895         local d1=`date +%s`
4896         echo hello >> $DIR1/$tfile
4897         local d2=`date +%s`
4898         local mtime2=`stat -c %Y $DIR1/$tfile`
4899         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4900                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4901
4902         mv $DIR1/$tfile $DIR1/$tfile-1
4903
4904         for (( i=0; i < 2; i++ )) ; do
4905                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4906                 [ "$mtime2" = "$mtime3" ] || \
4907                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4908
4909                 cancel_lru_locks $OSC
4910                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4911         done
4912 }
4913 run_test 39c "mtime change on rename ==========================="
4914
4915 # bug 21114
4916 test_39d() {
4917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4918
4919         touch $DIR1/$tfile
4920         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4921
4922         for (( i=0; i < 2; i++ )) ; do
4923                 local mtime=`stat -c %Y $DIR1/$tfile`
4924                 [ $mtime = $TEST_39_MTIME ] || \
4925                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4926
4927                 cancel_lru_locks $OSC
4928                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4929         done
4930 }
4931 run_test 39d "create, utime, stat =============================="
4932
4933 # bug 21114
4934 test_39e() {
4935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4936
4937         touch $DIR1/$tfile
4938         local mtime1=`stat -c %Y $DIR1/$tfile`
4939
4940         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4941
4942         for (( i=0; i < 2; i++ )) ; do
4943                 local mtime2=`stat -c %Y $DIR1/$tfile`
4944                 [ $mtime2 = $TEST_39_MTIME ] || \
4945                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4946
4947                 cancel_lru_locks $OSC
4948                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4949         done
4950 }
4951 run_test 39e "create, stat, utime, stat ========================"
4952
4953 # bug 21114
4954 test_39f() {
4955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4956
4957         touch $DIR1/$tfile
4958         mtime1=`stat -c %Y $DIR1/$tfile`
4959
4960         sleep 2
4961         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4962
4963         for (( i=0; i < 2; i++ )) ; do
4964                 local mtime2=`stat -c %Y $DIR1/$tfile`
4965                 [ $mtime2 = $TEST_39_MTIME ] || \
4966                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4967
4968                 cancel_lru_locks $OSC
4969                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4970         done
4971 }
4972 run_test 39f "create, stat, sleep, utime, stat ================="
4973
4974 # bug 11063
4975 test_39g() {
4976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4977
4978         echo hello >> $DIR1/$tfile
4979         local mtime1=`stat -c %Y $DIR1/$tfile`
4980
4981         sleep 2
4982         chmod o+r $DIR1/$tfile
4983
4984         for (( i=0; i < 2; i++ )) ; do
4985                 local mtime2=`stat -c %Y $DIR1/$tfile`
4986                 [ "$mtime1" = "$mtime2" ] || \
4987                         error "lost mtime: $mtime2, should be $mtime1"
4988
4989                 cancel_lru_locks $OSC
4990                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4991         done
4992 }
4993 run_test 39g "write, chmod, stat ==============================="
4994
4995 # bug 11063
4996 test_39h() {
4997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4998
4999         touch $DIR1/$tfile
5000         sleep 1
5001
5002         local d1=`date`
5003         echo hello >> $DIR1/$tfile
5004         local mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5007         local d2=`date`
5008         if [ "$d1" != "$d2" ]; then
5009                 echo "write and touch not within one second"
5010         else
5011                 for (( i=0; i < 2; i++ )) ; do
5012                         local mtime2=`stat -c %Y $DIR1/$tfile`
5013                         [ "$mtime2" = $TEST_39_MTIME ] || \
5014                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5015
5016                         cancel_lru_locks $OSC
5017                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5018                 done
5019         fi
5020 }
5021 run_test 39h "write, utime within one second, stat ============="
5022
5023 test_39i() {
5024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5025
5026         touch $DIR1/$tfile
5027         sleep 1
5028
5029         echo hello >> $DIR1/$tfile
5030         local mtime1=`stat -c %Y $DIR1/$tfile`
5031
5032         mv $DIR1/$tfile $DIR1/$tfile-1
5033
5034         for (( i=0; i < 2; i++ )) ; do
5035                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5036
5037                 [ "$mtime1" = "$mtime2" ] || \
5038                         error "lost mtime: $mtime2, should be $mtime1"
5039
5040                 cancel_lru_locks $OSC
5041                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5042         done
5043 }
5044 run_test 39i "write, rename, stat =============================="
5045
5046 test_39j() {
5047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5048
5049         start_full_debug_logging
5050         touch $DIR1/$tfile
5051         sleep 1
5052
5053         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5054         lctl set_param fail_loc=0x80000412
5055         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5056                 error "multiop failed"
5057         local multipid=$!
5058         local mtime1=`stat -c %Y $DIR1/$tfile`
5059
5060         mv $DIR1/$tfile $DIR1/$tfile-1
5061
5062         kill -USR1 $multipid
5063         wait $multipid || error "multiop close failed"
5064
5065         for (( i=0; i < 2; i++ )) ; do
5066                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5067                 [ "$mtime1" = "$mtime2" ] ||
5068                         error "mtime is lost on close: $mtime2, " \
5069                               "should be $mtime1"
5070
5071                 cancel_lru_locks
5072                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5073         done
5074         lctl set_param fail_loc=0
5075         stop_full_debug_logging
5076 }
5077 run_test 39j "write, rename, close, stat ======================="
5078
5079 test_39k() {
5080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5081
5082         touch $DIR1/$tfile
5083         sleep 1
5084
5085         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5086         local multipid=$!
5087         local mtime1=`stat -c %Y $DIR1/$tfile`
5088
5089         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5090
5091         kill -USR1 $multipid
5092         wait $multipid || error "multiop close failed"
5093
5094         for (( i=0; i < 2; i++ )) ; do
5095                 local mtime2=`stat -c %Y $DIR1/$tfile`
5096
5097                 [ "$mtime2" = $TEST_39_MTIME ] || \
5098                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5099
5100                 cancel_lru_locks
5101                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5102         done
5103 }
5104 run_test 39k "write, utime, close, stat ========================"
5105
5106 # this should be set to future
5107 TEST_39_ATIME=`date -d "1 year" +%s`
5108
5109 test_39l() {
5110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5111         remote_mds_nodsh && skip "remote MDS with nodsh"
5112
5113         local atime_diff=$(do_facet $SINGLEMDS \
5114                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5115         rm -rf $DIR/$tdir
5116         mkdir_on_mdt0 $DIR/$tdir
5117
5118         # test setting directory atime to future
5119         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5120         local atime=$(stat -c %X $DIR/$tdir)
5121         [ "$atime" = $TEST_39_ATIME ] ||
5122                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5123
5124         # test setting directory atime from future to now
5125         local now=$(date +%s)
5126         touch -a -d @$now $DIR/$tdir
5127
5128         atime=$(stat -c %X $DIR/$tdir)
5129         [ "$atime" -eq "$now"  ] ||
5130                 error "atime is not updated from future: $atime, $now"
5131
5132         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5133         sleep 3
5134
5135         # test setting directory atime when now > dir atime + atime_diff
5136         local d1=$(date +%s)
5137         ls $DIR/$tdir
5138         local d2=$(date +%s)
5139         cancel_lru_locks mdc
5140         atime=$(stat -c %X $DIR/$tdir)
5141         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5142                 error "atime is not updated  : $atime, should be $d2"
5143
5144         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5145         sleep 3
5146
5147         # test not setting directory atime when now < dir atime + atime_diff
5148         ls $DIR/$tdir
5149         cancel_lru_locks mdc
5150         atime=$(stat -c %X $DIR/$tdir)
5151         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5152                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5153
5154         do_facet $SINGLEMDS \
5155                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5156 }
5157 run_test 39l "directory atime update ==========================="
5158
5159 test_39m() {
5160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5161
5162         touch $DIR1/$tfile
5163         sleep 2
5164         local far_past_mtime=$(date -d "May 29 1953" +%s)
5165         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5166
5167         touch -m -d @$far_past_mtime $DIR1/$tfile
5168         touch -a -d @$far_past_atime $DIR1/$tfile
5169
5170         for (( i=0; i < 2; i++ )) ; do
5171                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5172                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5173                         error "atime or mtime set incorrectly"
5174
5175                 cancel_lru_locks $OSC
5176                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5177         done
5178 }
5179 run_test 39m "test atime and mtime before 1970"
5180
5181 test_39n() { # LU-3832
5182         remote_mds_nodsh && skip "remote MDS with nodsh"
5183
5184         local atime_diff=$(do_facet $SINGLEMDS \
5185                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5186         local atime0
5187         local atime1
5188         local atime2
5189
5190         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5191
5192         rm -rf $DIR/$tfile
5193         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5194         atime0=$(stat -c %X $DIR/$tfile)
5195
5196         sleep 5
5197         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5198         atime1=$(stat -c %X $DIR/$tfile)
5199
5200         sleep 5
5201         cancel_lru_locks mdc
5202         cancel_lru_locks osc
5203         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5204         atime2=$(stat -c %X $DIR/$tfile)
5205
5206         do_facet $SINGLEMDS \
5207                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5208
5209         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5210         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5211 }
5212 run_test 39n "check that O_NOATIME is honored"
5213
5214 test_39o() {
5215         TESTDIR=$DIR/$tdir/$tfile
5216         [ -e $TESTDIR ] && rm -rf $TESTDIR
5217         mkdir -p $TESTDIR
5218         cd $TESTDIR
5219         links1=2
5220         ls
5221         mkdir a b
5222         ls
5223         links2=$(stat -c %h .)
5224         [ $(($links1 + 2)) != $links2 ] &&
5225                 error "wrong links count $(($links1 + 2)) != $links2"
5226         rmdir b
5227         links3=$(stat -c %h .)
5228         [ $(($links1 + 1)) != $links3 ] &&
5229                 error "wrong links count $links1 != $links3"
5230         return 0
5231 }
5232 run_test 39o "directory cached attributes updated after create"
5233
5234 test_39p() {
5235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5236
5237         local MDTIDX=1
5238         TESTDIR=$DIR/$tdir/$tdir
5239         [ -e $TESTDIR ] && rm -rf $TESTDIR
5240         test_mkdir -p $TESTDIR
5241         cd $TESTDIR
5242         links1=2
5243         ls
5244         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5245         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5246         ls
5247         links2=$(stat -c %h .)
5248         [ $(($links1 + 2)) != $links2 ] &&
5249                 error "wrong links count $(($links1 + 2)) != $links2"
5250         rmdir remote_dir2
5251         links3=$(stat -c %h .)
5252         [ $(($links1 + 1)) != $links3 ] &&
5253                 error "wrong links count $links1 != $links3"
5254         return 0
5255 }
5256 run_test 39p "remote directory cached attributes updated after create ========"
5257
5258 test_39r() {
5259         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5260                 skip "no atime update on old OST"
5261         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5262                 skip_env "ldiskfs only test"
5263         fi
5264
5265         local saved_adiff
5266         saved_adiff=$(do_facet ost1 \
5267                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5268         stack_trap "do_facet ost1 \
5269                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5270
5271         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5272
5273         $LFS setstripe -i 0 $DIR/$tfile
5274         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5275                 error "can't write initial file"
5276         cancel_lru_locks osc
5277
5278         # exceed atime_diff and access file
5279         sleep 10
5280         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5281                 error "can't udpate atime"
5282
5283         local atime_cli=$(stat -c %X $DIR/$tfile)
5284         echo "client atime: $atime_cli"
5285         # allow atime update to be written to device
5286         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5287         sleep 5
5288
5289         local ostdev=$(ostdevname 1)
5290         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5291         local seq=${fid[3]#0x}
5292         local oid=${fid[1]}
5293         local oid_hex
5294
5295         if [ $seq == 0 ]; then
5296                 oid_hex=${fid[1]}
5297         else
5298                 oid_hex=${fid[2]#0x}
5299         fi
5300         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5301         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5302
5303         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5304         local atime_ost=$(do_facet ost1 "$cmd" |&
5305                           awk -F'[: ]' '/atime:/ { print $4 }')
5306         (( atime_cli == atime_ost )) ||
5307                 error "atime on client $atime_cli != ost $atime_ost"
5308 }
5309 run_test 39r "lazy atime update on OST"
5310
5311 test_39q() { # LU-8041
5312         local testdir=$DIR/$tdir
5313         mkdir -p $testdir
5314         multiop_bg_pause $testdir D_c || error "multiop failed"
5315         local multipid=$!
5316         cancel_lru_locks mdc
5317         kill -USR1 $multipid
5318         local atime=$(stat -c %X $testdir)
5319         [ "$atime" -ne 0 ] || error "atime is zero"
5320 }
5321 run_test 39q "close won't zero out atime"
5322
5323 test_39s() {
5324         local atime0
5325         local atime1
5326         local atime2
5327         local atime3
5328         local atime4
5329
5330         umount_client $MOUNT
5331         mount_client $MOUNT relatime
5332
5333         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5334         atime0=$(stat -c %X $DIR/$tfile)
5335
5336         # First read updates atime
5337         sleep 1
5338         cat $DIR/$tfile >/dev/null
5339         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5340
5341         # Next reads do not update atime
5342         sleep 1
5343         cat $DIR/$tfile >/dev/null
5344         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5345
5346         # If mtime is greater than atime, atime is updated
5347         sleep 1
5348         touch -m $DIR/$tfile # (mtime = now)
5349         sleep 1
5350         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5351         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5352
5353         # Next reads do not update atime
5354         sleep 1
5355         cat $DIR/$tfile >/dev/null
5356         atime4=$(stat -c %X $DIR/$tfile)
5357
5358         # Remount the client to clear 'relatime' option
5359         remount_client $MOUNT
5360
5361         (( atime0 < atime1 )) ||
5362                 error "atime $atime0 should be smaller than $atime1"
5363         (( atime1 == atime2 )) ||
5364                 error "atime $atime1 was updated to $atime2"
5365         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5366         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5367 }
5368 run_test 39s "relatime is supported"
5369
5370 test_40() {
5371         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5372         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5373                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5374         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5375                 error "$tfile is not 4096 bytes in size"
5376 }
5377 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5378
5379 test_41() {
5380         # bug 1553
5381         small_write $DIR/f41 18
5382 }
5383 run_test 41 "test small file write + fstat ====================="
5384
5385 count_ost_writes() {
5386         lctl get_param -n ${OSC}.*.stats |
5387                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5388                         END { printf("%0.0f", writes) }'
5389 }
5390
5391 # decent default
5392 WRITEBACK_SAVE=500
5393 DIRTY_RATIO_SAVE=40
5394 MAX_DIRTY_RATIO=50
5395 BG_DIRTY_RATIO_SAVE=10
5396 MAX_BG_DIRTY_RATIO=25
5397
5398 start_writeback() {
5399         trap 0
5400         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5401         # dirty_ratio, dirty_background_ratio
5402         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5403                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5404                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5405                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5406         else
5407                 # if file not here, we are a 2.4 kernel
5408                 kill -CONT `pidof kupdated`
5409         fi
5410 }
5411
5412 stop_writeback() {
5413         # setup the trap first, so someone cannot exit the test at the
5414         # exact wrong time and mess up a machine
5415         trap start_writeback EXIT
5416         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5417         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5418                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5419                 sysctl -w vm.dirty_writeback_centisecs=0
5420                 sysctl -w vm.dirty_writeback_centisecs=0
5421                 # save and increase /proc/sys/vm/dirty_ratio
5422                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5423                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5424                 # save and increase /proc/sys/vm/dirty_background_ratio
5425                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5426                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5427         else
5428                 # if file not here, we are a 2.4 kernel
5429                 kill -STOP `pidof kupdated`
5430         fi
5431 }
5432
5433 # ensure that all stripes have some grant before we test client-side cache
5434 setup_test42() {
5435         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5436                 dd if=/dev/zero of=$i bs=4k count=1
5437                 rm $i
5438         done
5439 }
5440
5441 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5442 # file truncation, and file removal.
5443 test_42a() {
5444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5445
5446         setup_test42
5447         cancel_lru_locks $OSC
5448         stop_writeback
5449         sync; sleep 1; sync # just to be safe
5450         BEFOREWRITES=`count_ost_writes`
5451         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5452         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5453         AFTERWRITES=`count_ost_writes`
5454         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5455                 error "$BEFOREWRITES < $AFTERWRITES"
5456         start_writeback
5457 }
5458 run_test 42a "ensure that we don't flush on close"
5459
5460 test_42b() {
5461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5462
5463         setup_test42
5464         cancel_lru_locks $OSC
5465         stop_writeback
5466         sync
5467         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5468         BEFOREWRITES=$(count_ost_writes)
5469         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5470         AFTERWRITES=$(count_ost_writes)
5471         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5472                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5473         fi
5474         BEFOREWRITES=$(count_ost_writes)
5475         sync || error "sync: $?"
5476         AFTERWRITES=$(count_ost_writes)
5477         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5478                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5479         fi
5480         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5481         start_writeback
5482         return 0
5483 }
5484 run_test 42b "test destroy of file with cached dirty data ======"
5485
5486 # if these tests just want to test the effect of truncation,
5487 # they have to be very careful.  consider:
5488 # - the first open gets a {0,EOF}PR lock
5489 # - the first write conflicts and gets a {0, count-1}PW
5490 # - the rest of the writes are under {count,EOF}PW
5491 # - the open for truncate tries to match a {0,EOF}PR
5492 #   for the filesize and cancels the PWs.
5493 # any number of fixes (don't get {0,EOF} on open, match
5494 # composite locks, do smarter file size management) fix
5495 # this, but for now we want these tests to verify that
5496 # the cancellation with truncate intent works, so we
5497 # start the file with a full-file pw lock to match against
5498 # until the truncate.
5499 trunc_test() {
5500         test=$1
5501         file=$DIR/$test
5502         offset=$2
5503         cancel_lru_locks $OSC
5504         stop_writeback
5505         # prime the file with 0,EOF PW to match
5506         touch $file
5507         $TRUNCATE $file 0
5508         sync; sync
5509         # now the real test..
5510         dd if=/dev/zero of=$file bs=1024 count=100
5511         BEFOREWRITES=`count_ost_writes`
5512         $TRUNCATE $file $offset
5513         cancel_lru_locks $OSC
5514         AFTERWRITES=`count_ost_writes`
5515         start_writeback
5516 }
5517
5518 test_42c() {
5519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5520
5521         trunc_test 42c 1024
5522         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5523                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5524         rm $file
5525 }
5526 run_test 42c "test partial truncate of file with cached dirty data"
5527
5528 test_42d() {
5529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5530
5531         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5532         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5533         $LCTL set_param debug=+cache
5534
5535         trunc_test 42d 0
5536         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5537                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5538         rm $file
5539 }
5540 run_test 42d "test complete truncate of file with cached dirty data"
5541
5542 test_42e() { # bug22074
5543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5544
5545         local TDIR=$DIR/${tdir}e
5546         local pages=16 # hardcoded 16 pages, don't change it.
5547         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5548         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5549         local max_dirty_mb
5550         local warmup_files
5551
5552         test_mkdir $DIR/${tdir}e
5553         $LFS setstripe -c 1 $TDIR
5554         createmany -o $TDIR/f $files
5555
5556         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5557
5558         # we assume that with $OSTCOUNT files, at least one of them will
5559         # be allocated on OST0.
5560         warmup_files=$((OSTCOUNT * max_dirty_mb))
5561         createmany -o $TDIR/w $warmup_files
5562
5563         # write a large amount of data into one file and sync, to get good
5564         # avail_grant number from OST.
5565         for ((i=0; i<$warmup_files; i++)); do
5566                 idx=$($LFS getstripe -i $TDIR/w$i)
5567                 [ $idx -ne 0 ] && continue
5568                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5569                 break
5570         done
5571         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5572         sync
5573         $LCTL get_param $proc_osc0/cur_dirty_bytes
5574         $LCTL get_param $proc_osc0/cur_grant_bytes
5575
5576         # create as much dirty pages as we can while not to trigger the actual
5577         # RPCs directly. but depends on the env, VFS may trigger flush during this
5578         # period, hopefully we are good.
5579         for ((i=0; i<$warmup_files; i++)); do
5580                 idx=$($LFS getstripe -i $TDIR/w$i)
5581                 [ $idx -ne 0 ] && continue
5582                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5583         done
5584         $LCTL get_param $proc_osc0/cur_dirty_bytes
5585         $LCTL get_param $proc_osc0/cur_grant_bytes
5586
5587         # perform the real test
5588         $LCTL set_param $proc_osc0/rpc_stats 0
5589         for ((;i<$files; i++)); do
5590                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5591                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5592         done
5593         sync
5594         $LCTL get_param $proc_osc0/rpc_stats
5595
5596         local percent=0
5597         local have_ppr=false
5598         $LCTL get_param $proc_osc0/rpc_stats |
5599                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5600                         # skip lines until we are at the RPC histogram data
5601                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5602                         $have_ppr || continue
5603
5604                         # we only want the percent stat for < 16 pages
5605                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5606
5607                         percent=$((percent + WPCT))
5608                         if [[ $percent -gt 15 ]]; then
5609                                 error "less than 16-pages write RPCs" \
5610                                       "$percent% > 15%"
5611                                 break
5612                         fi
5613                 done
5614         rm -rf $TDIR
5615 }
5616 run_test 42e "verify sub-RPC writes are not done synchronously"
5617
5618 test_43A() { # was test_43
5619         test_mkdir $DIR/$tdir
5620         cp -p /bin/ls $DIR/$tdir/$tfile
5621         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5622         pid=$!
5623         # give multiop a chance to open
5624         sleep 1
5625
5626         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5627         kill -USR1 $pid
5628         # Wait for multiop to exit
5629         wait $pid
5630 }
5631 run_test 43A "execution of file opened for write should return -ETXTBSY"
5632
5633 test_43a() {
5634         test_mkdir $DIR/$tdir
5635         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5636         $DIR/$tdir/sleep 60 &
5637         SLEEP_PID=$!
5638         # Make sure exec of $tdir/sleep wins race with truncate
5639         sleep 1
5640         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5641         kill $SLEEP_PID
5642 }
5643 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5644
5645 test_43b() {
5646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5647
5648         test_mkdir $DIR/$tdir
5649         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5650         $DIR/$tdir/sleep 60 &
5651         SLEEP_PID=$!
5652         # Make sure exec of $tdir/sleep wins race with truncate
5653         sleep 1
5654         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5655         kill $SLEEP_PID
5656 }
5657 run_test 43b "truncate of file being executed should return -ETXTBSY"
5658
5659 test_43c() {
5660         local testdir="$DIR/$tdir"
5661         test_mkdir $testdir
5662         cp $SHELL $testdir/
5663         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5664                 ( cd $testdir && md5sum -c )
5665 }
5666 run_test 43c "md5sum of copy into lustre"
5667
5668 test_44A() { # was test_44
5669         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5670
5671         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5672         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5673 }
5674 run_test 44A "zero length read from a sparse stripe"
5675
5676 test_44a() {
5677         local nstripe=$($LFS getstripe -c -d $DIR)
5678         [ -z "$nstripe" ] && skip "can't get stripe info"
5679         [[ $nstripe -gt $OSTCOUNT ]] &&
5680                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5681
5682         local stride=$($LFS getstripe -S -d $DIR)
5683         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5684                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5685         fi
5686
5687         OFFSETS="0 $((stride/2)) $((stride-1))"
5688         for offset in $OFFSETS; do
5689                 for i in $(seq 0 $((nstripe-1))); do
5690                         local GLOBALOFFSETS=""
5691                         # size in Bytes
5692                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5693                         local myfn=$DIR/d44a-$size
5694                         echo "--------writing $myfn at $size"
5695                         ll_sparseness_write $myfn $size ||
5696                                 error "ll_sparseness_write"
5697                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5698                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5699                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5700
5701                         for j in $(seq 0 $((nstripe-1))); do
5702                                 # size in Bytes
5703                                 size=$((((j + $nstripe )*$stride + $offset)))
5704                                 ll_sparseness_write $myfn $size ||
5705                                         error "ll_sparseness_write"
5706                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5707                         done
5708                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5709                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5710                         rm -f $myfn
5711                 done
5712         done
5713 }
5714 run_test 44a "test sparse pwrite ==============================="
5715
5716 dirty_osc_total() {
5717         tot=0
5718         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5719                 tot=$(($tot + $d))
5720         done
5721         echo $tot
5722 }
5723 do_dirty_record() {
5724         before=`dirty_osc_total`
5725         echo executing "\"$*\""
5726         eval $*
5727         after=`dirty_osc_total`
5728         echo before $before, after $after
5729 }
5730 test_45() {
5731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5732
5733         f="$DIR/f45"
5734         # Obtain grants from OST if it supports it
5735         echo blah > ${f}_grant
5736         stop_writeback
5737         sync
5738         do_dirty_record "echo blah > $f"
5739         [[ $before -eq $after ]] && error "write wasn't cached"
5740         do_dirty_record "> $f"
5741         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5742         do_dirty_record "echo blah > $f"
5743         [[ $before -eq $after ]] && error "write wasn't cached"
5744         do_dirty_record "sync"
5745         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5746         do_dirty_record "echo blah > $f"
5747         [[ $before -eq $after ]] && error "write wasn't cached"
5748         do_dirty_record "cancel_lru_locks osc"
5749         [[ $before -gt $after ]] ||
5750                 error "lock cancellation didn't lower dirty count"
5751         start_writeback
5752 }
5753 run_test 45 "osc io page accounting ============================"
5754
5755 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5756 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5757 # objects offset and an assert hit when an rpc was built with 1023's mapped
5758 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5759 test_46() {
5760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5761
5762         f="$DIR/f46"
5763         stop_writeback
5764         sync
5765         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5766         sync
5767         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5768         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5769         sync
5770         start_writeback
5771 }
5772 run_test 46 "dirtying a previously written page ================"
5773
5774 # test_47 is removed "Device nodes check" is moved to test_28
5775
5776 test_48a() { # bug 2399
5777         [ "$mds1_FSTYPE" = "zfs" ] &&
5778         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5779                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5780
5781         test_mkdir $DIR/$tdir
5782         cd $DIR/$tdir
5783         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5784         test_mkdir $DIR/$tdir
5785         touch foo || error "'touch foo' failed after recreating cwd"
5786         test_mkdir bar
5787         touch .foo || error "'touch .foo' failed after recreating cwd"
5788         test_mkdir .bar
5789         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5790         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5791         cd . || error "'cd .' failed after recreating cwd"
5792         mkdir . && error "'mkdir .' worked after recreating cwd"
5793         rmdir . && error "'rmdir .' worked after recreating cwd"
5794         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5795         cd .. || error "'cd ..' failed after recreating cwd"
5796 }
5797 run_test 48a "Access renamed working dir (should return errors)="
5798
5799 test_48b() { # bug 2399
5800         rm -rf $DIR/$tdir
5801         test_mkdir $DIR/$tdir
5802         cd $DIR/$tdir
5803         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5804         touch foo && error "'touch foo' worked after removing cwd"
5805         mkdir foo && error "'mkdir foo' worked after removing cwd"
5806         touch .foo && error "'touch .foo' worked after removing cwd"
5807         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5808         ls . > /dev/null && error "'ls .' worked after removing cwd"
5809         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5810         mkdir . && error "'mkdir .' worked after removing cwd"
5811         rmdir . && error "'rmdir .' worked after removing cwd"
5812         ln -s . foo && error "'ln -s .' worked after removing cwd"
5813         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5814 }
5815 run_test 48b "Access removed working dir (should return errors)="
5816
5817 test_48c() { # bug 2350
5818         #lctl set_param debug=-1
5819         #set -vx
5820         rm -rf $DIR/$tdir
5821         test_mkdir -p $DIR/$tdir/dir
5822         cd $DIR/$tdir/dir
5823         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5824         $TRACE touch foo && error "touch foo worked after removing cwd"
5825         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5826         touch .foo && error "touch .foo worked after removing cwd"
5827         mkdir .foo && error "mkdir .foo worked after removing cwd"
5828         $TRACE ls . && error "'ls .' worked after removing cwd"
5829         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5830         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5831         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5832         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5833         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5834 }
5835 run_test 48c "Access removed working subdir (should return errors)"
5836
5837 test_48d() { # bug 2350
5838         #lctl set_param debug=-1
5839         #set -vx
5840         rm -rf $DIR/$tdir
5841         test_mkdir -p $DIR/$tdir/dir
5842         cd $DIR/$tdir/dir
5843         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5844         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5845         $TRACE touch foo && error "'touch foo' worked after removing parent"
5846         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5847         touch .foo && error "'touch .foo' worked after removing parent"
5848         mkdir .foo && error "mkdir .foo worked after removing parent"
5849         $TRACE ls . && error "'ls .' worked after removing parent"
5850         $TRACE ls .. && error "'ls ..' worked after removing parent"
5851         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5852         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5853         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5854         true
5855 }
5856 run_test 48d "Access removed parent subdir (should return errors)"
5857
5858 test_48e() { # bug 4134
5859         #lctl set_param debug=-1
5860         #set -vx
5861         rm -rf $DIR/$tdir
5862         test_mkdir -p $DIR/$tdir/dir
5863         cd $DIR/$tdir/dir
5864         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5865         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5866         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5867         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5868         # On a buggy kernel addition of "touch foo" after cd .. will
5869         # produce kernel oops in lookup_hash_it
5870         touch ../foo && error "'cd ..' worked after recreate parent"
5871         cd $DIR
5872         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5873 }
5874 run_test 48e "Access to recreated parent subdir (should return errors)"
5875
5876 test_48f() {
5877         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5878                 skip "need MDS >= 2.13.55"
5879         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5880         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5881                 skip "needs different host for mdt1 mdt2"
5882         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5883
5884         $LFS mkdir -i0 $DIR/$tdir
5885         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5886
5887         for d in sub1 sub2 sub3; do
5888                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5889                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5890                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5891         done
5892
5893         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5894 }
5895 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5896
5897 test_49() { # LU-1030
5898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5899         remote_ost_nodsh && skip "remote OST with nodsh"
5900
5901         # get ost1 size - $FSNAME-OST0000
5902         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5903                 awk '{ print $4 }')
5904         # write 800M at maximum
5905         [[ $ost1_size -lt 2 ]] && ost1_size=2
5906         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5907
5908         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5909         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5910         local dd_pid=$!
5911
5912         # change max_pages_per_rpc while writing the file
5913         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5914         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5915         # loop until dd process exits
5916         while ps ax -opid | grep -wq $dd_pid; do
5917                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5918                 sleep $((RANDOM % 5 + 1))
5919         done
5920         # restore original max_pages_per_rpc
5921         $LCTL set_param $osc1_mppc=$orig_mppc
5922         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5923 }
5924 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5925
5926 test_50() {
5927         # bug 1485
5928         test_mkdir $DIR/$tdir
5929         cd $DIR/$tdir
5930         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5931 }
5932 run_test 50 "special situations: /proc symlinks  ==============="
5933
5934 test_51a() {    # was test_51
5935         # bug 1516 - create an empty entry right after ".." then split dir
5936         test_mkdir -c1 $DIR/$tdir
5937         touch $DIR/$tdir/foo
5938         $MCREATE $DIR/$tdir/bar
5939         rm $DIR/$tdir/foo
5940         createmany -m $DIR/$tdir/longfile 201
5941         FNUM=202
5942         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5943                 $MCREATE $DIR/$tdir/longfile$FNUM
5944                 FNUM=$(($FNUM + 1))
5945                 echo -n "+"
5946         done
5947         echo
5948         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5949 }
5950 run_test 51a "special situations: split htree with empty entry =="
5951
5952 cleanup_print_lfs_df () {
5953         trap 0
5954         $LFS df
5955         $LFS df -i
5956 }
5957
5958 test_51b() {
5959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5960
5961         local dir=$DIR/$tdir
5962         local nrdirs=$((65536 + 100))
5963
5964         # cleanup the directory
5965         rm -fr $dir
5966
5967         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5968
5969         $LFS df
5970         $LFS df -i
5971         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5972         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5973         [[ $numfree -lt $nrdirs ]] &&
5974                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5975
5976         # need to check free space for the directories as well
5977         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5978         numfree=$(( blkfree / $(fs_inode_ksize) ))
5979         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5980
5981         trap cleanup_print_lfs_df EXIT
5982
5983         # create files
5984         createmany -d $dir/d $nrdirs || {
5985                 unlinkmany $dir/d $nrdirs
5986                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5987         }
5988
5989         # really created :
5990         nrdirs=$(ls -U $dir | wc -l)
5991
5992         # unlink all but 100 subdirectories, then check it still works
5993         local left=100
5994         local delete=$((nrdirs - left))
5995
5996         $LFS df
5997         $LFS df -i
5998
5999         # for ldiskfs the nlink count should be 1, but this is OSD specific
6000         # and so this is listed for informational purposes only
6001         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6002         unlinkmany -d $dir/d $delete ||
6003                 error "unlink of first $delete subdirs failed"
6004
6005         echo "nlink between: $(stat -c %h $dir)"
6006         local found=$(ls -U $dir | wc -l)
6007         [ $found -ne $left ] &&
6008                 error "can't find subdirs: found only $found, expected $left"
6009
6010         unlinkmany -d $dir/d $delete $left ||
6011                 error "unlink of second $left subdirs failed"
6012         # regardless of whether the backing filesystem tracks nlink accurately
6013         # or not, the nlink count shouldn't be more than "." and ".." here
6014         local after=$(stat -c %h $dir)
6015         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6016                 echo "nlink after: $after"
6017
6018         cleanup_print_lfs_df
6019 }
6020 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6021
6022 test_51d_sub() {
6023         local stripecount=$1
6024         local nfiles=$2
6025
6026         log "create files with stripecount=$stripecount"
6027         $LFS setstripe -C $stripecount $DIR/$tdir
6028         createmany -o $DIR/$tdir/t- $nfiles
6029         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6030         for ((n = 0; n < $OSTCOUNT; n++)); do
6031                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6032                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6033                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6034                             '($1 == '$n') { objs += 1 } \
6035                             END { printf("%0.0f", objs) }')
6036                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6037         done
6038         unlinkmany $DIR/$tdir/t- $nfiles
6039         rm  -f $TMP/$tfile
6040
6041         local nlast
6042         local min=4
6043         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6044
6045         # For some combinations of stripecount and OSTCOUNT current code
6046         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6047         # than others. Rather than skipping this test entirely, check that
6048         # and keep testing to ensure imbalance does not get worse. LU-15282
6049         (( (OSTCOUNT == 6 && stripecount == 4) ||
6050            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6051            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6052         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6053                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6054                         { $LFS df && $LFS df -i &&
6055                         error "stripecount=$stripecount: " \
6056                               "OST $n has fewer objects vs. OST $nlast " \
6057                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6058                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6059                         { $LFS df && $LFS df -i &&
6060                         error "stripecount=$stripecount: " \
6061                               "OST $n has more objects vs. OST $nlast " \
6062                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6063
6064                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6065                         { $LFS df && $LFS df -i &&
6066                         error "stripecount=$stripecount: " \
6067                               "OST $n has fewer #0 objects vs. OST $nlast " \
6068                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6069                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6070                         { $LFS df && $LFS df -i &&
6071                         error "stripecount=$stripecount: " \
6072                               "OST $n has more #0 objects vs. OST $nlast " \
6073                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6074         done
6075 }
6076
6077 test_51d() {
6078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6079         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6080
6081         local stripecount
6082         local per_ost=100
6083         local nfiles=$((per_ost * OSTCOUNT))
6084         local mdts=$(comma_list $(mdts_nodes))
6085         local param="osp.*.create_count"
6086         local qos_old=$(do_facet mds1 \
6087                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6088
6089         do_nodes $mdts \
6090                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6091         stack_trap "do_nodes $mdts \
6092                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6093
6094         test_mkdir $DIR/$tdir
6095         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6096         (( dirstripes > 0 )) || dirstripes=1
6097
6098         # Ensure enough OST objects precreated for tests to pass without
6099         # running out of objects.  This is an LOV r-r OST algorithm test,
6100         # not an OST object precreation test.
6101         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6102         (( old >= nfiles )) ||
6103         {
6104                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6105
6106                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6107                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6108
6109                 # trigger precreation from all MDTs for all OSTs
6110                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6111                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6112                 done
6113         }
6114
6115         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6116                 sleep 8  # allow object precreation to catch up
6117                 test_51d_sub $stripecount $nfiles
6118         done
6119 }
6120 run_test 51d "check LOV round-robin OST object distribution"
6121
6122 test_51e() {
6123         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6124                 skip_env "ldiskfs only test"
6125         fi
6126
6127         test_mkdir -c1 $DIR/$tdir
6128         test_mkdir -c1 $DIR/$tdir/d0
6129
6130         touch $DIR/$tdir/d0/foo
6131         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6132                 error "file exceed 65000 nlink limit!"
6133         unlinkmany $DIR/$tdir/d0/f- 65001
6134         return 0
6135 }
6136 run_test 51e "check file nlink limit"
6137
6138 test_51f() {
6139         test_mkdir $DIR/$tdir
6140
6141         local max=100000
6142         local ulimit_old=$(ulimit -n)
6143         local spare=20 # number of spare fd's for scripts/libraries, etc.
6144         local mdt=$($LFS getstripe -m $DIR/$tdir)
6145         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6146
6147         echo "MDT$mdt numfree=$numfree, max=$max"
6148         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6149         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6150                 while ! ulimit -n $((numfree + spare)); do
6151                         numfree=$((numfree * 3 / 4))
6152                 done
6153                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6154         else
6155                 echo "left ulimit at $ulimit_old"
6156         fi
6157
6158         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6159                 unlinkmany $DIR/$tdir/f $numfree
6160                 error "create+open $numfree files in $DIR/$tdir failed"
6161         }
6162         ulimit -n $ulimit_old
6163
6164         # if createmany exits at 120s there will be fewer than $numfree files
6165         unlinkmany $DIR/$tdir/f $numfree || true
6166 }
6167 run_test 51f "check many open files limit"
6168
6169 test_52a() {
6170         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6171         test_mkdir $DIR/$tdir
6172         touch $DIR/$tdir/foo
6173         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6174         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6175         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6176         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6177         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6178                                         error "link worked"
6179         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6180         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6181         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6182                                                      error "lsattr"
6183         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6184         cp -r $DIR/$tdir $TMP/
6185         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6186 }
6187 run_test 52a "append-only flag test (should return errors)"
6188
6189 test_52b() {
6190         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6191         test_mkdir $DIR/$tdir
6192         touch $DIR/$tdir/foo
6193         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6194         cat test > $DIR/$tdir/foo && error "cat test worked"
6195         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6196         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6197         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6198                                         error "link worked"
6199         echo foo >> $DIR/$tdir/foo && error "echo worked"
6200         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6201         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6202         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6203         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6204                                                         error "lsattr"
6205         chattr -i $DIR/$tdir/foo || error "chattr failed"
6206
6207         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6208 }
6209 run_test 52b "immutable flag test (should return errors) ======="
6210
6211 test_53() {
6212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6213         remote_mds_nodsh && skip "remote MDS with nodsh"
6214         remote_ost_nodsh && skip "remote OST with nodsh"
6215
6216         local param
6217         local param_seq
6218         local ostname
6219         local mds_last
6220         local mds_last_seq
6221         local ost_last
6222         local ost_last_seq
6223         local ost_last_id
6224         local ostnum
6225         local node
6226         local found=false
6227         local support_last_seq=true
6228
6229         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6230                 support_last_seq=false
6231
6232         # only test MDT0000
6233         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6234         local value
6235         for value in $(do_facet $SINGLEMDS \
6236                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6237                 param=$(echo ${value[0]} | cut -d "=" -f1)
6238                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6239
6240                 if $support_last_seq; then
6241                         param_seq=$(echo $param |
6242                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6243                         mds_last_seq=$(do_facet $SINGLEMDS \
6244                                        $LCTL get_param -n $param_seq)
6245                 fi
6246                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6247
6248                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6249                 node=$(facet_active_host ost$((ostnum+1)))
6250                 param="obdfilter.$ostname.last_id"
6251                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6252                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6253                         ost_last_id=$ost_last
6254
6255                         if $support_last_seq; then
6256                                 ost_last_id=$(echo $ost_last |
6257                                               awk -F':' '{print $2}' |
6258                                               sed -e "s/^0x//g")
6259                                 ost_last_seq=$(echo $ost_last |
6260                                                awk -F':' '{print $1}')
6261                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6262                         fi
6263
6264                         if [[ $ost_last_id != $mds_last ]]; then
6265                                 error "$ost_last_id != $mds_last"
6266                         else
6267                                 found=true
6268                                 break
6269                         fi
6270                 done
6271         done
6272         $found || error "can not match last_seq/last_id for $mdtosc"
6273         return 0
6274 }
6275 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6276
6277 test_54a() {
6278         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6279
6280         LANG=C $SOCKETSERVER $DIR/socket ||
6281                 error "$SOCKETSERVER $DIR/socket failed: $?"
6282         LANG=C $SOCKETCLIENT $DIR/socket ||
6283                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6284         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6285 }
6286 run_test 54a "unix domain socket test =========================="
6287
6288 test_54b() {
6289         f="$DIR/f54b"
6290         mknod $f c 1 3
6291         chmod 0666 $f
6292         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6293 }
6294 run_test 54b "char device works in lustre ======================"
6295
6296 find_loop_dev() {
6297         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6298         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6299         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6300
6301         for i in $(seq 3 7); do
6302                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6303                 LOOPDEV=$LOOPBASE$i
6304                 LOOPNUM=$i
6305                 break
6306         done
6307 }
6308
6309 cleanup_54c() {
6310         local rc=0
6311         loopdev="$DIR/loop54c"
6312
6313         trap 0
6314         $UMOUNT $DIR/$tdir || rc=$?
6315         losetup -d $loopdev || true
6316         losetup -d $LOOPDEV || true
6317         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6318         return $rc
6319 }
6320
6321 test_54c() {
6322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6323
6324         loopdev="$DIR/loop54c"
6325
6326         find_loop_dev
6327         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6328         trap cleanup_54c EXIT
6329         mknod $loopdev b 7 $LOOPNUM
6330         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6331         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6332         losetup $loopdev $DIR/$tfile ||
6333                 error "can't set up $loopdev for $DIR/$tfile"
6334         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6335         test_mkdir $DIR/$tdir
6336         mount -t ext2 $loopdev $DIR/$tdir ||
6337                 error "error mounting $loopdev on $DIR/$tdir"
6338         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6339                 error "dd write"
6340         df $DIR/$tdir
6341         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6342                 error "dd read"
6343         cleanup_54c
6344 }
6345 run_test 54c "block device works in lustre ====================="
6346
6347 test_54d() {
6348         local pipe="$DIR/$tfile.pipe"
6349         local string="aaaaaa"
6350
6351         mknod $pipe p
6352         echo -n "$string" > $pipe &
6353         local result=$(cat $pipe)
6354         [[ "$result" == "$string" ]] || error "$result != $string"
6355 }
6356 run_test 54d "fifo device works in lustre ======================"
6357
6358 test_54e() {
6359         f="$DIR/f54e"
6360         string="aaaaaa"
6361         cp -aL /dev/console $f
6362         echo $string > $f || error "echo $string to $f failed"
6363 }
6364 run_test 54e "console/tty device works in lustre ======================"
6365
6366 test_55a() {
6367         local dev_path="/sys/kernel/debug/lustre/devices"
6368
6369         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6370
6371         # This must be run in iteractive mode, since attach and setup
6372         # are stateful
6373         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6374                 attach obd_test obd_name obd_uuid
6375                 setup obd_test
6376         EOF"
6377
6378         echo "Devices:"
6379         cat "$dev_path" | tail -n 10
6380
6381         $LCTL --device "obd_name" cleanup
6382         $LCTL --device "obd_name" detach
6383
6384         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6385                 error "OBD unit test failed"
6386
6387         rmmod -v obd_test ||
6388                 error "rmmod failed (may trigger a failure in a later test)"
6389 }
6390 run_test 55a "OBD device life cycle unit tests"
6391
6392 test_55b() {
6393         local dev_path="/sys/kernel/debug/lustre/devices"
6394         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6395
6396         # Set up a large number of devices, using the number
6397         # that can be set up in about a minute (based on prior
6398         # testing). We don't want to run this test forever.
6399         local num_dev_to_create="$(( 24000 - $dev_count))"
6400
6401         load_module obdclass/obd_test || error "load_module failed"
6402
6403         local start=$SECONDS
6404
6405         # This must be run in iteractive mode, since attach and setup
6406         # are stateful
6407         for ((i = 1; i <= num_dev_to_create; i++)); do
6408                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6409                 echo "setup obd_test_$i"
6410         done | $LCTL || error "OBD device creation failed"
6411
6412         echo "Load time: $((SECONDS - start))"
6413         echo "Devices:"
6414         cat "$dev_path" | tail -n 10
6415
6416         for ((i = 1; i <= num_dev_to_create; i++)); do
6417                 echo "--device obd_name_$i cleanup"
6418                 echo "--device obd_name_$i detach"
6419         done | $LCTL || error "OBD device cleanup failed"
6420
6421         echo "Unload time: $((SECONDS - start))"
6422
6423         rmmod -v obd_test ||
6424                 error "rmmod failed (may trigger a failure in a later test)"
6425 }
6426 run_test 55b "Load and unload max OBD devices"
6427
6428 test_56a() {
6429         local numfiles=3
6430         local numdirs=2
6431         local dir=$DIR/$tdir
6432
6433         rm -rf $dir
6434         test_mkdir -p $dir/dir
6435         for i in $(seq $numfiles); do
6436                 touch $dir/file$i
6437                 touch $dir/dir/file$i
6438         done
6439
6440         local numcomp=$($LFS getstripe --component-count $dir)
6441
6442         [[ $numcomp == 0 ]] && numcomp=1
6443
6444         # test lfs getstripe with --recursive
6445         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6446
6447         [[ $filenum -eq $((numfiles * 2)) ]] ||
6448                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6449         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6450         [[ $filenum -eq $numfiles ]] ||
6451                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6452         echo "$LFS getstripe showed obdidx or l_ost_idx"
6453
6454         # test lfs getstripe with file instead of dir
6455         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6456         [[ $filenum -eq 1 ]] ||
6457                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6458         echo "$LFS getstripe file1 passed"
6459
6460         #test lfs getstripe with --verbose
6461         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6462         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6463                 error "$LFS getstripe --verbose $dir: "\
6464                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6465         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6466                 error "$LFS getstripe $dir: showed lmm_magic"
6467
6468         #test lfs getstripe with -v prints lmm_fid
6469         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6470         local countfids=$((numdirs + numfiles * numcomp))
6471         [[ $filenum -eq $countfids ]] ||
6472                 error "$LFS getstripe -v $dir: "\
6473                       "got $filenum want $countfids lmm_fid"
6474         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6475                 error "$LFS getstripe $dir: showed lmm_fid by default"
6476         echo "$LFS getstripe --verbose passed"
6477
6478         #check for FID information
6479         local fid1=$($LFS getstripe --fid $dir/file1)
6480         local fid2=$($LFS getstripe --verbose $dir/file1 |
6481                      awk '/lmm_fid: / { print $2; exit; }')
6482         local fid3=$($LFS path2fid $dir/file1)
6483
6484         [ "$fid1" != "$fid2" ] &&
6485                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6486         [ "$fid1" != "$fid3" ] &&
6487                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6488         echo "$LFS getstripe --fid passed"
6489
6490         #test lfs getstripe with --obd
6491         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6492                 error "$LFS getstripe --obd wrong_uuid: should return error"
6493
6494         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6495
6496         local ostidx=1
6497         local obduuid=$(ostuuid_from_index $ostidx)
6498         local found=$($LFS getstripe -r --obd $obduuid $dir |
6499                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6500
6501         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6502         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6503                 ((filenum--))
6504         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6505                 ((filenum--))
6506
6507         [[ $found -eq $filenum ]] ||
6508                 error "$LFS getstripe --obd: found $found expect $filenum"
6509         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6510                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6511                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6512                 error "$LFS getstripe --obd: should not show file on other obd"
6513         echo "$LFS getstripe --obd passed"
6514 }
6515 run_test 56a "check $LFS getstripe"
6516
6517 test_56b() {
6518         local dir=$DIR/$tdir
6519         local numdirs=3
6520
6521         test_mkdir $dir
6522         for i in $(seq $numdirs); do
6523                 test_mkdir $dir/dir$i
6524         done
6525
6526         # test lfs getdirstripe default mode is non-recursion, which is
6527         # different from lfs getstripe
6528         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6529
6530         [[ $dircnt -eq 1 ]] ||
6531                 error "$LFS getdirstripe: found $dircnt, not 1"
6532         dircnt=$($LFS getdirstripe --recursive $dir |
6533                 grep -c lmv_stripe_count)
6534         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6535                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6536 }
6537 run_test 56b "check $LFS getdirstripe"
6538
6539 test_56bb() {
6540         verify_yaml_available || skip_env "YAML verification not installed"
6541         local output_file=$DIR/$tfile.out
6542
6543         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6544
6545         cat $output_file
6546         cat $output_file | verify_yaml || error "layout is not valid YAML"
6547 }
6548 run_test 56bb "check $LFS getdirstripe layout is YAML"
6549
6550 test_56c() {
6551         remote_ost_nodsh && skip "remote OST with nodsh"
6552
6553         local ost_idx=0
6554         local ost_name=$(ostname_from_index $ost_idx)
6555         local old_status=$(ost_dev_status $ost_idx)
6556         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6557
6558         [[ -z "$old_status" ]] ||
6559                 skip_env "OST $ost_name is in $old_status status"
6560
6561         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6562         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6563                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6564         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6565                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6566                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6567         fi
6568
6569         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6570                 error "$LFS df -v showing inactive devices"
6571         sleep_maxage
6572
6573         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6574
6575         [[ "$new_status" =~ "D" ]] ||
6576                 error "$ost_name status is '$new_status', missing 'D'"
6577         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6578                 [[ "$new_status" =~ "N" ]] ||
6579                         error "$ost_name status is '$new_status', missing 'N'"
6580         fi
6581         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6582                 [[ "$new_status" =~ "f" ]] ||
6583                         error "$ost_name status is '$new_status', missing 'f'"
6584         fi
6585
6586         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6587         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6588                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6589         [[ -z "$p" ]] && restore_lustre_params < $p || true
6590         sleep_maxage
6591
6592         new_status=$(ost_dev_status $ost_idx)
6593         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6594                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6595         # can't check 'f' as devices may actually be on flash
6596 }
6597 run_test 56c "check 'lfs df' showing device status"
6598
6599 test_56d() {
6600         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6601         local osts=$($LFS df -v $MOUNT | grep -c OST)
6602
6603         $LFS df $MOUNT
6604
6605         (( mdts == MDSCOUNT )) ||
6606                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6607         (( osts == OSTCOUNT )) ||
6608                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6609 }
6610 run_test 56d "'lfs df -v' prints only configured devices"
6611
6612 test_56e() {
6613         err_enoent=2 # No such file or directory
6614         err_eopnotsupp=95 # Operation not supported
6615
6616         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6617         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6618
6619         # Check for handling of path not exists
6620         output=$($LFS df $enoent_mnt 2>&1)
6621         ret=$?
6622
6623         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6624         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6625                 error "expect failure $err_enoent, not $ret"
6626
6627         # Check for handling of non-Lustre FS
6628         output=$($LFS df $notsup_mnt)
6629         ret=$?
6630
6631         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6632         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6633                 error "expect success $err_eopnotsupp, not $ret"
6634
6635         # Check for multiple LustreFS argument
6636         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6637         ret=$?
6638
6639         [[ $output -eq 3 && $ret -eq 0 ]] ||
6640                 error "expect success 3, not $output, rc = $ret"
6641
6642         # Check for correct non-Lustre FS handling among multiple
6643         # LustreFS argument
6644         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6645                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6646         ret=$?
6647
6648         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6649                 error "expect success 2, not $output, rc = $ret"
6650 }
6651 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6652
6653 NUMFILES=3
6654 NUMDIRS=3
6655 setup_56() {
6656         local local_tdir="$1"
6657         local local_numfiles="$2"
6658         local local_numdirs="$3"
6659         local dir_params="$4"
6660         local dir_stripe_params="$5"
6661
6662         if [ ! -d "$local_tdir" ] ; then
6663                 test_mkdir -p $dir_stripe_params $local_tdir
6664                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6665                 for i in $(seq $local_numfiles) ; do
6666                         touch $local_tdir/file$i
6667                 done
6668                 for i in $(seq $local_numdirs) ; do
6669                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6670                         for j in $(seq $local_numfiles) ; do
6671                                 touch $local_tdir/dir$i/file$j
6672                         done
6673                 done
6674         fi
6675 }
6676
6677 setup_56_special() {
6678         local local_tdir=$1
6679         local local_numfiles=$2
6680         local local_numdirs=$3
6681
6682         setup_56 $local_tdir $local_numfiles $local_numdirs
6683
6684         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6685                 for i in $(seq $local_numfiles) ; do
6686                         mknod $local_tdir/loop${i}b b 7 $i
6687                         mknod $local_tdir/null${i}c c 1 3
6688                         ln -s $local_tdir/file1 $local_tdir/link${i}
6689                 done
6690                 for i in $(seq $local_numdirs) ; do
6691                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6692                         mknod $local_tdir/dir$i/null${i}c c 1 3
6693                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6694                 done
6695         fi
6696 }
6697
6698 test_56g() {
6699         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6700         local expected=$(($NUMDIRS + 2))
6701
6702         setup_56 $dir $NUMFILES $NUMDIRS
6703
6704         # test lfs find with -name
6705         for i in $(seq $NUMFILES) ; do
6706                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6707
6708                 [ $nums -eq $expected ] ||
6709                         error "lfs find -name '*$i' $dir wrong: "\
6710                               "found $nums, expected $expected"
6711         done
6712 }
6713 run_test 56g "check lfs find -name"
6714
6715 test_56h() {
6716         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6717         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6718
6719         setup_56 $dir $NUMFILES $NUMDIRS
6720
6721         # test lfs find with ! -name
6722         for i in $(seq $NUMFILES) ; do
6723                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6724
6725                 [ $nums -eq $expected ] ||
6726                         error "lfs find ! -name '*$i' $dir wrong: "\
6727                               "found $nums, expected $expected"
6728         done
6729 }
6730 run_test 56h "check lfs find ! -name"
6731
6732 test_56i() {
6733         local dir=$DIR/$tdir
6734
6735         test_mkdir $dir
6736
6737         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6738         local out=$($cmd)
6739
6740         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6741 }
6742 run_test 56i "check 'lfs find -ost UUID' skips directories"
6743
6744 test_56j() {
6745         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6746
6747         setup_56_special $dir $NUMFILES $NUMDIRS
6748
6749         local expected=$((NUMDIRS + 1))
6750         local cmd="$LFS find -type d $dir"
6751         local nums=$($cmd | wc -l)
6752
6753         [ $nums -eq $expected ] ||
6754                 error "'$cmd' wrong: found $nums, expected $expected"
6755 }
6756 run_test 56j "check lfs find -type d"
6757
6758 test_56k() {
6759         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6760
6761         setup_56_special $dir $NUMFILES $NUMDIRS
6762
6763         local expected=$(((NUMDIRS + 1) * NUMFILES))
6764         local cmd="$LFS find -type f $dir"
6765         local nums=$($cmd | wc -l)
6766
6767         [ $nums -eq $expected ] ||
6768                 error "'$cmd' wrong: found $nums, expected $expected"
6769 }
6770 run_test 56k "check lfs find -type f"
6771
6772 test_56l() {
6773         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6774
6775         setup_56_special $dir $NUMFILES $NUMDIRS
6776
6777         local expected=$((NUMDIRS + NUMFILES))
6778         local cmd="$LFS find -type b $dir"
6779         local nums=$($cmd | wc -l)
6780
6781         [ $nums -eq $expected ] ||
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783 }
6784 run_test 56l "check lfs find -type b"
6785
6786 test_56m() {
6787         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6788
6789         setup_56_special $dir $NUMFILES $NUMDIRS
6790
6791         local expected=$((NUMDIRS + NUMFILES))
6792         local cmd="$LFS find -type c $dir"
6793         local nums=$($cmd | wc -l)
6794         [ $nums -eq $expected ] ||
6795                 error "'$cmd' wrong: found $nums, expected $expected"
6796 }
6797 run_test 56m "check lfs find -type c"
6798
6799 test_56n() {
6800         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6801         setup_56_special $dir $NUMFILES $NUMDIRS
6802
6803         local expected=$((NUMDIRS + NUMFILES))
6804         local cmd="$LFS find -type l $dir"
6805         local nums=$($cmd | wc -l)
6806
6807         [ $nums -eq $expected ] ||
6808                 error "'$cmd' wrong: found $nums, expected $expected"
6809 }
6810 run_test 56n "check lfs find -type l"
6811
6812 test_56o() {
6813         local dir=$DIR/$tdir
6814
6815         setup_56 $dir $NUMFILES $NUMDIRS
6816         utime $dir/file1 > /dev/null || error "utime (1)"
6817         utime $dir/file2 > /dev/null || error "utime (2)"
6818         utime $dir/dir1 > /dev/null || error "utime (3)"
6819         utime $dir/dir2 > /dev/null || error "utime (4)"
6820         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6821         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6822
6823         local expected=4
6824         local nums=$($LFS find -mtime +0 $dir | wc -l)
6825
6826         [ $nums -eq $expected ] ||
6827                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6828
6829         expected=12
6830         cmd="$LFS find -mtime 0 $dir"
6831         nums=$($cmd | wc -l)
6832         [ $nums -eq $expected ] ||
6833                 error "'$cmd' wrong: found $nums, expected $expected"
6834 }
6835 run_test 56o "check lfs find -mtime for old files"
6836
6837 test_56ob() {
6838         local dir=$DIR/$tdir
6839         local expected=1
6840         local count=0
6841
6842         # just to make sure there is something that won't be found
6843         test_mkdir $dir
6844         touch $dir/$tfile.now
6845
6846         for age in year week day hour min; do
6847                 count=$((count + 1))
6848
6849                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6850                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6851                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6852
6853                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6854                 local nums=$($cmd | wc -l)
6855                 [ $nums -eq $expected ] ||
6856                         error "'$cmd' wrong: found $nums, expected $expected"
6857
6858                 cmd="$LFS find $dir -atime $count${age:0:1}"
6859                 nums=$($cmd | wc -l)
6860                 [ $nums -eq $expected ] ||
6861                         error "'$cmd' wrong: found $nums, expected $expected"
6862         done
6863
6864         sleep 2
6865         cmd="$LFS find $dir -ctime +1s -type f"
6866         nums=$($cmd | wc -l)
6867         (( $nums == $count * 2 + 1)) ||
6868                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6869 }
6870 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6871
6872 test_newerXY_base() {
6873         local x=$1
6874         local y=$2
6875         local dir=$DIR/$tdir
6876         local ref
6877         local negref
6878
6879         if [ $y == "t" ]; then
6880                 if [ $x == "b" ]; then
6881                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6882                 else
6883                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6884                 fi
6885         else
6886                 ref=$DIR/$tfile.newer.$x$y
6887                 touch $ref || error "touch $ref failed"
6888         fi
6889
6890         echo "before = $ref"
6891         sleep 2
6892         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6893         sleep 2
6894         if [ $y == "t" ]; then
6895                 if [ $x == "b" ]; then
6896                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6897                 else
6898                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6899                 fi
6900         else
6901                 negref=$DIR/$tfile.negnewer.$x$y
6902                 touch $negref || error "touch $negref failed"
6903         fi
6904
6905         echo "after = $negref"
6906         local cmd="$LFS find $dir -newer$x$y $ref"
6907         local nums=$(eval $cmd | wc -l)
6908         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6909
6910         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6911                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6912
6913         cmd="$LFS find $dir ! -newer$x$y $negref"
6914         nums=$(eval $cmd | wc -l)
6915         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6916                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6917
6918         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6919         nums=$(eval $cmd | wc -l)
6920         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6921                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6922
6923         rm -rf $DIR/*
6924 }
6925
6926 test_56oc() {
6927         test_newerXY_base "a" "a"
6928         test_newerXY_base "a" "m"
6929         test_newerXY_base "a" "c"
6930         test_newerXY_base "m" "a"
6931         test_newerXY_base "m" "m"
6932         test_newerXY_base "m" "c"
6933         test_newerXY_base "c" "a"
6934         test_newerXY_base "c" "m"
6935         test_newerXY_base "c" "c"
6936
6937         test_newerXY_base "a" "t"
6938         test_newerXY_base "m" "t"
6939         test_newerXY_base "c" "t"
6940
6941         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6942            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6943                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6944
6945         test_newerXY_base "b" "b"
6946         test_newerXY_base "b" "t"
6947 }
6948 run_test 56oc "check lfs find -newerXY work"
6949
6950 test_56od() {
6951         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6952                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6953
6954         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6955                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6956
6957         local dir=$DIR/$tdir
6958         local ref=$DIR/$tfile.ref
6959         local negref=$DIR/$tfile.negref
6960
6961         mkdir $dir || error "mkdir $dir failed"
6962         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6963         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6964         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6965         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6966         touch $ref || error "touch $ref failed"
6967         # sleep 3 seconds at least
6968         sleep 3
6969
6970         local before=$(do_facet mds1 date +%s)
6971         local skew=$(($(date +%s) - before + 1))
6972
6973         if (( skew < 0 && skew > -5 )); then
6974                 sleep $((0 - skew + 1))
6975                 skew=0
6976         fi
6977
6978         # Set the dir stripe params to limit files all on MDT0,
6979         # otherwise we need to calc the max clock skew between
6980         # the client and MDTs.
6981         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6982         sleep 2
6983         touch $negref || error "touch $negref failed"
6984
6985         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6986         local nums=$($cmd | wc -l)
6987         local expected=$(((NUMFILES + 1) * NUMDIRS))
6988
6989         [ $nums -eq $expected ] ||
6990                 error "'$cmd' wrong: found $nums, expected $expected"
6991
6992         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6993         nums=$($cmd | wc -l)
6994         expected=$((NUMFILES + 1))
6995         [ $nums -eq $expected ] ||
6996                 error "'$cmd' wrong: found $nums, expected $expected"
6997
6998         [ $skew -lt 0 ] && return
6999
7000         local after=$(do_facet mds1 date +%s)
7001         local age=$((after - before + 1 + skew))
7002
7003         cmd="$LFS find $dir -btime -${age}s -type f"
7004         nums=$($cmd | wc -l)
7005         expected=$(((NUMFILES + 1) * NUMDIRS))
7006
7007         echo "Clock skew between client and server: $skew, age:$age"
7008         [ $nums -eq $expected ] ||
7009                 error "'$cmd' wrong: found $nums, expected $expected"
7010
7011         expected=$(($NUMDIRS + 1))
7012         cmd="$LFS find $dir -btime -${age}s -type d"
7013         nums=$($cmd | wc -l)
7014         [ $nums -eq $expected ] ||
7015                 error "'$cmd' wrong: found $nums, expected $expected"
7016         rm -f $ref $negref || error "Failed to remove $ref $negref"
7017 }
7018 run_test 56od "check lfs find -btime with units"
7019
7020 test_56p() {
7021         [ $RUNAS_ID -eq $UID ] &&
7022                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7023
7024         local dir=$DIR/$tdir
7025
7026         setup_56 $dir $NUMFILES $NUMDIRS
7027         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7028
7029         local expected=$NUMFILES
7030         local cmd="$LFS find -uid $RUNAS_ID $dir"
7031         local nums=$($cmd | wc -l)
7032
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7037         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041 }
7042 run_test 56p "check lfs find -uid and ! -uid"
7043
7044 test_56q() {
7045         [ $RUNAS_ID -eq $UID ] &&
7046                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7047
7048         local dir=$DIR/$tdir
7049
7050         setup_56 $dir $NUMFILES $NUMDIRS
7051         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7052
7053         local expected=$NUMFILES
7054         local cmd="$LFS find -gid $RUNAS_GID $dir"
7055         local nums=$($cmd | wc -l)
7056
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7061         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065 }
7066 run_test 56q "check lfs find -gid and ! -gid"
7067
7068 test_56r() {
7069         local dir=$DIR/$tdir
7070
7071         setup_56 $dir $NUMFILES $NUMDIRS
7072
7073         local expected=12
7074         local cmd="$LFS find -size 0 -type f -lazy $dir"
7075         local nums=$($cmd | wc -l)
7076
7077         [ $nums -eq $expected ] ||
7078                 error "'$cmd' wrong: found $nums, expected $expected"
7079         cmd="$LFS find -size 0 -type f $dir"
7080         nums=$($cmd | wc -l)
7081         [ $nums -eq $expected ] ||
7082                 error "'$cmd' wrong: found $nums, expected $expected"
7083
7084         expected=0
7085         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7086         nums=$($cmd | wc -l)
7087         [ $nums -eq $expected ] ||
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089         cmd="$LFS find ! -size 0 -type f $dir"
7090         nums=$($cmd | wc -l)
7091         [ $nums -eq $expected ] ||
7092                 error "'$cmd' wrong: found $nums, expected $expected"
7093
7094         echo "test" > $dir/$tfile
7095         echo "test2" > $dir/$tfile.2 && sync
7096         expected=1
7097         cmd="$LFS find -size 5 -type f -lazy $dir"
7098         nums=$($cmd | wc -l)
7099         [ $nums -eq $expected ] ||
7100                 error "'$cmd' wrong: found $nums, expected $expected"
7101         cmd="$LFS find -size 5 -type f $dir"
7102         nums=$($cmd | wc -l)
7103         [ $nums -eq $expected ] ||
7104                 error "'$cmd' wrong: found $nums, expected $expected"
7105
7106         expected=1
7107         cmd="$LFS find -size +5 -type f -lazy $dir"
7108         nums=$($cmd | wc -l)
7109         [ $nums -eq $expected ] ||
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111         cmd="$LFS find -size +5 -type f $dir"
7112         nums=$($cmd | wc -l)
7113         [ $nums -eq $expected ] ||
7114                 error "'$cmd' wrong: found $nums, expected $expected"
7115
7116         expected=2
7117         cmd="$LFS find -size +0 -type f -lazy $dir"
7118         nums=$($cmd | wc -l)
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121         cmd="$LFS find -size +0 -type f $dir"
7122         nums=$($cmd | wc -l)
7123         [ $nums -eq $expected ] ||
7124                 error "'$cmd' wrong: found $nums, expected $expected"
7125
7126         expected=2
7127         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7128         nums=$($cmd | wc -l)
7129         [ $nums -eq $expected ] ||
7130                 error "'$cmd' wrong: found $nums, expected $expected"
7131         cmd="$LFS find ! -size -5 -type f $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135
7136         expected=12
7137         cmd="$LFS find -size -5 -type f -lazy $dir"
7138         nums=$($cmd | wc -l)
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141         cmd="$LFS find -size -5 -type f $dir"
7142         nums=$($cmd | wc -l)
7143         [ $nums -eq $expected ] ||
7144                 error "'$cmd' wrong: found $nums, expected $expected"
7145 }
7146 run_test 56r "check lfs find -size works"
7147
7148 test_56ra_sub() {
7149         local expected=$1
7150         local glimpses=$2
7151         local cmd="$3"
7152
7153         cancel_lru_locks $OSC
7154
7155         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7156         local nums=$($cmd | wc -l)
7157
7158         [ $nums -eq $expected ] ||
7159                 error "'$cmd' wrong: found $nums, expected $expected"
7160
7161         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7162
7163         if (( rpcs_before + glimpses != rpcs_after )); then
7164                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7165                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7166
7167                 if [[ $glimpses == 0 ]]; then
7168                         error "'$cmd' should not send glimpse RPCs to OST"
7169                 else
7170                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7171                 fi
7172         fi
7173 }
7174
7175 test_56ra() {
7176         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7177                 skip "MDS < 2.12.58 doesn't return LSOM data"
7178         local dir=$DIR/$tdir
7179         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7180
7181         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7182
7183         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7184         $LCTL set_param -n llite.*.statahead_agl=0
7185         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7186
7187         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7188         # open and close all files to ensure LSOM is updated
7189         cancel_lru_locks $OSC
7190         find $dir -type f | xargs cat > /dev/null
7191
7192         #   expect_found  glimpse_rpcs  command_to_run
7193         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7194         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7195         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7196         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7197
7198         echo "test" > $dir/$tfile
7199         echo "test2" > $dir/$tfile.2 && sync
7200         cancel_lru_locks $OSC
7201         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7202
7203         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7204         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7205         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7206         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7207
7208         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7209         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7210         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7211         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7212         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7213         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7214 }
7215 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7216
7217 test_56rb() {
7218         local dir=$DIR/$tdir
7219         local tmp=$TMP/$tfile.log
7220         local mdt_idx;
7221
7222         test_mkdir -p $dir || error "failed to mkdir $dir"
7223         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7224                 error "failed to setstripe $dir/$tfile"
7225         mdt_idx=$($LFS getdirstripe -i $dir)
7226         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7227
7228         stack_trap "rm -f $tmp" EXIT
7229         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7230         ! grep -q obd_uuid $tmp ||
7231                 error "failed to find --size +100K --ost 0 $dir"
7232         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7233         ! grep -q obd_uuid $tmp ||
7234                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7235 }
7236 run_test 56rb "check lfs find --size --ost/--mdt works"
7237
7238 test_56rc() {
7239         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7240         local dir=$DIR/$tdir
7241         local found
7242
7243         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7244         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7245         (( $MDSCOUNT > 2 )) &&
7246                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7247         mkdir $dir/$tdir-{1..10}
7248         touch $dir/$tfile-{1..10}
7249
7250         found=$($LFS find $dir --mdt-count 2 | wc -l)
7251         expect=11
7252         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7253
7254         found=$($LFS find $dir -T +1 | wc -l)
7255         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7256         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7257
7258         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7259         expect=11
7260         (( $found == $expect )) || error "found $found all_char, expect $expect"
7261
7262         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7263         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7264         (( $found == $expect )) || error "found $found all_char, expect $expect"
7265 }
7266 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7267
7268 test_56rd() {
7269         local dir=$DIR/$tdir
7270
7271         test_mkdir $dir
7272         rm -f $dir/*
7273
7274         mkfifo $dir/fifo || error "failed to create fifo file"
7275         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7276                 error "should not fail even cannot get projid from pipe file"
7277         found=$($LFS find $dir -t p --printf "%y")
7278         [[ "p" == $found ]] || error "found $found, expect p"
7279
7280         mknod $dir/chardev c 1 5 ||
7281                 error "failed to create character device file"
7282         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7283                 error "should not fail even cannot get projid from chardev file"
7284         found=$($LFS find $dir -t c --printf "%y")
7285         [[ "c" == $found ]] || error "found $found, expect c"
7286
7287         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7288         (( found == 2 )) || error "unable to list all files"
7289 }
7290 run_test 56rd "check lfs find --printf special files"
7291
7292 test_56s() { # LU-611 #LU-9369
7293         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7294
7295         local dir=$DIR/$tdir
7296         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7297
7298         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7299         for i in $(seq $NUMDIRS); do
7300                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7301         done
7302
7303         local expected=$NUMDIRS
7304         local cmd="$LFS find -c $OSTCOUNT $dir"
7305         local nums=$($cmd | wc -l)
7306
7307         [ $nums -eq $expected ] || {
7308                 $LFS getstripe -R $dir
7309                 error "'$cmd' wrong: found $nums, expected $expected"
7310         }
7311
7312         expected=$((NUMDIRS + onestripe))
7313         cmd="$LFS find -stripe-count +0 -type f $dir"
7314         nums=$($cmd | wc -l)
7315         [ $nums -eq $expected ] || {
7316                 $LFS getstripe -R $dir
7317                 error "'$cmd' wrong: found $nums, expected $expected"
7318         }
7319
7320         expected=$onestripe
7321         cmd="$LFS find -stripe-count 1 -type f $dir"
7322         nums=$($cmd | wc -l)
7323         [ $nums -eq $expected ] || {
7324                 $LFS getstripe -R $dir
7325                 error "'$cmd' wrong: found $nums, expected $expected"
7326         }
7327
7328         cmd="$LFS find -stripe-count -2 -type f $dir"
7329         nums=$($cmd | wc -l)
7330         [ $nums -eq $expected ] || {
7331                 $LFS getstripe -R $dir
7332                 error "'$cmd' wrong: found $nums, expected $expected"
7333         }
7334
7335         expected=0
7336         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -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 run_test 56s "check lfs find -stripe-count works"
7344
7345 test_56t() { # LU-611 #LU-9369
7346         local dir=$DIR/$tdir
7347
7348         setup_56 $dir 0 $NUMDIRS
7349         for i in $(seq $NUMDIRS); do
7350                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7351         done
7352
7353         local expected=$NUMDIRS
7354         local cmd="$LFS find -S 8M $dir"
7355         local nums=$($cmd | wc -l)
7356
7357         [ $nums -eq $expected ] || {
7358                 $LFS getstripe -R $dir
7359                 error "'$cmd' wrong: found $nums, expected $expected"
7360         }
7361         rm -rf $dir
7362
7363         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7364
7365         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7366
7367         expected=$(((NUMDIRS + 1) * NUMFILES))
7368         cmd="$LFS find -stripe-size 512k -type f $dir"
7369         nums=$($cmd | wc -l)
7370         [ $nums -eq $expected ] ||
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372
7373         cmd="$LFS find -stripe-size +320k -type f $dir"
7374         nums=$($cmd | wc -l)
7375         [ $nums -eq $expected ] ||
7376                 error "'$cmd' wrong: found $nums, expected $expected"
7377
7378         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7379         cmd="$LFS find -stripe-size +200k -type f $dir"
7380         nums=$($cmd | wc -l)
7381         [ $nums -eq $expected ] ||
7382                 error "'$cmd' wrong: found $nums, expected $expected"
7383
7384         cmd="$LFS find -stripe-size -640k -type f $dir"
7385         nums=$($cmd | wc -l)
7386         [ $nums -eq $expected ] ||
7387                 error "'$cmd' wrong: found $nums, expected $expected"
7388
7389         expected=4
7390         cmd="$LFS find -stripe-size 256k -type f $dir"
7391         nums=$($cmd | wc -l)
7392         [ $nums -eq $expected ] ||
7393                 error "'$cmd' wrong: found $nums, expected $expected"
7394
7395         cmd="$LFS find -stripe-size -320k -type f $dir"
7396         nums=$($cmd | wc -l)
7397         [ $nums -eq $expected ] ||
7398                 error "'$cmd' wrong: found $nums, expected $expected"
7399
7400         expected=0
7401         cmd="$LFS find -stripe-size 1024k -type f $dir"
7402         nums=$($cmd | wc -l)
7403         [ $nums -eq $expected ] ||
7404                 error "'$cmd' wrong: found $nums, expected $expected"
7405 }
7406 run_test 56t "check lfs find -stripe-size works"
7407
7408 test_56u() { # LU-611
7409         local dir=$DIR/$tdir
7410
7411         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7412
7413         if [[ $OSTCOUNT -gt 1 ]]; then
7414                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7415                 onestripe=4
7416         else
7417                 onestripe=0
7418         fi
7419
7420         local expected=$(((NUMDIRS + 1) * NUMFILES))
7421         local cmd="$LFS find -stripe-index 0 -type f $dir"
7422         local nums=$($cmd | wc -l)
7423
7424         [ $nums -eq $expected ] ||
7425                 error "'$cmd' wrong: found $nums, expected $expected"
7426
7427         expected=$onestripe
7428         cmd="$LFS find -stripe-index 1 -type f $dir"
7429         nums=$($cmd | wc -l)
7430         [ $nums -eq $expected ] ||
7431                 error "'$cmd' wrong: found $nums, expected $expected"
7432
7433         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7434         nums=$($cmd | wc -l)
7435         [ $nums -eq $expected ] ||
7436                 error "'$cmd' wrong: found $nums, expected $expected"
7437
7438         expected=0
7439         # This should produce an error and not return any files
7440         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7441         nums=$($cmd 2>/dev/null | wc -l)
7442         [ $nums -eq $expected ] ||
7443                 error "'$cmd' wrong: found $nums, expected $expected"
7444
7445         if [[ $OSTCOUNT -gt 1 ]]; then
7446                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7447                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7448                 nums=$($cmd | wc -l)
7449                 [ $nums -eq $expected ] ||
7450                         error "'$cmd' wrong: found $nums, expected $expected"
7451         fi
7452 }
7453 run_test 56u "check lfs find -stripe-index works"
7454
7455 test_56v() {
7456         local mdt_idx=0
7457         local dir=$DIR/$tdir
7458
7459         setup_56 $dir $NUMFILES $NUMDIRS
7460
7461         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7462         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7463
7464         for file in $($LFS find -m $UUID $dir); do
7465                 file_midx=$($LFS getstripe -m $file)
7466                 [ $file_midx -eq $mdt_idx ] ||
7467                         error "lfs find -m $UUID != getstripe -m $file_midx"
7468         done
7469 }
7470 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7471
7472 test_56wa() {
7473         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7475
7476         local dir=$DIR/$tdir
7477
7478         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7479         stack_trap "rm -rf $dir"
7480
7481         local stripe_size=$($LFS getstripe -S -d $dir) ||
7482                 error "$LFS getstripe -S -d $dir failed"
7483         stripe_size=${stripe_size%% *}
7484
7485         local file_size=$((stripe_size * OSTCOUNT))
7486         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7487         local required_space=$((file_num * file_size))
7488         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7489                            head -n1)
7490         (( free_space >= required_space / 1024 )) ||
7491                 skip_env "need $required_space, have $free_space kbytes"
7492
7493         local dd_bs=65536
7494         local dd_count=$((file_size / dd_bs))
7495
7496         # write data into the files
7497         local i
7498         local j
7499         local file
7500
7501         for ((i = 1; i <= NUMFILES; i++ )); do
7502                 file=$dir/file$i
7503                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7504                         error "write data into $file failed"
7505         done
7506         for ((i = 1; i <= NUMDIRS; i++ )); do
7507                 for ((j = 1; j <= NUMFILES; j++ )); do
7508                         file=$dir/dir$i/file$j
7509                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7510                                 error "write data into $file failed"
7511                 done
7512         done
7513
7514         # $LFS_MIGRATE will fail if hard link migration is unsupported
7515         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7516                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7517                         error "creating links to $dir/dir1/file1 failed"
7518         fi
7519
7520         local expected=-1
7521
7522         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7523
7524         # lfs_migrate file
7525         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7526
7527         echo "$cmd"
7528         eval $cmd || error "$cmd failed"
7529
7530         check_stripe_count $dir/file1 $expected
7531
7532         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7533                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7534                 # OST 1 if it is on OST 0. This file is small enough to
7535                 # be on only one stripe.
7536                 file=$dir/migr_1_ost
7537                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7538                         error "write data into $file failed"
7539                 local obdidx=$($LFS getstripe -i $file)
7540                 local oldmd5=$(md5sum $file)
7541                 local newobdidx=0
7542
7543                 (( obdidx != 0 )) || newobdidx=1
7544                 cmd="$LFS migrate -i $newobdidx $file"
7545                 echo $cmd
7546                 eval $cmd || error "$cmd failed"
7547
7548                 local realobdix=$($LFS getstripe -i $file)
7549                 local newmd5=$(md5sum $file)
7550
7551                 (( $newobdidx == $realobdix )) ||
7552                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7553                 [[ "$oldmd5" == "$newmd5" ]] ||
7554                         error "md5sum differ: $oldmd5, $newmd5"
7555         fi
7556
7557         # lfs_migrate dir
7558         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7559         echo "$cmd"
7560         eval $cmd || error "$cmd failed"
7561
7562         for (( j = 1; j <= NUMFILES; j++ )); do
7563                 check_stripe_count $dir/dir1/file$j $expected
7564         done
7565
7566         # lfs_migrate works with lfs find
7567         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7568              $LFS_MIGRATE -y -c $expected"
7569         echo "$cmd"
7570         eval $cmd || error "$cmd failed"
7571
7572         for (( i = 2; i <= NUMFILES; i++ )); do
7573                 check_stripe_count $dir/file$i $expected
7574         done
7575         for (( i = 2; i <= NUMDIRS; i++ )); do
7576                 for (( j = 1; j <= NUMFILES; j++ )); do
7577                         check_stripe_count $dir/dir$i/file$j $expected
7578                 done
7579         done
7580 }
7581 run_test 56wa "check lfs_migrate -c stripe_count works"
7582
7583 test_56wb() {
7584         local file1=$DIR/$tdir/file1
7585         local create_pool=false
7586         local initial_pool=$($LFS getstripe -p $DIR)
7587         local pool_list=()
7588         local pool=""
7589
7590         echo -n "Creating test dir..."
7591         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7592         echo "done."
7593
7594         echo -n "Creating test file..."
7595         touch $file1 || error "cannot create file"
7596         echo "done."
7597
7598         echo -n "Detecting existing pools..."
7599         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7600
7601         if [ ${#pool_list[@]} -gt 0 ]; then
7602                 echo "${pool_list[@]}"
7603                 for thispool in "${pool_list[@]}"; do
7604                         if [[ -z "$initial_pool" ||
7605                               "$initial_pool" != "$thispool" ]]; then
7606                                 pool="$thispool"
7607                                 echo "Using existing pool '$pool'"
7608                                 break
7609                         fi
7610                 done
7611         else
7612                 echo "none detected."
7613         fi
7614         if [ -z "$pool" ]; then
7615                 pool=${POOL:-testpool}
7616                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7617                 echo -n "Creating pool '$pool'..."
7618                 create_pool=true
7619                 pool_add $pool &> /dev/null ||
7620                         error "pool_add failed"
7621                 echo "done."
7622
7623                 echo -n "Adding target to pool..."
7624                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7625                         error "pool_add_targets failed"
7626                 echo "done."
7627         fi
7628
7629         echo -n "Setting pool using -p option..."
7630         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7631                 error "migrate failed rc = $?"
7632         echo "done."
7633
7634         echo -n "Verifying test file is in pool after migrating..."
7635         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7636                 error "file was not migrated to pool $pool"
7637         echo "done."
7638
7639         echo -n "Removing test file from pool '$pool'..."
7640         # "lfs migrate $file" won't remove the file from the pool
7641         # until some striping information is changed.
7642         $LFS migrate -c 1 $file1 &> /dev/null ||
7643                 error "cannot remove from pool"
7644         [ "$($LFS getstripe -p $file1)" ] &&
7645                 error "pool still set"
7646         echo "done."
7647
7648         echo -n "Setting pool using --pool option..."
7649         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7650                 error "migrate failed rc = $?"
7651         echo "done."
7652
7653         # Clean up
7654         rm -f $file1
7655         if $create_pool; then
7656                 destroy_test_pools 2> /dev/null ||
7657                         error "destroy test pools failed"
7658         fi
7659 }
7660 run_test 56wb "check lfs_migrate pool support"
7661
7662 test_56wc() {
7663         local file1="$DIR/$tdir/$tfile"
7664         local md5
7665         local parent_ssize
7666         local parent_scount
7667         local cur_ssize
7668         local cur_scount
7669         local orig_ssize
7670         local new_scount
7671         local cur_comp
7672
7673         echo -n "Creating test dir..."
7674         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7675         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7676                 error "cannot set stripe by '-S 1M -c 1'"
7677         echo "done"
7678
7679         echo -n "Setting initial stripe for test file..."
7680         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7681                 error "cannot set stripe"
7682         cur_ssize=$($LFS getstripe -S "$file1")
7683         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7684         echo "done."
7685
7686         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7687         stack_trap "rm -f $file1"
7688         md5="$(md5sum $file1)"
7689
7690         # File currently set to -S 512K -c 1
7691
7692         # Ensure -c and -S options are rejected when -R is set
7693         echo -n "Verifying incompatible options are detected..."
7694         $LFS_MIGRATE -R -c 1 "$file1" &&
7695                 error "incompatible -R and -c options not detected"
7696         $LFS_MIGRATE -R -S 1M "$file1" &&
7697                 error "incompatible -R and -S options not detected"
7698         $LFS_MIGRATE -R -p pool "$file1" &&
7699                 error "incompatible -R and -p options not detected"
7700         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7701                 error "incompatible -R and -E options not detected"
7702         $LFS_MIGRATE -R -A "$file1" &&
7703                 error "incompatible -R and -A options not detected"
7704         $LFS_MIGRATE -A -c 1 "$file1" &&
7705                 error "incompatible -A and -c options not detected"
7706         $LFS_MIGRATE -A -S 1M "$file1" &&
7707                 error "incompatible -A and -S options not detected"
7708         $LFS_MIGRATE -A -p pool "$file1" &&
7709                 error "incompatible -A and -p options not detected"
7710         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7711                 error "incompatible -A and -E options not detected"
7712         echo "done."
7713
7714         # Ensure unrecognized options are passed through to 'lfs migrate'
7715         echo -n "Verifying -S option is passed through to lfs migrate..."
7716         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7717         cur_ssize=$($LFS getstripe -S "$file1")
7718         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7719         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7720         echo "done."
7721
7722         # File currently set to -S 1M -c 1
7723
7724         # Ensure long options are supported
7725         echo -n "Verifying long options supported..."
7726         $LFS_MIGRATE --non-block "$file1" ||
7727                 error "long option without argument not supported"
7728         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7729                 error "long option with argument not supported"
7730         cur_ssize=$($LFS getstripe -S "$file1")
7731         (( cur_ssize == 524288 )) ||
7732                 error "migrate --stripe-size $cur_ssize != 524288"
7733         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7734         echo "done."
7735
7736         # File currently set to -S 512K -c 1
7737
7738         if (( OSTCOUNT > 1 )); then
7739                 echo -n "Verifying explicit stripe count can be set..."
7740                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7741                 cur_scount=$($LFS getstripe -c "$file1")
7742                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7743                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7744                         error "file data has changed (3)"
7745                 echo "done."
7746         fi
7747
7748         # File currently set to -S 512K -c 1 or -S 512K -c 2
7749
7750         # Ensure parent striping is used if -R is set, and no stripe
7751         # count or size is specified
7752         echo -n "Setting stripe for parent directory..."
7753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7754                 error "cannot set stripe '-S 2M -c 1'"
7755         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7756         echo "done."
7757
7758         echo -n "Verifying restripe option uses parent stripe settings..."
7759         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7760         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7761         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7762         cur_ssize=$($LFS getstripe -S "$file1")
7763         (( cur_ssize == parent_ssize )) ||
7764                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7765         cur_scount=$($LFS getstripe -c "$file1")
7766         (( cur_scount == parent_scount )) ||
7767                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7768         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7769         echo "done."
7770
7771         # File currently set to -S 1M -c 1
7772
7773         # Ensure striping is preserved if -R is not set, and no stripe
7774         # count or size is specified
7775         echo -n "Verifying striping size preserved when not specified..."
7776         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7777         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7778                 error "cannot set stripe on parent directory"
7779         $LFS_MIGRATE "$file1" || error "migrate failed"
7780         cur_ssize=$($LFS getstripe -S "$file1")
7781         (( cur_ssize == orig_ssize )) ||
7782                 error "migrate by default $cur_ssize != $orig_ssize"
7783         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7784         echo "done."
7785
7786         # Ensure file name properly detected when final option has no argument
7787         echo -n "Verifying file name properly detected..."
7788         $LFS_MIGRATE "$file1" ||
7789                 error "file name interpreted as option argument"
7790         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7791         echo "done."
7792
7793         # Ensure PFL arguments are passed through properly
7794         echo -n "Verifying PFL options passed through..."
7795         new_scount=$(((OSTCOUNT + 1) / 2))
7796         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7797                 error "migrate PFL arguments failed"
7798         cur_comp=$($LFS getstripe --comp-count $file1)
7799         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7800         cur_scount=$($LFS getstripe --stripe-count $file1)
7801         (( cur_scount == new_scount)) ||
7802                 error "PFL stripe count $cur_scount != $new_scount"
7803         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7804         echo "done."
7805 }
7806 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7807
7808 test_56wd() {
7809         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7810
7811         local file1=$DIR/$tdir/$tfile
7812
7813         echo -n "Creating test dir..."
7814         test_mkdir $DIR/$tdir || error "cannot create dir"
7815         echo "done."
7816
7817         echo -n "Creating test file..."
7818         echo "$tfile" > $file1
7819         echo "done."
7820
7821         # Ensure 'lfs migrate' will fail by using a non-existent option,
7822         # and make sure rsync is not called to recover
7823         echo -n "Make sure --no-rsync option works..."
7824         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7825                 grep -q 'refusing to fall back to rsync' ||
7826                 error "rsync was called with --no-rsync set"
7827         echo "done."
7828
7829         # Ensure rsync is called without trying 'lfs migrate' first
7830         echo -n "Make sure --rsync option works..."
7831         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7832                 grep -q 'falling back to rsync' &&
7833                 error "lfs migrate was called with --rsync set"
7834         echo "done."
7835 }
7836 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7837
7838 test_56we() {
7839         local td=$DIR/$tdir
7840         local tf=$td/$tfile
7841
7842         test_mkdir $td || error "cannot create $td"
7843         touch $tf || error "cannot touch $tf"
7844
7845         echo -n "Make sure --non-direct|-D works..."
7846         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7847                 grep -q "lfs migrate --non-direct" ||
7848                 error "--non-direct option cannot work correctly"
7849         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7850                 grep -q "lfs migrate -D" ||
7851                 error "-D option cannot work correctly"
7852         echo "done."
7853 }
7854 run_test 56we "check lfs_migrate --non-direct|-D support"
7855
7856 test_56x() {
7857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7858         check_swap_layouts_support
7859
7860         local dir=$DIR/$tdir
7861         local ref1=/etc/passwd
7862         local file1=$dir/file1
7863
7864         test_mkdir $dir || error "creating dir $dir"
7865         $LFS setstripe -c 2 $file1
7866         cp $ref1 $file1
7867         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7868         stripe=$($LFS getstripe -c $file1)
7869         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7870         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7871
7872         # clean up
7873         rm -f $file1
7874 }
7875 run_test 56x "lfs migration support"
7876
7877 test_56xa() {
7878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7879         check_swap_layouts_support
7880
7881         local dir=$DIR/$tdir/$testnum
7882
7883         test_mkdir -p $dir
7884
7885         local ref1=/etc/passwd
7886         local file1=$dir/file1
7887
7888         $LFS setstripe -c 2 $file1
7889         cp $ref1 $file1
7890         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7891
7892         local stripe=$($LFS getstripe -c $file1)
7893
7894         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7895         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7896
7897         # clean up
7898         rm -f $file1
7899 }
7900 run_test 56xa "lfs migration --block support"
7901
7902 check_migrate_links() {
7903         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7904         local dir="$1"
7905         local file1="$dir/file1"
7906         local begin="$2"
7907         local count="$3"
7908         local runas="$4"
7909         local total_count=$(($begin + $count - 1))
7910         local symlink_count=10
7911         local uniq_count=10
7912
7913         if [ ! -f "$file1" ]; then
7914                 echo -n "creating initial file..."
7915                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7916                         error "cannot setstripe initial file"
7917                 echo "done"
7918
7919                 echo -n "creating symlinks..."
7920                 for s in $(seq 1 $symlink_count); do
7921                         ln -s "$file1" "$dir/slink$s" ||
7922                                 error "cannot create symlinks"
7923                 done
7924                 echo "done"
7925
7926                 echo -n "creating nonlinked files..."
7927                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7928                         error "cannot create nonlinked files"
7929                 echo "done"
7930         fi
7931
7932         # create hard links
7933         if [ ! -f "$dir/file$total_count" ]; then
7934                 echo -n "creating hard links $begin:$total_count..."
7935                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7936                         /dev/null || error "cannot create hard links"
7937                 echo "done"
7938         fi
7939
7940         echo -n "checking number of hard links listed in xattrs..."
7941         local fid=$($LFS getstripe -F "$file1")
7942         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7943
7944         echo "${#paths[*]}"
7945         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7946                         skip "hard link list has unexpected size, skipping test"
7947         fi
7948         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7949                         error "link names should exceed xattrs size"
7950         fi
7951
7952         echo -n "migrating files..."
7953         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7954         local rc=$?
7955         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7956         echo "done"
7957
7958         # make sure all links have been properly migrated
7959         echo -n "verifying files..."
7960         fid=$($LFS getstripe -F "$file1") ||
7961                 error "cannot get fid for file $file1"
7962         for i in $(seq 2 $total_count); do
7963                 local fid2=$($LFS getstripe -F $dir/file$i)
7964
7965                 [ "$fid2" == "$fid" ] ||
7966                         error "migrated hard link has mismatched FID"
7967         done
7968
7969         # make sure hard links were properly detected, and migration was
7970         # performed only once for the entire link set; nonlinked files should
7971         # also be migrated
7972         local actual=$(grep -c 'done' <<< "$migrate_out")
7973         local expected=$(($uniq_count + 1))
7974
7975         [ "$actual" -eq  "$expected" ] ||
7976                 error "hard links individually migrated ($actual != $expected)"
7977
7978         # make sure the correct number of hard links are present
7979         local hardlinks=$(stat -c '%h' "$file1")
7980
7981         [ $hardlinks -eq $total_count ] ||
7982                 error "num hard links $hardlinks != $total_count"
7983         echo "done"
7984
7985         return 0
7986 }
7987
7988 test_56xb() {
7989         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7990                 skip "Need MDS version at least 2.10.55"
7991
7992         local dir="$DIR/$tdir"
7993
7994         test_mkdir "$dir" || error "cannot create dir $dir"
7995
7996         echo "testing lfs migrate mode when all links fit within xattrs"
7997         check_migrate_links "$dir" 2 99
7998
7999         echo "testing rsync mode when all links fit within xattrs"
8000         check_migrate_links --rsync "$dir" 2 99
8001
8002         echo "testing lfs migrate mode when all links do not fit within xattrs"
8003         check_migrate_links "$dir" 101 100
8004
8005         echo "testing rsync mode when all links do not fit within xattrs"
8006         check_migrate_links --rsync "$dir" 101 100
8007
8008         chown -R $RUNAS_ID $dir
8009         echo "testing non-root lfs migrate mode when not all links are in xattr"
8010         check_migrate_links "$dir" 101 100 "$RUNAS"
8011
8012         # clean up
8013         rm -rf $dir
8014 }
8015 run_test 56xb "lfs migration hard link support"
8016
8017 test_56xc() {
8018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8019
8020         local dir="$DIR/$tdir"
8021
8022         test_mkdir "$dir" || error "cannot create dir $dir"
8023
8024         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8025         echo -n "Setting initial stripe for 20MB test file..."
8026         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8027                 error "cannot setstripe 20MB file"
8028         echo "done"
8029         echo -n "Sizing 20MB test file..."
8030         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8031         echo "done"
8032         echo -n "Verifying small file autostripe count is 1..."
8033         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8034                 error "cannot migrate 20MB file"
8035         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8036                 error "cannot get stripe for $dir/20mb"
8037         [ $stripe_count -eq 1 ] ||
8038                 error "unexpected stripe count $stripe_count for 20MB file"
8039         rm -f "$dir/20mb"
8040         echo "done"
8041
8042         # Test 2: File is small enough to fit within the available space on
8043         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8044         # have at least an additional 1KB for each desired stripe for test 3
8045         echo -n "Setting stripe for 1GB test file..."
8046         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8047         echo "done"
8048         echo -n "Sizing 1GB test file..."
8049         # File size is 1GB + 3KB
8050         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8051         echo "done"
8052
8053         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8054         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8055         if (( avail > 524288 * OSTCOUNT )); then
8056                 echo -n "Migrating 1GB file..."
8057                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8058                         error "cannot migrate 1GB file"
8059                 echo "done"
8060                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8061                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8062                         error "cannot getstripe for 1GB file"
8063                 [ $stripe_count -eq 2 ] ||
8064                         error "unexpected stripe count $stripe_count != 2"
8065                 echo "done"
8066         fi
8067
8068         # Test 3: File is too large to fit within the available space on
8069         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8070         if [ $OSTCOUNT -ge 3 ]; then
8071                 # The required available space is calculated as
8072                 # file size (1GB + 3KB) / OST count (3).
8073                 local kb_per_ost=349526
8074
8075                 echo -n "Migrating 1GB file with limit..."
8076                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8077                         error "cannot migrate 1GB file with limit"
8078                 echo "done"
8079
8080                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8081                 echo -n "Verifying 1GB autostripe count with limited space..."
8082                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8083                         error "unexpected stripe count $stripe_count (min 3)"
8084                 echo "done"
8085         fi
8086
8087         # clean up
8088         rm -rf $dir
8089 }
8090 run_test 56xc "lfs migration autostripe"
8091
8092 test_56xd() {
8093         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8094
8095         local dir=$DIR/$tdir
8096         local f_mgrt=$dir/$tfile.mgrt
8097         local f_yaml=$dir/$tfile.yaml
8098         local f_copy=$dir/$tfile.copy
8099         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8100         local layout_copy="-c 2 -S 2M -i 1"
8101         local yamlfile=$dir/yamlfile
8102         local layout_before;
8103         local layout_after;
8104
8105         test_mkdir "$dir" || error "cannot create dir $dir"
8106         stack_trap "rm -rf $dir"
8107         $LFS setstripe $layout_yaml $f_yaml ||
8108                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8109         $LFS getstripe --yaml $f_yaml > $yamlfile
8110         $LFS setstripe $layout_copy $f_copy ||
8111                 error "cannot setstripe $f_copy with layout $layout_copy"
8112         touch $f_mgrt
8113         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8114
8115         # 1. test option --yaml
8116         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8117                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8118         layout_before=$(get_layout_param $f_yaml)
8119         layout_after=$(get_layout_param $f_mgrt)
8120         [ "$layout_after" == "$layout_before" ] ||
8121                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8122
8123         # 2. test option --copy
8124         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8125                 error "cannot migrate $f_mgrt with --copy $f_copy"
8126         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8127         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8128         [ "$layout_after" == "$layout_before" ] ||
8129                 error "lfs_migrate --copy: $layout_after != $layout_before"
8130 }
8131 run_test 56xd "check lfs_migrate --yaml and --copy support"
8132
8133 test_56xe() {
8134         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8135
8136         local dir=$DIR/$tdir
8137         local f_comp=$dir/$tfile
8138         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8139         local layout_before=""
8140         local layout_after=""
8141
8142         test_mkdir "$dir" || error "cannot create dir $dir"
8143         stack_trap "rm -rf $dir"
8144         $LFS setstripe $layout $f_comp ||
8145                 error "cannot setstripe $f_comp with layout $layout"
8146         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8147         dd if=/dev/zero of=$f_comp bs=1M count=4
8148
8149         # 1. migrate a comp layout file by lfs_migrate
8150         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8151         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8152         [ "$layout_before" == "$layout_after" ] ||
8153                 error "lfs_migrate: $layout_before != $layout_after"
8154
8155         # 2. migrate a comp layout file by lfs migrate
8156         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8157         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8158         [ "$layout_before" == "$layout_after" ] ||
8159                 error "lfs migrate: $layout_before != $layout_after"
8160 }
8161 run_test 56xe "migrate a composite layout file"
8162
8163 test_56xf() {
8164         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8165
8166         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8167                 skip "Need server version at least 2.13.53"
8168
8169         local dir=$DIR/$tdir
8170         local f_comp=$dir/$tfile
8171         local layout="-E 1M -c1 -E -1 -c2"
8172         local fid_before=""
8173         local fid_after=""
8174
8175         test_mkdir "$dir" || error "cannot create dir $dir"
8176         stack_trap "rm -rf $dir"
8177         $LFS setstripe $layout $f_comp ||
8178                 error "cannot setstripe $f_comp with layout $layout"
8179         fid_before=$($LFS getstripe --fid $f_comp)
8180         dd if=/dev/zero of=$f_comp bs=1M count=4
8181
8182         # 1. migrate a comp layout file to a comp layout
8183         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8184         fid_after=$($LFS getstripe --fid $f_comp)
8185         [ "$fid_before" == "$fid_after" ] ||
8186                 error "comp-to-comp migrate: $fid_before != $fid_after"
8187
8188         # 2. migrate a comp layout file to a plain layout
8189         $LFS migrate -c2 $f_comp ||
8190                 error "cannot migrate $f_comp by lfs migrate"
8191         fid_after=$($LFS getstripe --fid $f_comp)
8192         [ "$fid_before" == "$fid_after" ] ||
8193                 error "comp-to-plain migrate: $fid_before != $fid_after"
8194
8195         # 3. migrate a plain layout file to a comp layout
8196         $LFS migrate $layout $f_comp ||
8197                 error "cannot migrate $f_comp by lfs migrate"
8198         fid_after=$($LFS getstripe --fid $f_comp)
8199         [ "$fid_before" == "$fid_after" ] ||
8200                 error "plain-to-comp migrate: $fid_before != $fid_after"
8201 }
8202 run_test 56xf "FID is not lost during migration of a composite layout file"
8203
8204 check_file_ost_range() {
8205         local file="$1"
8206         shift
8207         local range="$*"
8208         local -a file_range
8209         local idx
8210
8211         file_range=($($LFS getstripe -y "$file" |
8212                 awk '/l_ost_idx:/ { print $NF }'))
8213
8214         if [[ "${#file_range[@]}" = 0 ]]; then
8215                 echo "No osts found for $file"
8216                 return 1
8217         fi
8218
8219         for idx in "${file_range[@]}"; do
8220                 [[ " $range " =~ " $idx " ]] ||
8221                         return 1
8222         done
8223
8224         return 0
8225 }
8226
8227 sub_test_56xg() {
8228         local stripe_opt="$1"
8229         local pool="$2"
8230         shift 2
8231         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8232
8233         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8234                 error "Fail to migrate $tfile on $pool"
8235         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8236                 error "$tfile is not in pool $pool"
8237         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8238                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8239 }
8240
8241 test_56xg() {
8242         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8243         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8244         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8245                 skip "Need MDS version newer than 2.14.52"
8246
8247         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8248         local -a pool_ranges=("0 0" "1 1" "0 1")
8249
8250         # init pools
8251         for i in "${!pool_names[@]}"; do
8252                 pool_add ${pool_names[$i]} ||
8253                         error "pool_add failed (pool: ${pool_names[$i]})"
8254                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8255                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8256         done
8257
8258         # init the file to migrate
8259         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8260                 error "Unable to create $tfile on OST1"
8261         stack_trap "rm -f $DIR/$tfile"
8262         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8263                 error "Unable to write on $tfile"
8264
8265         echo "1. migrate $tfile on pool ${pool_names[0]}"
8266         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8267
8268         echo "2. migrate $tfile on pool ${pool_names[2]}"
8269         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8270
8271         echo "3. migrate $tfile on pool ${pool_names[1]}"
8272         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8273
8274         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8275         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8276         echo
8277
8278         # Clean pools
8279         destroy_test_pools ||
8280                 error "pool_destroy failed"
8281 }
8282 run_test 56xg "lfs migrate pool support"
8283
8284 test_56xh() {
8285         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8286
8287         local size_mb=25
8288         local file1=$DIR/$tfile
8289         local tmp1=$TMP/$tfile.tmp
8290
8291         $LFS setstripe -c 2 $file1
8292
8293         stack_trap "rm -f $file1 $tmp1"
8294         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8295                         error "error creating $tmp1"
8296         ls -lsh $tmp1
8297         cp $tmp1 $file1
8298
8299         local start=$SECONDS
8300
8301         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8302                 error "migrate failed rc = $?"
8303
8304         local elapsed=$((SECONDS - start))
8305
8306         # with 1MB/s, elapsed should equal size_mb
8307         (( elapsed >= size_mb * 95 / 100 )) ||
8308                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8309
8310         (( elapsed <= size_mb * 120 / 100 )) ||
8311                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8312
8313         (( elapsed <= size_mb * 350 / 100 )) ||
8314                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8315
8316         stripe=$($LFS getstripe -c $file1)
8317         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8318         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8319
8320         # Clean up file (since it is multiple MB)
8321         rm -f $file1 $tmp1
8322 }
8323 run_test 56xh "lfs migrate bandwidth limitation support"
8324
8325 test_56xi() {
8326         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8327         verify_yaml_available || skip_env "YAML verification not installed"
8328
8329         local size_mb=5
8330         local file1=$DIR/$tfile.1
8331         local file2=$DIR/$tfile.2
8332         local file3=$DIR/$tfile.3
8333         local output_file=$DIR/$tfile.out
8334         local tmp1=$TMP/$tfile.tmp
8335
8336         $LFS setstripe -c 2 $file1
8337         $LFS setstripe -c 2 $file2
8338         $LFS setstripe -c 2 $file3
8339
8340         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8341         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8342                         error "error creating $tmp1"
8343         ls -lsh $tmp1
8344         cp $tmp1 $file1
8345         cp $tmp1 $file2
8346         cp $tmp1 $file3
8347
8348         $LFS migrate --stats --stats-interval=1 \
8349                 -c 1 $file1 $file2 $file3 1> $output_file ||
8350                 error "migrate failed rc = $?"
8351
8352         cat $output_file
8353         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8354
8355         # Clean up file (since it is multiple MB)
8356         rm -f $file1 $file2 $file3 $tmp1 $output_file
8357 }
8358 run_test 56xi "lfs migrate stats support"
8359
8360 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8361         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8362
8363         local file=$DIR/$tfile
8364         local linkdir=$DIR/$tdir
8365
8366         test_mkdir $linkdir || error "fail to create $linkdir"
8367         $LFS setstripe -i 0 -c 1 -S1M $file
8368         stack_trap "rm -rf $file $linkdir"
8369         dd if=/dev/urandom of=$file bs=1M count=10 ||
8370                 error "fail to create $file"
8371
8372         # Create file links
8373         local cpts
8374         local threads_max
8375         local nlinks
8376
8377         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8378         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8379         (( nlinks = thread_max * 3 / 2 / cpts))
8380
8381         echo "create $nlinks hard links of $file"
8382         createmany -l $file $linkdir/link $nlinks
8383
8384         # Parallel migrates (should not block)
8385         local i
8386         for ((i = 0; i < nlinks; i++)); do
8387                 echo $linkdir/link$i
8388         done | xargs -n1 -P $nlinks $LFS migrate -c2
8389
8390         local stripe_count
8391         stripe_count=$($LFS getstripe -c $file) ||
8392                 error "fail to get stripe count on $file"
8393
8394         ((stripe_count == 2)) ||
8395                 error "fail to migrate $file (stripe_count = $stripe_count)"
8396 }
8397 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8398
8399 test_56xk() {
8400         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8401
8402         local size_mb=5
8403         local file1=$DIR/$tfile
8404
8405         stack_trap "rm -f $file1"
8406         $LFS setstripe -c 1 $file1
8407         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8408                 error "error creating $file1"
8409         $LFS mirror extend -N $file1 || error "can't mirror"
8410         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8411                 error "can't dd"
8412         $LFS getstripe $file1 | grep stale ||
8413                 error "one component must be stale"
8414
8415         local start=$SECONDS
8416         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8417                 error "migrate failed rc = $?"
8418         local elapsed=$((SECONDS - start))
8419         $LFS getstripe $file1 | grep stale &&
8420                 error "all components must be sync"
8421
8422         # with 1MB/s, elapsed should equal size_mb
8423         (( elapsed >= size_mb * 95 / 100 )) ||
8424                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8425
8426         (( elapsed <= size_mb * 120 / 100 )) ||
8427                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8428
8429         (( elapsed <= size_mb * 350 / 100 )) ||
8430                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8431 }
8432 run_test 56xk "lfs mirror resync bandwidth limitation support"
8433
8434 test_56xl() {
8435         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8436         verify_yaml_available || skip_env "YAML verification not installed"
8437
8438         local size_mb=5
8439         local file1=$DIR/$tfile.1
8440         local output_file=$DIR/$tfile.out
8441
8442         stack_trap "rm -f $file1"
8443         $LFS setstripe -c 1 $file1
8444         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8445                 error "error creating $file1"
8446         $LFS mirror extend -N $file1 || error "can't mirror"
8447         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8448                 error "can't dd"
8449         $LFS getstripe $file1 | grep stale ||
8450                 error "one component must be stale"
8451         $LFS getstripe $file1
8452
8453         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8454                 error "resync failed rc = $?"
8455         $LFS getstripe $file1 | grep stale &&
8456                 error "all components must be sync"
8457
8458         cat $output_file
8459         cat $output_file | verify_yaml || error "stats is not valid YAML"
8460 }
8461 run_test 56xl "lfs mirror resync stats support"
8462
8463 test_56y() {
8464         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8465                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8466
8467         local res=""
8468         local dir=$DIR/$tdir
8469         local f1=$dir/file1
8470         local f2=$dir/file2
8471
8472         test_mkdir -p $dir || error "creating dir $dir"
8473         touch $f1 || error "creating std file $f1"
8474         $MULTIOP $f2 H2c || error "creating released file $f2"
8475
8476         # a directory can be raid0, so ask only for files
8477         res=$($LFS find $dir -L raid0 -type f | wc -l)
8478         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8479
8480         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8481         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8482
8483         # only files can be released, so no need to force file search
8484         res=$($LFS find $dir -L released)
8485         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8486
8487         res=$($LFS find $dir -type f \! -L released)
8488         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8489 }
8490 run_test 56y "lfs find -L raid0|released"
8491
8492 test_56z() { # LU-4824
8493         # This checks to make sure 'lfs find' continues after errors
8494         # There are two classes of errors that should be caught:
8495         # - If multiple paths are provided, all should be searched even if one
8496         #   errors out
8497         # - If errors are encountered during the search, it should not terminate
8498         #   early
8499         local dir=$DIR/$tdir
8500         local i
8501
8502         test_mkdir $dir
8503         for i in d{0..9}; do
8504                 test_mkdir $dir/$i
8505                 touch $dir/$i/$tfile
8506         done
8507         $LFS find $DIR/non_existent_dir $dir &&
8508                 error "$LFS find did not return an error"
8509         # Make a directory unsearchable. This should NOT be the last entry in
8510         # directory order.  Arbitrarily pick the 6th entry
8511         chmod 700 $($LFS find $dir -type d | sed '6!d')
8512
8513         $RUNAS $LFS find $DIR/non_existent $dir
8514         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8515
8516         # The user should be able to see 10 directories and 9 files
8517         (( count == 19 )) ||
8518                 error "$LFS find found $count != 19 entries after error"
8519 }
8520 run_test 56z "lfs find should continue after an error"
8521
8522 test_56aa() { # LU-5937
8523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8524
8525         local dir=$DIR/$tdir
8526
8527         mkdir $dir
8528         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8529
8530         createmany -o $dir/striped_dir/${tfile}- 1024
8531         local dirs=$($LFS find --size +8k $dir/)
8532
8533         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8534 }
8535 run_test 56aa "lfs find --size under striped dir"
8536
8537 test_56ab() { # LU-10705
8538         test_mkdir $DIR/$tdir
8539         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8540         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8541         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8542         # Flush writes to ensure valid blocks.  Need to be more thorough for
8543         # ZFS, since blocks are not allocated/returned to client immediately.
8544         sync_all_data
8545         wait_zfs_commit ost1 2
8546         cancel_lru_locks osc
8547         ls -ls $DIR/$tdir
8548
8549         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8550
8551         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8552
8553         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8554         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8555
8556         rm -f $DIR/$tdir/$tfile.[123]
8557 }
8558 run_test 56ab "lfs find --blocks"
8559
8560 # LU-11188
8561 test_56aca() {
8562         local dir="$DIR/$tdir"
8563         local perms=(001 002 003 004 005 006 007
8564                      010 020 030 040 050 060 070
8565                      100 200 300 400 500 600 700
8566                      111 222 333 444 555 666 777)
8567         local perm_minus=(8 8 4 8 4 4 2
8568                           8 8 4 8 4 4 2
8569                           8 8 4 8 4 4 2
8570                           4 4 2 4 2 2 1)
8571         local perm_slash=(8  8 12  8 12 12 14
8572                           8  8 12  8 12 12 14
8573                           8  8 12  8 12 12 14
8574                          16 16 24 16 24 24 28)
8575
8576         test_mkdir "$dir"
8577         for perm in ${perms[*]}; do
8578                 touch "$dir/$tfile.$perm"
8579                 chmod $perm "$dir/$tfile.$perm"
8580         done
8581
8582         for ((i = 0; i < ${#perms[*]}; i++)); do
8583                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8584                 (( $num == 1 )) ||
8585                         error "lfs find -perm ${perms[i]}:"\
8586                               "$num != 1"
8587
8588                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8589                 (( $num == ${perm_minus[i]} )) ||
8590                         error "lfs find -perm -${perms[i]}:"\
8591                               "$num != ${perm_minus[i]}"
8592
8593                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8594                 (( $num == ${perm_slash[i]} )) ||
8595                         error "lfs find -perm /${perms[i]}:"\
8596                               "$num != ${perm_slash[i]}"
8597         done
8598 }
8599 run_test 56aca "check lfs find -perm with octal representation"
8600
8601 test_56acb() {
8602         local dir=$DIR/$tdir
8603         # p is the permission of write and execute for user, group and other
8604         # without the umask. It is used to test +wx.
8605         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8606         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8607         local symbolic=(+t  a+t u+t g+t o+t
8608                         g+s u+s o+s +s o+sr
8609                         o=r,ug+o,u+w
8610                         u+ g+ o+ a+ ugo+
8611                         u- g- o- a- ugo-
8612                         u= g= o= a= ugo=
8613                         o=r,ug+o,u+w u=r,a+u,u+w
8614                         g=r,ugo=g,u+w u+x,+X +X
8615                         u+x,u+X u+X u+x,g+X o+r,+X
8616                         u+x,go+X +wx +rwx)
8617
8618         test_mkdir $dir
8619         for perm in ${perms[*]}; do
8620                 touch "$dir/$tfile.$perm"
8621                 chmod $perm "$dir/$tfile.$perm"
8622         done
8623
8624         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8625                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8626
8627                 (( $num == 1 )) ||
8628                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8629         done
8630 }
8631 run_test 56acb "check lfs find -perm with symbolic representation"
8632
8633 test_56acc() {
8634         local dir=$DIR/$tdir
8635         local tests="17777 787 789 abcd
8636                 ug=uu ug=a ug=gu uo=ou urw
8637                 u+xg+x a=r,u+x,"
8638
8639         test_mkdir $dir
8640         for err in $tests; do
8641                 if $LFS find $dir -perm $err 2>/dev/null; then
8642                         error "lfs find -perm $err: parsing should have failed"
8643                 fi
8644         done
8645 }
8646 run_test 56acc "check parsing error for lfs find -perm"
8647
8648 test_56ba() {
8649         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8650                 skip "Need MDS version at least 2.10.50"
8651
8652         # Create composite files with one component
8653         local dir=$DIR/$tdir
8654
8655         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8656         # Create composite files with three components
8657         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8658         # LU-16904 Create plain layout files
8659         lfs setstripe -c 1 $dir/$tfile-{1..10}
8660
8661         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8662
8663         [[ $nfiles == 10 ]] ||
8664                 error "lfs find -E 1M found $nfiles != 10 files"
8665
8666         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8667         [[ $nfiles == 25 ]] ||
8668                 error "lfs find ! -E 1M found $nfiles != 25 files"
8669
8670         # All files have a component that starts at 0
8671         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8672         [[ $nfiles == 35 ]] ||
8673                 error "lfs find --component-start 0 - $nfiles != 35 files"
8674
8675         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8676         [[ $nfiles == 15 ]] ||
8677                 error "lfs find --component-start 2M - $nfiles != 15 files"
8678
8679         # All files created here have a componenet that does not starts at 2M
8680         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8681         [[ $nfiles == 35 ]] ||
8682                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8683
8684         # Find files with a specified number of components
8685         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8686         [[ $nfiles == 15 ]] ||
8687                 error "lfs find --component-count 3 - $nfiles != 15 files"
8688
8689         # Remember non-composite files have a component count of zero
8690         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8691         [[ $nfiles == 10 ]] ||
8692                 error "lfs find --component-count 0 - $nfiles != 10 files"
8693
8694         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8695         [[ $nfiles == 20 ]] ||
8696                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8697
8698         # All files have a flag called "init"
8699         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8700         [[ $nfiles == 35 ]] ||
8701                 error "lfs find --component-flags init - $nfiles != 35 files"
8702
8703         # Multi-component files will have a component not initialized
8704         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8705         [[ $nfiles == 15 ]] ||
8706                 error "lfs find !--component-flags init - $nfiles != 15 files"
8707
8708         rm -rf $dir
8709
8710 }
8711 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8712
8713 test_56ca() {
8714         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8715                 skip "Need MDS version at least 2.10.57"
8716
8717         local td=$DIR/$tdir
8718         local tf=$td/$tfile
8719         local dir
8720         local nfiles
8721         local cmd
8722         local i
8723         local j
8724
8725         # create mirrored directories and mirrored files
8726         mkdir $td || error "mkdir $td failed"
8727         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8728         createmany -o $tf- 10 || error "create $tf- failed"
8729
8730         for i in $(seq 2); do
8731                 dir=$td/dir$i
8732                 mkdir $dir || error "mkdir $dir failed"
8733                 $LFS mirror create -N$((3 + i)) $dir ||
8734                         error "create mirrored dir $dir failed"
8735                 createmany -o $dir/$tfile- 10 ||
8736                         error "create $dir/$tfile- failed"
8737         done
8738
8739         # change the states of some mirrored files
8740         echo foo > $tf-6
8741         for i in $(seq 2); do
8742                 dir=$td/dir$i
8743                 for j in $(seq 4 9); do
8744                         echo foo > $dir/$tfile-$j
8745                 done
8746         done
8747
8748         # find mirrored files with specific mirror count
8749         cmd="$LFS find --mirror-count 3 --type f $td"
8750         nfiles=$($cmd | wc -l)
8751         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8752
8753         cmd="$LFS find ! --mirror-count 3 --type f $td"
8754         nfiles=$($cmd | wc -l)
8755         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8756
8757         cmd="$LFS find --mirror-count +2 --type f $td"
8758         nfiles=$($cmd | wc -l)
8759         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8760
8761         cmd="$LFS find --mirror-count -6 --type f $td"
8762         nfiles=$($cmd | wc -l)
8763         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8764
8765         # find mirrored files with specific file state
8766         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8767         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8768
8769         cmd="$LFS find --mirror-state=ro --type f $td"
8770         nfiles=$($cmd | wc -l)
8771         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8772
8773         cmd="$LFS find ! --mirror-state=ro --type f $td"
8774         nfiles=$($cmd | wc -l)
8775         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8776
8777         cmd="$LFS find --mirror-state=wp --type f $td"
8778         nfiles=$($cmd | wc -l)
8779         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8780
8781         cmd="$LFS find ! --mirror-state=sp --type f $td"
8782         nfiles=$($cmd | wc -l)
8783         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8784 }
8785 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8786
8787 test_56da() { # LU-14179
8788         local path=$DIR/$tdir
8789
8790         test_mkdir $path
8791         cd $path
8792
8793         local longdir=$(str_repeat 'a' 255)
8794
8795         for i in {1..15}; do
8796                 path=$path/$longdir
8797                 test_mkdir $longdir
8798                 cd $longdir
8799         done
8800
8801         local len=${#path}
8802         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8803
8804         test_mkdir $lastdir
8805         cd $lastdir
8806         # PATH_MAX-1
8807         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8808
8809         # NAME_MAX
8810         touch $(str_repeat 'f' 255)
8811
8812         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8813                 error "lfs find reported an error"
8814
8815         rm -rf $DIR/$tdir
8816 }
8817 run_test 56da "test lfs find with long paths"
8818
8819 test_56ea() { #LU-10378
8820         local path=$DIR/$tdir
8821         local pool=$TESTNAME
8822
8823         # Create ost pool
8824         pool_add $pool || error "pool_add $pool failed"
8825         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8826                 error "adding targets to $pool failed"
8827
8828         # Set default pool on directory before creating file
8829         mkdir $path || error "mkdir $path failed"
8830         $LFS setstripe -p $pool $path ||
8831                 error "set OST pool on $pool failed"
8832         touch $path/$tfile || error "touch $path/$tfile failed"
8833
8834         # Compare basic file attributes from -printf and stat
8835         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8836         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8837
8838         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8839                 error "Attrs from lfs find and stat don't match"
8840
8841         # Compare Lustre attributes from lfs find and lfs getstripe
8842         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8843         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8844         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8845         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8846         local fpool=$($LFS getstripe --pool $path/$tfile)
8847         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8848
8849         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8850                 error "Attrs from lfs find and lfs getstripe don't match"
8851
8852         # Verify behavior for unknown escape/format sequences
8853         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8854
8855         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8856                 error "Escape/format codes don't match"
8857 }
8858 run_test 56ea "test lfs find -printf option"
8859
8860 test_56eb() {
8861         local dir=$DIR/$tdir
8862         local subdir_1=$dir/subdir_1
8863
8864         test_mkdir -p $subdir_1
8865         ln -s subdir_1 $dir/link_1
8866
8867         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8868                 error "symlink is not followed"
8869
8870         $LFS getstripe --no-follow $dir |
8871                 grep "^$dir/link_1 has no stripe info$" ||
8872                 error "symlink should not have stripe info"
8873
8874         touch $dir/testfile
8875         ln -s testfile $dir/file_link_2
8876
8877         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8878                 error "symlink is not followed"
8879
8880         $LFS getstripe --no-follow $dir |
8881                 grep "^$dir/file_link_2 has no stripe info$" ||
8882                 error "symlink should not have stripe info"
8883 }
8884 run_test 56eb "check lfs getstripe on symlink"
8885
8886 test_56ec() {
8887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8888         local dir=$DIR/$tdir
8889         local srcfile=$dir/srcfile
8890         local srcyaml=$dir/srcyaml
8891         local destfile=$dir/destfile
8892
8893         test_mkdir -p $dir
8894
8895         $LFS setstripe -i 1 $srcfile
8896         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8897         # if the setstripe yaml parsing fails for any reason, the command can
8898         # randomly assign the correct OST index, leading to an erroneous
8899         # success. but the chance of false success is low enough that a
8900         # regression should still be quickly caught.
8901         $LFS setstripe --yaml=$srcyaml $destfile
8902
8903         local srcindex=$($LFS getstripe -i $srcfile)
8904         local destindex=$($LFS getstripe -i $destfile)
8905
8906         if [[ ! $srcindex -eq $destindex ]]; then
8907                 error "setstripe did not set OST index correctly"
8908         fi
8909 }
8910 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8911
8912 test_56eda() {
8913         local dir=$DIR/$tdir
8914         local subdir=$dir/subdir
8915         local file1=$dir/$tfile
8916         local file2=$dir/$tfile\2
8917         local link=$dir/$tfile-link
8918         local nfiles
8919
8920         test_mkdir -p $dir
8921         $LFS setdirstripe -c1 $subdir
8922         touch $file1
8923         touch $file2
8924         ln $file2 $link
8925
8926         nfiles=$($LFS find --links 1 $dir | wc -l)
8927         (( $nfiles == 1 )) ||
8928                 error "lfs find --links expected 1 file, got $nfiles"
8929
8930         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8931         (( $nfiles == 2 )) ||
8932                 error "lfs find --links expected 2 files, got $nfiles"
8933
8934         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8935         (( $nfiles == 1 )) ||
8936                 error "lfs find --links expected 1 directory, got $nfiles"
8937 }
8938 run_test 56eda "check lfs find --links"
8939
8940 test_56edb() {
8941         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8942
8943         local dir=$DIR/$tdir
8944         local stripedir=$dir/stripedir
8945         local nfiles
8946
8947         test_mkdir -p $dir
8948
8949         $LFS setdirstripe -c2 $stripedir
8950
8951         $LFS getdirstripe $stripedir
8952
8953         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8954         (( $nfiles == 1 )) ||
8955                 error "lfs find --links expected 1 directory, got $nfiles"
8956 }
8957 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8958
8959 test_56ef() {
8960         local dir=$DIR/$tdir
8961         local dir1=$dir/d1
8962         local dir2=$dir/d2
8963         local nfiles
8964
8965         test_mkdir -p $dir
8966
8967         mkdir $dir1
8968         mkdir $dir2
8969
8970         touch $dir1/f
8971         touch $dir2/f
8972
8973         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8974         (( $nfiles == 2 )) ||
8975                 error "(1) lfs find expected 2 files, got $nfiles"
8976
8977         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8978         (( $nfiles == 2 )) ||
8979                 error "(2) lfs find expected 2 files, got $nfiles"
8980
8981         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
8982         (( $nfiles == 2 )) ||
8983                 error "(3) lfs find expected 2 files, got $nfiles"
8984 }
8985 run_test 56ef "lfs find with multiple paths"
8986
8987 test_57a() {
8988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8989         # note test will not do anything if MDS is not local
8990         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8991                 skip_env "ldiskfs only test"
8992         fi
8993         remote_mds_nodsh && skip "remote MDS with nodsh"
8994
8995         local MNTDEV="osd*.*MDT*.mntdev"
8996         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8997         [ -z "$DEV" ] && error "can't access $MNTDEV"
8998         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8999                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9000                         error "can't access $DEV"
9001                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9002                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9003                 rm $TMP/t57a.dump
9004         done
9005 }
9006 run_test 57a "verify MDS filesystem created with large inodes =="
9007
9008 test_57b() {
9009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9010         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9011                 skip_env "ldiskfs only test"
9012         fi
9013         remote_mds_nodsh && skip "remote MDS with nodsh"
9014
9015         local dir=$DIR/$tdir
9016         local filecount=100
9017         local file1=$dir/f1
9018         local fileN=$dir/f$filecount
9019
9020         rm -rf $dir || error "removing $dir"
9021         test_mkdir -c1 $dir
9022         local mdtidx=$($LFS getstripe -m $dir)
9023         local mdtname=MDT$(printf %04x $mdtidx)
9024         local facet=mds$((mdtidx + 1))
9025
9026         echo "mcreating $filecount files"
9027         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9028
9029         # verify that files do not have EAs yet
9030         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9031                 error "$file1 has an EA"
9032         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9033                 error "$fileN has an EA"
9034
9035         sync
9036         sleep 1
9037         df $dir  #make sure we get new statfs data
9038         local mdsfree=$(do_facet $facet \
9039                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9040         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9041         local file
9042
9043         echo "opening files to create objects/EAs"
9044         for file in $(seq -f $dir/f%g 1 $filecount); do
9045                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9046                         error "opening $file"
9047         done
9048
9049         # verify that files have EAs now
9050         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9051                 error "$file1 missing EA"
9052         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9053                 error "$fileN missing EA"
9054
9055         sleep 1  #make sure we get new statfs data
9056         df $dir
9057         local mdsfree2=$(do_facet $facet \
9058                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9059         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9060
9061         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9062                 if [ "$mdsfree" != "$mdsfree2" ]; then
9063                         error "MDC before $mdcfree != after $mdcfree2"
9064                 else
9065                         echo "MDC before $mdcfree != after $mdcfree2"
9066                         echo "unable to confirm if MDS has large inodes"
9067                 fi
9068         fi
9069         rm -rf $dir
9070 }
9071 run_test 57b "default LOV EAs are stored inside large inodes ==="
9072
9073 test_58() {
9074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9075         [ -z "$(which wiretest 2>/dev/null)" ] &&
9076                         skip_env "could not find wiretest"
9077
9078         wiretest
9079 }
9080 run_test 58 "verify cross-platform wire constants =============="
9081
9082 test_59() {
9083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9084
9085         echo "touch 130 files"
9086         createmany -o $DIR/f59- 130
9087         echo "rm 130 files"
9088         unlinkmany $DIR/f59- 130
9089         sync
9090         # wait for commitment of removal
9091         wait_delete_completed
9092 }
9093 run_test 59 "verify cancellation of llog records async ========="
9094
9095 TEST60_HEAD="test_60 run $RANDOM"
9096 test_60a() {
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098         remote_mgs_nodsh && skip "remote MGS with nodsh"
9099         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9100                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9101                         skip_env "missing subtest run-llog.sh"
9102
9103         log "$TEST60_HEAD - from kernel mode"
9104         do_facet mgs "$LCTL dk > /dev/null"
9105         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9106         do_facet mgs $LCTL dk > $TMP/$tfile
9107
9108         # LU-6388: test llog_reader
9109         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9110         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9111         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9112                         skip_env "missing llog_reader"
9113         local fstype=$(facet_fstype mgs)
9114         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9115                 skip_env "Only for ldiskfs or zfs type mgs"
9116
9117         local mntpt=$(facet_mntpt mgs)
9118         local mgsdev=$(mgsdevname 1)
9119         local fid_list
9120         local fid
9121         local rec_list
9122         local rec
9123         local rec_type
9124         local obj_file
9125         local path
9126         local seq
9127         local oid
9128         local pass=true
9129
9130         #get fid and record list
9131         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9132                 tail -n 4))
9133         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9134                 tail -n 4))
9135         #remount mgs as ldiskfs or zfs type
9136         stop mgs || error "stop mgs failed"
9137         mount_fstype mgs || error "remount mgs failed"
9138         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9139                 fid=${fid_list[i]}
9140                 rec=${rec_list[i]}
9141                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9142                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9143                 oid=$((16#$oid))
9144
9145                 case $fstype in
9146                         ldiskfs )
9147                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9148                         zfs )
9149                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9150                 esac
9151                 echo "obj_file is $obj_file"
9152                 do_facet mgs $llog_reader $obj_file
9153
9154                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9155                         awk '{ print $3 }' | sed -e "s/^type=//g")
9156                 if [ $rec_type != $rec ]; then
9157                         echo "FAILED test_60a wrong record type $rec_type," \
9158                               "should be $rec"
9159                         pass=false
9160                         break
9161                 fi
9162
9163                 #check obj path if record type is LLOG_LOGID_MAGIC
9164                 if [ "$rec" == "1064553b" ]; then
9165                         path=$(do_facet mgs $llog_reader $obj_file |
9166                                 grep "path=" | awk '{ print $NF }' |
9167                                 sed -e "s/^path=//g")
9168                         if [ $obj_file != $mntpt/$path ]; then
9169                                 echo "FAILED test_60a wrong obj path" \
9170                                       "$montpt/$path, should be $obj_file"
9171                                 pass=false
9172                                 break
9173                         fi
9174                 fi
9175         done
9176         rm -f $TMP/$tfile
9177         #restart mgs before "error", otherwise it will block the next test
9178         stop mgs || error "stop mgs failed"
9179         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9180         $pass || error "test failed, see FAILED test_60a messages for specifics"
9181 }
9182 run_test 60a "llog_test run from kernel module and test llog_reader"
9183
9184 test_60b() { # bug 6411
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186
9187         dmesg > $DIR/$tfile
9188         LLOG_COUNT=$(do_facet mgs dmesg |
9189                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9190                           /llog_[a-z]*.c:[0-9]/ {
9191                                 if (marker)
9192                                         from_marker++
9193                                 from_begin++
9194                           }
9195                           END {
9196                                 if (marker)
9197                                         print from_marker
9198                                 else
9199                                         print from_begin
9200                           }")
9201
9202         [[ $LLOG_COUNT -gt 120 ]] &&
9203                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9204 }
9205 run_test 60b "limit repeated messages from CERROR/CWARN"
9206
9207 test_60c() {
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         echo "create 5000 files"
9211         createmany -o $DIR/f60c- 5000
9212 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9213         lctl set_param fail_loc=0x80000137
9214         unlinkmany $DIR/f60c- 5000
9215         lctl set_param fail_loc=0
9216 }
9217 run_test 60c "unlink file when mds full"
9218
9219 test_60d() {
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221
9222         SAVEPRINTK=$(lctl get_param -n printk)
9223         # verify "lctl mark" is even working"
9224         MESSAGE="test message ID $RANDOM $$"
9225         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9226         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9227
9228         lctl set_param printk=0 || error "set lnet.printk failed"
9229         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9230         MESSAGE="new test message ID $RANDOM $$"
9231         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9232         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9233         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9234
9235         lctl set_param -n printk="$SAVEPRINTK"
9236 }
9237 run_test 60d "test printk console message masking"
9238
9239 test_60e() {
9240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9241         remote_mds_nodsh && skip "remote MDS with nodsh"
9242
9243         touch $DIR/$tfile
9244 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9245         do_facet mds1 lctl set_param fail_loc=0x15b
9246         rm $DIR/$tfile
9247 }
9248 run_test 60e "no space while new llog is being created"
9249
9250 test_60f() {
9251         local old_path=$($LCTL get_param -n debug_path)
9252
9253         stack_trap "$LCTL set_param debug_path=$old_path"
9254         stack_trap "rm -f $TMP/$tfile*"
9255         rm -f $TMP/$tfile* 2> /dev/null
9256         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9257         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9258         test_mkdir $DIR/$tdir
9259         # retry in case the open is cached and not released
9260         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9261                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9262                 sleep 0.1
9263         done
9264         ls $TMP/$tfile*
9265         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9266 }
9267 run_test 60f "change debug_path works"
9268
9269 test_60g() {
9270         local pid
9271         local i
9272
9273         test_mkdir -c $MDSCOUNT $DIR/$tdir
9274
9275         (
9276                 local index=0
9277                 while true; do
9278                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9279                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9280                                 2>/dev/null
9281                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9282                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9283                         index=$((index + 1))
9284                 done
9285         ) &
9286
9287         pid=$!
9288
9289         for i in {0..100}; do
9290                 # define OBD_FAIL_OSD_TXN_START    0x19a
9291                 local index=$((i % MDSCOUNT + 1))
9292
9293                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9294                         > /dev/null
9295                 sleep 0.01
9296         done
9297
9298         kill -9 $pid
9299
9300         for i in $(seq $MDSCOUNT); do
9301                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9302         done
9303
9304         mkdir $DIR/$tdir/new || error "mkdir failed"
9305         rmdir $DIR/$tdir/new || error "rmdir failed"
9306
9307         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9308                 -t namespace
9309         for i in $(seq $MDSCOUNT); do
9310                 wait_update_facet mds$i "$LCTL get_param -n \
9311                         mdd.$(facet_svc mds$i).lfsck_namespace |
9312                         awk '/^status/ { print \\\$2 }'" "completed"
9313         done
9314
9315         ls -R $DIR/$tdir
9316         rm -rf $DIR/$tdir || error "rmdir failed"
9317 }
9318 run_test 60g "transaction abort won't cause MDT hung"
9319
9320 test_60h() {
9321         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9322                 skip "Need MDS version at least 2.12.52"
9323         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9324
9325         local f
9326
9327         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9328         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9329         for fail_loc in 0x80000188 0x80000189; do
9330                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9331                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9332                         error "mkdir $dir-$fail_loc failed"
9333                 for i in {0..10}; do
9334                         # create may fail on missing stripe
9335                         echo $i > $DIR/$tdir-$fail_loc/$i
9336                 done
9337                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9338                         error "getdirstripe $tdir-$fail_loc failed"
9339                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9340                         error "migrate $tdir-$fail_loc failed"
9341                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9342                         error "getdirstripe $tdir-$fail_loc failed"
9343                 pushd $DIR/$tdir-$fail_loc
9344                 for f in *; do
9345                         echo $f | cmp $f - || error "$f data mismatch"
9346                 done
9347                 popd
9348                 rm -rf $DIR/$tdir-$fail_loc
9349         done
9350 }
9351 run_test 60h "striped directory with missing stripes can be accessed"
9352
9353 function t60i_load() {
9354         mkdir $DIR/$tdir
9355         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9356         $LCTL set_param fail_loc=0x131c fail_val=1
9357         for ((i=0; i<5000; i++)); do
9358                 touch $DIR/$tdir/f$i
9359         done
9360 }
9361
9362 test_60i() {
9363         changelog_register || error "changelog_register failed"
9364         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9365         changelog_users $SINGLEMDS | grep -q $cl_user ||
9366                 error "User $cl_user not found in changelog_users"
9367         changelog_chmask "ALL"
9368         t60i_load &
9369         local PID=$!
9370         for((i=0; i<100; i++)); do
9371                 changelog_dump >/dev/null ||
9372                         error "can't read changelog"
9373         done
9374         kill $PID
9375         wait $PID
9376         changelog_deregister || error "changelog_deregister failed"
9377         $LCTL set_param fail_loc=0
9378 }
9379 run_test 60i "llog: new record vs reader race"
9380
9381 test_60j() {
9382         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9383                 skip "need MDS version at least 2.15.50"
9384         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9385         remote_mds_nodsh && skip "remote MDS with nodsh"
9386         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9387
9388         changelog_users $SINGLEMDS | grep "^cl" &&
9389                 skip "active changelog user"
9390
9391         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9392
9393         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9394                 skip_env "missing llog_reader"
9395
9396         mkdir_on_mdt0 $DIR/$tdir
9397
9398         local f=$DIR/$tdir/$tfile
9399         local mdt_dev
9400         local tmpfile
9401         local plain
9402
9403         changelog_register || error "cannot register changelog user"
9404
9405         # set changelog_mask to ALL
9406         changelog_chmask "ALL"
9407         changelog_clear
9408
9409         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9410         unlinkmany ${f}- 100 || error "unlinkmany failed"
9411
9412         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9413         mdt_dev=$(facet_device $SINGLEMDS)
9414
9415         do_facet $SINGLEMDS sync
9416         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9417                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9418                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9419
9420         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9421
9422         # if $tmpfile is not on EXT3 filesystem for some reason
9423         [[ ${plain:0:1} == 'O' ]] ||
9424                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9425
9426         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9427                 $mdt_dev; stat -c %s $tmpfile")
9428         echo "Truncate llog from $size to $((size - size % 8192))"
9429         size=$((size - size % 8192))
9430         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9431         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9432                 grep -c 'in bitmap only')
9433         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9434
9435         size=$((size - 9000))
9436         echo "Corrupt llog in the middle at $size"
9437         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9438                 count=333 conv=notrunc
9439         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9440                 grep -c 'next chunk')
9441         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9442 }
9443 run_test 60j "llog_reader reports corruptions"
9444
9445 test_61a() {
9446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9447
9448         f="$DIR/f61"
9449         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9450         cancel_lru_locks osc
9451         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9452         sync
9453 }
9454 run_test 61a "mmap() writes don't make sync hang ================"
9455
9456 test_61b() {
9457         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9458 }
9459 run_test 61b "mmap() of unstriped file is successful"
9460
9461 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9462 # Though this test is irrelevant anymore, it helped to reveal some
9463 # other grant bugs (LU-4482), let's keep it.
9464 test_63a() {   # was test_63
9465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9466
9467         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9468
9469         for i in `seq 10` ; do
9470                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9471                 sleep 5
9472                 kill $!
9473                 sleep 1
9474         done
9475
9476         rm -f $DIR/f63 || true
9477 }
9478 run_test 63a "Verify oig_wait interruption does not crash ======="
9479
9480 # bug 2248 - async write errors didn't return to application on sync
9481 # bug 3677 - async write errors left page locked
9482 test_63b() {
9483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9484
9485         debugsave
9486         lctl set_param debug=-1
9487
9488         # ensure we have a grant to do async writes
9489         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9490         rm $DIR/$tfile
9491
9492         sync    # sync lest earlier test intercept the fail_loc
9493
9494         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9495         lctl set_param fail_loc=0x80000406
9496         $MULTIOP $DIR/$tfile Owy && \
9497                 error "sync didn't return ENOMEM"
9498         sync; sleep 2; sync     # do a real sync this time to flush page
9499         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9500                 error "locked page left in cache after async error" || true
9501         debugrestore
9502 }
9503 run_test 63b "async write errors should be returned to fsync ==="
9504
9505 test_64a () {
9506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9507
9508         lfs df $DIR
9509         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9510 }
9511 run_test 64a "verify filter grant calculations (in kernel) ====="
9512
9513 test_64b () {
9514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9515
9516         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9517 }
9518 run_test 64b "check out-of-space detection on client"
9519
9520 test_64c() {
9521         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9522 }
9523 run_test 64c "verify grant shrink"
9524
9525 import_param() {
9526         local tgt=$1
9527         local param=$2
9528
9529         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9530 }
9531
9532 # this does exactly what osc_request.c:osc_announce_cached() does in
9533 # order to calculate max amount of grants to ask from server
9534 want_grant() {
9535         local tgt=$1
9536
9537         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9538         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9539
9540         ((rpc_in_flight++));
9541         nrpages=$((nrpages * rpc_in_flight))
9542
9543         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9544
9545         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9546
9547         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9548         local undirty=$((nrpages * PAGE_SIZE))
9549
9550         local max_extent_pages
9551         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9552         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9553         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9554         local grant_extent_tax
9555         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9556
9557         undirty=$((undirty + nrextents * grant_extent_tax))
9558
9559         echo $undirty
9560 }
9561
9562 # this is size of unit for grant allocation. It should be equal to
9563 # what tgt_grant.c:tgt_grant_chunk() calculates
9564 grant_chunk() {
9565         local tgt=$1
9566         local max_brw_size
9567         local grant_extent_tax
9568
9569         max_brw_size=$(import_param $tgt max_brw_size)
9570
9571         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9572
9573         echo $(((max_brw_size + grant_extent_tax) * 2))
9574 }
9575
9576 test_64d() {
9577         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9578                 skip "OST < 2.10.55 doesn't limit grants enough"
9579
9580         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9581
9582         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9583                 skip "no grant_param connect flag"
9584
9585         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9586
9587         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9588         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9589
9590
9591         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9592         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9593
9594         $LFS setstripe $DIR/$tfile -i 0 -c 1
9595         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9596         ddpid=$!
9597
9598         while kill -0 $ddpid; do
9599                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9600
9601                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9602                         kill $ddpid
9603                         error "cur_grant $cur_grant > $max_cur_granted"
9604                 fi
9605
9606                 sleep 1
9607         done
9608 }
9609 run_test 64d "check grant limit exceed"
9610
9611 check_grants() {
9612         local tgt=$1
9613         local expected=$2
9614         local msg=$3
9615         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9616
9617         ((cur_grants == expected)) ||
9618                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9619 }
9620
9621 round_up_p2() {
9622         echo $((($1 + $2 - 1) & ~($2 - 1)))
9623 }
9624
9625 test_64e() {
9626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9627         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9628                 skip "Need OSS version at least 2.11.56"
9629
9630         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9631         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9632         $LCTL set_param debug=+cache
9633
9634         # Remount client to reset grant
9635         remount_client $MOUNT || error "failed to remount client"
9636         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9637
9638         local init_grants=$(import_param $osc_tgt initial_grant)
9639
9640         check_grants $osc_tgt $init_grants "init grants"
9641
9642         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9643         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9644         local gbs=$(import_param $osc_tgt grant_block_size)
9645
9646         # write random number of bytes from max_brw_size / 4 to max_brw_size
9647         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9648         # align for direct io
9649         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9650         # round to grant consumption unit
9651         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9652
9653         local grants=$((wb_round_up + extent_tax))
9654
9655         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9656         stack_trap "rm -f $DIR/$tfile"
9657
9658         # define OBD_FAIL_TGT_NO_GRANT 0x725
9659         # make the server not grant more back
9660         do_facet ost1 $LCTL set_param fail_loc=0x725
9661         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9662
9663         do_facet ost1 $LCTL set_param fail_loc=0
9664
9665         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9666
9667         rm -f $DIR/$tfile || error "rm failed"
9668
9669         # Remount client to reset grant
9670         remount_client $MOUNT || error "failed to remount client"
9671         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9672
9673         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9674
9675         # define OBD_FAIL_TGT_NO_GRANT 0x725
9676         # make the server not grant more back
9677         do_facet ost1 $LCTL set_param fail_loc=0x725
9678         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9679         do_facet ost1 $LCTL set_param fail_loc=0
9680
9681         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9682 }
9683 run_test 64e "check grant consumption (no grant allocation)"
9684
9685 test_64f() {
9686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9687
9688         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9689         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9690         $LCTL set_param debug=+cache
9691
9692         # Remount client to reset grant
9693         remount_client $MOUNT || error "failed to remount client"
9694         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9695
9696         local init_grants=$(import_param $osc_tgt initial_grant)
9697         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9698         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9699         local gbs=$(import_param $osc_tgt grant_block_size)
9700         local chunk=$(grant_chunk $osc_tgt)
9701
9702         # write random number of bytes from max_brw_size / 4 to max_brw_size
9703         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9704         # align for direct io
9705         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9706         # round to grant consumption unit
9707         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9708
9709         local grants=$((wb_round_up + extent_tax))
9710
9711         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9712         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9713                 error "error writing to $DIR/$tfile"
9714
9715         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9716                 "direct io with grant allocation"
9717
9718         rm -f $DIR/$tfile || error "rm failed"
9719
9720         # Remount client to reset grant
9721         remount_client $MOUNT || error "failed to remount client"
9722         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9723
9724         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9725
9726         # Testing that buffered IO consumes grant on the client
9727
9728         # Delay the RPC on the server so it's guaranteed to not complete even
9729         # if the RPC is sent from the client
9730         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9731         $LCTL set_param fail_loc=0x50a fail_val=3
9732         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9733                 error "error writing to $DIR/$tfile with buffered IO"
9734
9735         check_grants $osc_tgt $((init_grants - grants)) \
9736                 "buffered io, not write rpc"
9737
9738         # Clear the fail loc and do a sync on the client
9739         $LCTL set_param fail_loc=0 fail_val=0
9740         sync
9741
9742         # RPC is now known to have sent
9743         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9744                 "buffered io, one RPC"
9745 }
9746 run_test 64f "check grant consumption (with grant allocation)"
9747
9748 test_64g() {
9749         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9750                 skip "Need MDS version at least 2.14.56"
9751
9752         local mdts=$(comma_list $(mdts_nodes))
9753
9754         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9755                         tr '\n' ' ')
9756         stack_trap "$LCTL set_param $old"
9757
9758         # generate dirty pages and increase dirty granted on MDT
9759         stack_trap "rm -f $DIR/$tfile-*"
9760         for (( i = 0; i < 10; i++)); do
9761                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9762                         error "can't set stripe"
9763                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9764                         error "can't dd"
9765                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9766                         $LFS getstripe $DIR/$tfile-$i
9767                         error "not DoM file"
9768                 }
9769         done
9770
9771         # flush dirty pages
9772         sync
9773
9774         # wait until grant shrink reset grant dirty on MDTs
9775         for ((i = 0; i < 120; i++)); do
9776                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9777                         awk '{sum=sum+$1} END {print sum}')
9778                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9779                 echo "$grant_dirty grants, $vm_dirty pages"
9780                 (( grant_dirty + vm_dirty == 0 )) && break
9781                 (( i == 3 )) && sync &&
9782                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9783                 sleep 1
9784         done
9785
9786         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9787                 awk '{sum=sum+$1} END {print sum}')
9788         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9789 }
9790 run_test 64g "grant shrink on MDT"
9791
9792 test_64h() {
9793         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9794                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9795
9796         local instance=$($LFS getname -i $DIR)
9797         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9798         local num_exps=$(do_facet ost1 \
9799             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9800         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9801         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9802         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9803
9804         # 10MiB is for file to be written, max_brw_size * 16 *
9805         # num_exps is space reserve so that tgt_grant_shrink() decided
9806         # to not shrink
9807         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9808         (( avail * 1024 < expect )) &&
9809                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9810
9811         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9812         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9813         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9814         $LCTL set_param osc.*OST0000*.grant_shrink=1
9815         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9816
9817         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9818         stack_trap "rm -f $DIR/$tfile"
9819         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9820
9821         # drop cache so that coming read would do rpc
9822         cancel_lru_locks osc
9823
9824         # shrink interval is set to 10, pause for 7 seconds so that
9825         # grant thread did not wake up yet but coming read entered
9826         # shrink mode for rpc (osc_should_shrink_grant())
9827         sleep 7
9828
9829         declare -a cur_grant_bytes
9830         declare -a tot_granted
9831         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9832         tot_granted[0]=$(do_facet ost1 \
9833             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9834
9835         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9836
9837         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9838         tot_granted[1]=$(do_facet ost1 \
9839             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9840
9841         # grant change should be equal on both sides
9842         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9843                 tot_granted[0] - tot_granted[1])) ||
9844                 error "grant change mismatch, "                                \
9845                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9846                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9847 }
9848 run_test 64h "grant shrink on read"
9849
9850 test_64i() {
9851         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9852                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9853
9854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9855         remote_ost_nodsh && skip "remote OSTs with nodsh"
9856
9857         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9858         stack_trap "rm -f $DIR/$tfile"
9859
9860         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9861
9862         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9863         local instance=$($LFS getname -i $DIR)
9864
9865         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9866         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9867
9868         # shrink grants and simulate rpc loss
9869         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9870         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9871         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9872
9873         fail ost1
9874
9875         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9876
9877         local testid=$(echo $TESTNAME | tr '_' ' ')
9878
9879         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9880                 grep "GRANT, real grant" &&
9881                 error "client has more grants then it owns" || true
9882 }
9883 run_test 64i "shrink on reconnect"
9884
9885 # bug 1414 - set/get directories' stripe info
9886 test_65a() {
9887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9888
9889         test_mkdir $DIR/$tdir
9890         touch $DIR/$tdir/f1
9891         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9892 }
9893 run_test 65a "directory with no stripe info"
9894
9895 test_65b() {
9896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9897
9898         test_mkdir $DIR/$tdir
9899         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9900
9901         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9902                                                 error "setstripe"
9903         touch $DIR/$tdir/f2
9904         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9905 }
9906 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9907
9908 test_65c() {
9909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9910         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9911
9912         test_mkdir $DIR/$tdir
9913         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9914
9915         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9916                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9917         touch $DIR/$tdir/f3
9918         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9919 }
9920 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9921
9922 test_65d() {
9923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9924
9925         test_mkdir $DIR/$tdir
9926         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9927         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9928
9929         if [[ $STRIPECOUNT -le 0 ]]; then
9930                 sc=1
9931         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9932                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9933                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9934         else
9935                 sc=$(($STRIPECOUNT - 1))
9936         fi
9937         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9938         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9939         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9940                 error "lverify failed"
9941 }
9942 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9943
9944 test_65e() {
9945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9946
9947         # LU-16904 delete layout when root is set as PFL layout
9948         save_layout_restore_at_exit $MOUNT
9949         $LFS setstripe -d $MOUNT || error "setstripe failed"
9950
9951         test_mkdir $DIR/$tdir
9952
9953         $LFS setstripe $DIR/$tdir || error "setstripe"
9954         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9955                                         error "no stripe info failed"
9956         touch $DIR/$tdir/f6
9957         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9958 }
9959 run_test 65e "directory setstripe defaults"
9960
9961 test_65f() {
9962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9963
9964         test_mkdir $DIR/${tdir}f
9965         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9966                 error "setstripe succeeded" || true
9967 }
9968 run_test 65f "dir setstripe permission (should return error) ==="
9969
9970 test_65g() {
9971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9972
9973         # LU-16904 delete layout when root is set as PFL layout
9974         save_layout_restore_at_exit $MOUNT
9975         $LFS setstripe -d $MOUNT || error "setstripe failed"
9976
9977         test_mkdir $DIR/$tdir
9978         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9979
9980         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9981                 error "setstripe -S failed"
9982         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9983         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9984                 error "delete default stripe failed"
9985 }
9986 run_test 65g "directory setstripe -d"
9987
9988 test_65h() {
9989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9990
9991         test_mkdir $DIR/$tdir
9992         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9993
9994         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9995                 error "setstripe -S failed"
9996         test_mkdir $DIR/$tdir/dd1
9997         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9998                 error "stripe info inherit failed"
9999 }
10000 run_test 65h "directory stripe info inherit ===================="
10001
10002 test_65i() {
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004
10005         save_layout_restore_at_exit $MOUNT
10006
10007         # bug6367: set non-default striping on root directory
10008         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10009
10010         # bug12836: getstripe on -1 default directory striping
10011         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10012
10013         # bug12836: getstripe -v on -1 default directory striping
10014         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10015
10016         # bug12836: new find on -1 default directory striping
10017         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10018 }
10019 run_test 65i "various tests to set root directory striping"
10020
10021 test_65j() { # bug6367
10022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10023
10024         sync; sleep 1
10025
10026         # if we aren't already remounting for each test, do so for this test
10027         if [ "$I_MOUNTED" = "yes" ]; then
10028                 cleanup || error "failed to unmount"
10029                 setup
10030         fi
10031
10032         save_layout_restore_at_exit $MOUNT
10033
10034         $LFS setstripe -d $MOUNT || error "setstripe failed"
10035 }
10036 run_test 65j "set default striping on root directory (bug 6367)="
10037
10038 cleanup_65k() {
10039         rm -rf $DIR/$tdir
10040         wait_delete_completed
10041         do_facet $SINGLEMDS "lctl set_param -n \
10042                 osp.$ost*MDT0000.max_create_count=$max_count"
10043         do_facet $SINGLEMDS "lctl set_param -n \
10044                 osp.$ost*MDT0000.create_count=$count"
10045         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10046         echo $INACTIVE_OSC "is Activate"
10047
10048         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10049 }
10050
10051 test_65k() { # bug11679
10052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10054         remote_mds_nodsh && skip "remote MDS with nodsh"
10055
10056         local disable_precreate=true
10057         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10058                 disable_precreate=false
10059
10060         echo "Check OST status: "
10061         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10062                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10063
10064         for OSC in $MDS_OSCS; do
10065                 echo $OSC "is active"
10066                 do_facet $SINGLEMDS lctl --device %$OSC activate
10067         done
10068
10069         for INACTIVE_OSC in $MDS_OSCS; do
10070                 local ost=$(osc_to_ost $INACTIVE_OSC)
10071                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10072                                lov.*md*.target_obd |
10073                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10074
10075                 mkdir -p $DIR/$tdir
10076                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10077                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10078
10079                 echo "Deactivate: " $INACTIVE_OSC
10080                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10081
10082                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10083                               osp.$ost*MDT0000.create_count")
10084                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10085                                   osp.$ost*MDT0000.max_create_count")
10086                 $disable_precreate &&
10087                         do_facet $SINGLEMDS "lctl set_param -n \
10088                                 osp.$ost*MDT0000.max_create_count=0"
10089
10090                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10091                         [ -f $DIR/$tdir/$idx ] && continue
10092                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10093                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10094                                 { cleanup_65k;
10095                                   error "setstripe $idx should succeed"; }
10096                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10097                 done
10098                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10099                 rmdir $DIR/$tdir
10100
10101                 do_facet $SINGLEMDS "lctl set_param -n \
10102                         osp.$ost*MDT0000.max_create_count=$max_count"
10103                 do_facet $SINGLEMDS "lctl set_param -n \
10104                         osp.$ost*MDT0000.create_count=$count"
10105                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10106                 echo $INACTIVE_OSC "is Activate"
10107
10108                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10109         done
10110 }
10111 run_test 65k "validate manual striping works properly with deactivated OSCs"
10112
10113 test_65l() { # bug 12836
10114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10115
10116         test_mkdir -p $DIR/$tdir/test_dir
10117         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10118         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10119 }
10120 run_test 65l "lfs find on -1 stripe dir ========================"
10121
10122 test_65m() {
10123         local layout=$(save_layout $MOUNT)
10124         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10125                 restore_layout $MOUNT $layout
10126                 error "setstripe should fail by non-root users"
10127         }
10128         true
10129 }
10130 run_test 65m "normal user can't set filesystem default stripe"
10131
10132 test_65n() {
10133         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10134         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10135                 skip "Need MDS version at least 2.12.50"
10136         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10137
10138         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10139         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10140         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10141
10142         save_layout_restore_at_exit $MOUNT
10143
10144         # new subdirectory under root directory should not inherit
10145         # the default layout from root
10146         # LU-16904 check if the root is set as PFL layout
10147         local numcomp=$($LFS getstripe --component-count $MOUNT)
10148
10149         if [[ $numcomp -eq 0 ]]; then
10150                 local dir1=$MOUNT/$tdir-1
10151                 mkdir $dir1 || error "mkdir $dir1 failed"
10152                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10153                         error "$dir1 shouldn't have LOV EA"
10154         fi
10155
10156         # delete the default layout on root directory
10157         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10158
10159         local dir2=$MOUNT/$tdir-2
10160         mkdir $dir2 || error "mkdir $dir2 failed"
10161         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10162                 error "$dir2 shouldn't have LOV EA"
10163
10164         # set a new striping pattern on root directory
10165         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10166         local new_def_stripe_size=$((def_stripe_size * 2))
10167         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10168                 error "set stripe size on $MOUNT failed"
10169
10170         # new file created in $dir2 should inherit the new stripe size from
10171         # the filesystem default
10172         local file2=$dir2/$tfile-2
10173         touch $file2 || error "touch $file2 failed"
10174
10175         local file2_stripe_size=$($LFS getstripe -S $file2)
10176         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10177         {
10178                 echo "file2_stripe_size: '$file2_stripe_size'"
10179                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10180                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10181         }
10182
10183         local dir3=$MOUNT/$tdir-3
10184         mkdir $dir3 || error "mkdir $dir3 failed"
10185         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10186         # the root layout, which is the actual default layout that will be used
10187         # when new files are created in $dir3.
10188         local dir3_layout=$(get_layout_param $dir3)
10189         local root_dir_layout=$(get_layout_param $MOUNT)
10190         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10191         {
10192                 echo "dir3_layout: '$dir3_layout'"
10193                 echo "root_dir_layout: '$root_dir_layout'"
10194                 error "$dir3 should show the default layout from $MOUNT"
10195         }
10196
10197         # set OST pool on root directory
10198         local pool=$TESTNAME
10199         pool_add $pool || error "add $pool failed"
10200         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10201                 error "add targets to $pool failed"
10202
10203         $LFS setstripe -p $pool $MOUNT ||
10204                 error "set OST pool on $MOUNT failed"
10205
10206         # new file created in $dir3 should inherit the pool from
10207         # the filesystem default
10208         local file3=$dir3/$tfile-3
10209         touch $file3 || error "touch $file3 failed"
10210
10211         local file3_pool=$($LFS getstripe -p $file3)
10212         [[ "$file3_pool" = "$pool" ]] ||
10213                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10214
10215         local dir4=$MOUNT/$tdir-4
10216         mkdir $dir4 || error "mkdir $dir4 failed"
10217         local dir4_layout=$(get_layout_param $dir4)
10218         root_dir_layout=$(get_layout_param $MOUNT)
10219         echo "$LFS getstripe -d $dir4"
10220         $LFS getstripe -d $dir4
10221         echo "$LFS getstripe -d $MOUNT"
10222         $LFS getstripe -d $MOUNT
10223         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10224         {
10225                 echo "dir4_layout: '$dir4_layout'"
10226                 echo "root_dir_layout: '$root_dir_layout'"
10227                 error "$dir4 should show the default layout from $MOUNT"
10228         }
10229
10230         # new file created in $dir4 should inherit the pool from
10231         # the filesystem default
10232         local file4=$dir4/$tfile-4
10233         touch $file4 || error "touch $file4 failed"
10234
10235         local file4_pool=$($LFS getstripe -p $file4)
10236         [[ "$file4_pool" = "$pool" ]] ||
10237                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10238
10239         # new subdirectory under non-root directory should inherit
10240         # the default layout from its parent directory
10241         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10242                 error "set directory layout on $dir4 failed"
10243
10244         local dir5=$dir4/$tdir-5
10245         mkdir $dir5 || error "mkdir $dir5 failed"
10246
10247         dir4_layout=$(get_layout_param $dir4)
10248         local dir5_layout=$(get_layout_param $dir5)
10249         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10250         {
10251                 echo "dir4_layout: '$dir4_layout'"
10252                 echo "dir5_layout: '$dir5_layout'"
10253                 error "$dir5 should inherit the default layout from $dir4"
10254         }
10255
10256         # though subdir under ROOT doesn't inherit default layout, but
10257         # its sub dir/file should be created with default layout.
10258         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10259         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10260                 skip "Need MDS version at least 2.12.59"
10261
10262         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10263         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10264         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10265
10266         if [ $default_lmv_hash == "none" ]; then
10267                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10268         else
10269                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10270                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10271         fi
10272
10273         $LFS setdirstripe -D -c 2 $MOUNT ||
10274                 error "setdirstripe -D -c 2 failed"
10275         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10276         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10277         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10278
10279         # $dir4 layout includes pool
10280         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10281         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10282                 error "pool lost on setstripe"
10283         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10284         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10285                 error "pool lost on compound layout setstripe"
10286 }
10287 run_test 65n "don't inherit default layout from root for new subdirectories"
10288
10289 test_65o() {
10290         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10291                 skip "need MDS version at least 2.14.57"
10292
10293         # set OST pool on root directory
10294         local pool=$TESTNAME
10295
10296         pool_add $pool || error "add $pool failed"
10297         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10298                 error "add targets to $pool failed"
10299
10300         local dir1=$MOUNT/$tdir
10301
10302         mkdir $dir1 || error "mkdir $dir1 failed"
10303
10304         # set a new striping pattern on root directory
10305         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10306
10307         $LFS setstripe -p $pool $dir1 ||
10308                 error "set directory layout on $dir1 failed"
10309
10310         # $dir1 layout includes pool
10311         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10312         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10313                 error "pool lost on setstripe"
10314         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10315         $LFS getstripe $dir1
10316         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10317                 error "pool lost on compound layout setstripe"
10318
10319         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10320                 error "setdirstripe failed on sub-dir with inherited pool"
10321         $LFS getstripe $dir1/dir2
10322         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10323                 error "pool lost on compound layout setdirstripe"
10324
10325         $LFS setstripe -E -1 -c 1 $dir1
10326         $LFS getstripe -d $dir1
10327         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10328                 error "pool lost on setstripe"
10329 }
10330 run_test 65o "pool inheritance for mdt component"
10331
10332 test_65p () { # LU-16152
10333         local src_dir=$DIR/$tdir/src_dir
10334         local dst_dir=$DIR/$tdir/dst_dir
10335         local yaml_file=$DIR/$tdir/layout.yaml
10336         local border
10337
10338         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10339                 skip "Need at least version 2.15.51"
10340
10341         test_mkdir -p $src_dir
10342         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10343                 error "failed to setstripe"
10344         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10345                 error "failed to getstripe"
10346
10347         test_mkdir -p $dst_dir
10348         $LFS setstripe --yaml $yaml_file $dst_dir ||
10349                 error "failed to setstripe with yaml file"
10350         border=$($LFS getstripe -d $dst_dir |
10351                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10352                 error "failed to getstripe"
10353
10354         # 2048M is 0x80000000, or 2147483648
10355         (( $border == 2147483648 )) ||
10356                 error "failed to handle huge number in yaml layout"
10357 }
10358 run_test 65p "setstripe with yaml file and huge number"
10359
10360 test_65p () { # LU-16194
10361         local src_dir=$DIR/$tdir/src_dir
10362
10363         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10364                 skip "Need at least version 2.15.51"
10365
10366         test_mkdir -p $src_dir
10367         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10368         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10369                 error "should fail if extent start/end >=8E"
10370
10371         # EOF should work as before
10372         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10373                 error "failed to setstripe normally"
10374 }
10375 run_test 65p "setstripe with >=8E offset should fail"
10376
10377 # bug 2543 - update blocks count on client
10378 test_66() {
10379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10380
10381         local COUNT=${COUNT:-8}
10382         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10383         sync; sync_all_data; sync; sync_all_data
10384         cancel_lru_locks osc
10385         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10386         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10387 }
10388 run_test 66 "update inode blocks count on client ==============="
10389
10390 meminfo() {
10391         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10392 }
10393
10394 swap_used() {
10395         swapon -s | awk '($1 == "'$1'") { print $4 }'
10396 }
10397
10398 # bug5265, obdfilter oa2dentry return -ENOENT
10399 # #define OBD_FAIL_SRV_ENOENT 0x217
10400 test_69() {
10401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10402         remote_ost_nodsh && skip "remote OST with nodsh"
10403
10404         f="$DIR/$tfile"
10405         $LFS setstripe -c 1 -i 0 $f
10406         stack_trap "rm -f $f ${f}.2"
10407
10408         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10409
10410         do_facet ost1 lctl set_param fail_loc=0x217
10411         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10412         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10413
10414         do_facet ost1 lctl set_param fail_loc=0
10415         $DIRECTIO write $f 0 2 || error "write error"
10416
10417         cancel_lru_locks osc
10418         $DIRECTIO read $f 0 1 || error "read error"
10419
10420         do_facet ost1 lctl set_param fail_loc=0x217
10421         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10422
10423         do_facet ost1 lctl set_param fail_loc=0
10424 }
10425 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10426
10427 test_71() {
10428         test_mkdir $DIR/$tdir
10429         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10430         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10431 }
10432 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10433
10434 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10436         [ "$RUNAS_ID" = "$UID" ] &&
10437                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10438         # Check that testing environment is properly set up. Skip if not
10439         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10440                 skip_env "User $RUNAS_ID does not exist - skipping"
10441
10442         touch $DIR/$tfile
10443         chmod 777 $DIR/$tfile
10444         chmod ug+s $DIR/$tfile
10445         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10446                 error "$RUNAS dd $DIR/$tfile failed"
10447         # See if we are still setuid/sgid
10448         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10449                 error "S/gid is not dropped on write"
10450         # Now test that MDS is updated too
10451         cancel_lru_locks mdc
10452         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10453                 error "S/gid is not dropped on MDS"
10454         rm -f $DIR/$tfile
10455 }
10456 run_test 72a "Test that remove suid works properly (bug5695) ===="
10457
10458 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10459         local perm
10460
10461         [ "$RUNAS_ID" = "$UID" ] &&
10462                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10463         [ "$RUNAS_ID" -eq 0 ] &&
10464                 skip_env "RUNAS_ID = 0 -- skipping"
10465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10466         # Check that testing environment is properly set up. Skip if not
10467         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10468                 skip_env "User $RUNAS_ID does not exist - skipping"
10469
10470         touch $DIR/${tfile}-f{g,u}
10471         test_mkdir $DIR/${tfile}-dg
10472         test_mkdir $DIR/${tfile}-du
10473         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10474         chmod g+s $DIR/${tfile}-{f,d}g
10475         chmod u+s $DIR/${tfile}-{f,d}u
10476         for perm in 777 2777 4777; do
10477                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10478                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10479                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10480                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10481         done
10482         true
10483 }
10484 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10485
10486 # bug 3462 - multiple simultaneous MDC requests
10487 test_73() {
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489
10490         test_mkdir $DIR/d73-1
10491         test_mkdir $DIR/d73-2
10492         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10493         pid1=$!
10494
10495         lctl set_param fail_loc=0x80000129
10496         $MULTIOP $DIR/d73-1/f73-2 Oc &
10497         sleep 1
10498         lctl set_param fail_loc=0
10499
10500         $MULTIOP $DIR/d73-2/f73-3 Oc &
10501         pid3=$!
10502
10503         kill -USR1 $pid1
10504         wait $pid1 || return 1
10505
10506         sleep 25
10507
10508         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10509         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10510         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10511
10512         rm -rf $DIR/d73-*
10513 }
10514 run_test 73 "multiple MDC requests (should not deadlock)"
10515
10516 test_74a() { # bug 6149, 6184
10517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10518
10519         touch $DIR/f74a
10520         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10521         #
10522         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10523         # will spin in a tight reconnection loop
10524         $LCTL set_param fail_loc=0x8000030e
10525         # get any lock that won't be difficult - lookup works.
10526         ls $DIR/f74a
10527         $LCTL set_param fail_loc=0
10528         rm -f $DIR/f74a
10529         true
10530 }
10531 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10532
10533 test_74b() { # bug 13310
10534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10535
10536         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10537         #
10538         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10539         # will spin in a tight reconnection loop
10540         $LCTL set_param fail_loc=0x8000030e
10541         # get a "difficult" lock
10542         touch $DIR/f74b
10543         $LCTL set_param fail_loc=0
10544         rm -f $DIR/f74b
10545         true
10546 }
10547 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10548
10549 test_74c() {
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551
10552         #define OBD_FAIL_LDLM_NEW_LOCK
10553         $LCTL set_param fail_loc=0x319
10554         touch $DIR/$tfile && error "touch successful"
10555         $LCTL set_param fail_loc=0
10556         true
10557 }
10558 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10559
10560 slab_lic=/sys/kernel/slab/lustre_inode_cache
10561 num_objects() {
10562         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10563         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10564                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10565 }
10566
10567 test_76a() { # Now for b=20433, added originally in b=1443
10568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10569
10570         cancel_lru_locks osc
10571         # there may be some slab objects cached per core
10572         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10573         local before=$(num_objects)
10574         local count=$((512 * cpus))
10575         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10576         local margin=$((count / 10))
10577         if [[ -f $slab_lic/aliases ]]; then
10578                 local aliases=$(cat $slab_lic/aliases)
10579                 (( aliases > 0 )) && margin=$((margin * aliases))
10580         fi
10581
10582         echo "before slab objects: $before"
10583         for i in $(seq $count); do
10584                 touch $DIR/$tfile
10585                 rm -f $DIR/$tfile
10586         done
10587         cancel_lru_locks osc
10588         local after=$(num_objects)
10589         echo "created: $count, after slab objects: $after"
10590         # shared slab counts are not very accurate, allow significant margin
10591         # the main goal is that the cache growth is not permanently > $count
10592         while (( after > before + margin )); do
10593                 sleep 1
10594                 after=$(num_objects)
10595                 wait=$((wait + 1))
10596                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10597                 if (( wait > 60 )); then
10598                         error "inode slab grew from $before+$margin to $after"
10599                 fi
10600         done
10601 }
10602 run_test 76a "confirm clients recycle inodes properly ===="
10603
10604 test_76b() {
10605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10606         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10607
10608         local count=512
10609         local before=$(num_objects)
10610
10611         for i in $(seq $count); do
10612                 mkdir $DIR/$tdir
10613                 rmdir $DIR/$tdir
10614         done
10615
10616         local after=$(num_objects)
10617         local wait=0
10618
10619         while (( after > before )); do
10620                 sleep 1
10621                 after=$(num_objects)
10622                 wait=$((wait + 1))
10623                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10624                 if (( wait > 60 )); then
10625                         error "inode slab grew from $before to $after"
10626                 fi
10627         done
10628
10629         echo "slab objects before: $before, after: $after"
10630 }
10631 run_test 76b "confirm clients recycle directory inodes properly ===="
10632
10633 export ORIG_CSUM=""
10634 set_checksums()
10635 {
10636         # Note: in sptlrpc modes which enable its own bulk checksum, the
10637         # original crc32_le bulk checksum will be automatically disabled,
10638         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10639         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10640         # In this case set_checksums() will not be no-op, because sptlrpc
10641         # bulk checksum will be enabled all through the test.
10642
10643         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10644         lctl set_param -n osc.*.checksums $1
10645         return 0
10646 }
10647
10648 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10649                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10650 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10651                              tr -d [] | head -n1)}
10652 set_checksum_type()
10653 {
10654         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10655         rc=$?
10656         log "set checksum type to $1, rc = $rc"
10657         return $rc
10658 }
10659
10660 get_osc_checksum_type()
10661 {
10662         # arugment 1: OST name, like OST0000
10663         ost=$1
10664         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10665                         sed 's/.*\[\(.*\)\].*/\1/g')
10666         rc=$?
10667         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10668         echo $checksum_type
10669 }
10670
10671 F77_TMP=$TMP/f77-temp
10672 F77SZ=8
10673 setup_f77() {
10674         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10675                 error "error writing to $F77_TMP"
10676 }
10677
10678 test_77a() { # bug 10889
10679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10680         $GSS && skip_env "could not run with gss"
10681
10682         [ ! -f $F77_TMP ] && setup_f77
10683         set_checksums 1
10684         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10685         set_checksums 0
10686         rm -f $DIR/$tfile
10687 }
10688 run_test 77a "normal checksum read/write operation"
10689
10690 test_77b() { # bug 10889
10691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10692         $GSS && skip_env "could not run with gss"
10693
10694         [ ! -f $F77_TMP ] && setup_f77
10695         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10696         $LCTL set_param fail_loc=0x80000409
10697         set_checksums 1
10698
10699         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10700                 error "dd error: $?"
10701         $LCTL set_param fail_loc=0
10702
10703         for algo in $CKSUM_TYPES; do
10704                 cancel_lru_locks osc
10705                 set_checksum_type $algo
10706                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10707                 $LCTL set_param fail_loc=0x80000408
10708                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10709                 $LCTL set_param fail_loc=0
10710         done
10711         set_checksums 0
10712         set_checksum_type $ORIG_CSUM_TYPE
10713         rm -f $DIR/$tfile
10714 }
10715 run_test 77b "checksum error on client write, read"
10716
10717 cleanup_77c() {
10718         trap 0
10719         set_checksums 0
10720         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10721         $check_ost &&
10722                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10723         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10724         $check_ost && [ -n "$ost_file_prefix" ] &&
10725                 do_facet ost1 rm -f ${ost_file_prefix}\*
10726 }
10727
10728 test_77c() {
10729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10730         $GSS && skip_env "could not run with gss"
10731         remote_ost_nodsh && skip "remote OST with nodsh"
10732
10733         local bad1
10734         local osc_file_prefix
10735         local osc_file
10736         local check_ost=false
10737         local ost_file_prefix
10738         local ost_file
10739         local orig_cksum
10740         local dump_cksum
10741         local fid
10742
10743         # ensure corruption will occur on first OSS/OST
10744         $LFS setstripe -i 0 $DIR/$tfile
10745
10746         [ ! -f $F77_TMP ] && setup_f77
10747         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10748                 error "dd write error: $?"
10749         fid=$($LFS path2fid $DIR/$tfile)
10750
10751         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10752         then
10753                 check_ost=true
10754                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10755                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10756         else
10757                 echo "OSS do not support bulk pages dump upon error"
10758         fi
10759
10760         osc_file_prefix=$($LCTL get_param -n debug_path)
10761         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10762
10763         trap cleanup_77c EXIT
10764
10765         set_checksums 1
10766         # enable bulk pages dump upon error on Client
10767         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10768         # enable bulk pages dump upon error on OSS
10769         $check_ost &&
10770                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10771
10772         # flush Client cache to allow next read to reach OSS
10773         cancel_lru_locks osc
10774
10775         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10776         $LCTL set_param fail_loc=0x80000408
10777         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10778         $LCTL set_param fail_loc=0
10779
10780         rm -f $DIR/$tfile
10781
10782         # check cksum dump on Client
10783         osc_file=$(ls ${osc_file_prefix}*)
10784         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10785         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10786         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10787         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10788         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10789                      cksum)
10790         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10791         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10792                 error "dump content does not match on Client"
10793
10794         $check_ost || skip "No need to check cksum dump on OSS"
10795
10796         # check cksum dump on OSS
10797         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10798         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10799         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10800         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10801         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10802                 error "dump content does not match on OSS"
10803
10804         cleanup_77c
10805 }
10806 run_test 77c "checksum error on client read with debug"
10807
10808 test_77d() { # bug 10889
10809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10810         $GSS && skip_env "could not run with gss"
10811
10812         stack_trap "rm -f $DIR/$tfile"
10813         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10814         $LCTL set_param fail_loc=0x80000409
10815         set_checksums 1
10816         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10817                 error "direct write: rc=$?"
10818         $LCTL set_param fail_loc=0
10819         set_checksums 0
10820
10821         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10822         $LCTL set_param fail_loc=0x80000408
10823         set_checksums 1
10824         cancel_lru_locks osc
10825         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10826                 error "direct read: rc=$?"
10827         $LCTL set_param fail_loc=0
10828         set_checksums 0
10829 }
10830 run_test 77d "checksum error on OST direct write, read"
10831
10832 test_77f() { # bug 10889
10833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10834         $GSS && skip_env "could not run with gss"
10835
10836         set_checksums 1
10837         stack_trap "rm -f $DIR/$tfile"
10838         for algo in $CKSUM_TYPES; do
10839                 cancel_lru_locks osc
10840                 set_checksum_type $algo
10841                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10842                 $LCTL set_param fail_loc=0x409
10843                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10844                         error "direct write succeeded"
10845                 $LCTL set_param fail_loc=0
10846         done
10847         set_checksum_type $ORIG_CSUM_TYPE
10848         set_checksums 0
10849 }
10850 run_test 77f "repeat checksum error on write (expect error)"
10851
10852 test_77g() { # bug 10889
10853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10854         $GSS && skip_env "could not run with gss"
10855         remote_ost_nodsh && skip "remote OST with nodsh"
10856
10857         [ ! -f $F77_TMP ] && setup_f77
10858
10859         local file=$DIR/$tfile
10860         stack_trap "rm -f $file" EXIT
10861
10862         $LFS setstripe -c 1 -i 0 $file
10863         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10864         do_facet ost1 lctl set_param fail_loc=0x8000021a
10865         set_checksums 1
10866         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10867                 error "write error: rc=$?"
10868         do_facet ost1 lctl set_param fail_loc=0
10869         set_checksums 0
10870
10871         cancel_lru_locks osc
10872         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10873         do_facet ost1 lctl set_param fail_loc=0x8000021b
10874         set_checksums 1
10875         cmp $F77_TMP $file || error "file compare failed"
10876         do_facet ost1 lctl set_param fail_loc=0
10877         set_checksums 0
10878 }
10879 run_test 77g "checksum error on OST write, read"
10880
10881 test_77k() { # LU-10906
10882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10883         $GSS && skip_env "could not run with gss"
10884
10885         local cksum_param="osc.$FSNAME*.checksums"
10886         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10887         local checksum
10888         local i
10889
10890         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10891         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10892         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10893
10894         for i in 0 1; do
10895                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10896                         error "failed to set checksum=$i on MGS"
10897                 wait_update $HOSTNAME "$get_checksum" $i
10898                 #remount
10899                 echo "remount client, checksum should be $i"
10900                 remount_client $MOUNT || error "failed to remount client"
10901                 checksum=$(eval $get_checksum)
10902                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10903         done
10904         # remove persistent param to avoid races with checksum mountopt below
10905         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10906                 error "failed to delete checksum on MGS"
10907
10908         for opt in "checksum" "nochecksum"; do
10909                 #remount with mount option
10910                 echo "remount client with option $opt, checksum should be $i"
10911                 umount_client $MOUNT || error "failed to umount client"
10912                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10913                         error "failed to mount client with option '$opt'"
10914                 checksum=$(eval $get_checksum)
10915                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10916                 i=$((i - 1))
10917         done
10918
10919         remount_client $MOUNT || error "failed to remount client"
10920 }
10921 run_test 77k "enable/disable checksum correctly"
10922
10923 test_77l() {
10924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10925         $GSS && skip_env "could not run with gss"
10926
10927         set_checksums 1
10928         stack_trap "set_checksums $ORIG_CSUM" EXIT
10929         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10930
10931         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10932
10933         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10934         for algo in $CKSUM_TYPES; do
10935                 set_checksum_type $algo || error "fail to set checksum type $algo"
10936                 osc_algo=$(get_osc_checksum_type OST0000)
10937                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10938
10939                 # no locks, no reqs to let the connection idle
10940                 cancel_lru_locks osc
10941                 lru_resize_disable osc
10942                 wait_osc_import_state client ost1 IDLE
10943
10944                 # ensure ost1 is connected
10945                 stat $DIR/$tfile >/dev/null || error "can't stat"
10946                 wait_osc_import_state client ost1 FULL
10947
10948                 osc_algo=$(get_osc_checksum_type OST0000)
10949                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10950         done
10951         return 0
10952 }
10953 run_test 77l "preferred checksum type is remembered after reconnected"
10954
10955 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10956 rm -f $F77_TMP
10957 unset F77_TMP
10958
10959 test_77m() {
10960         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10961                 skip "Need at least version 2.14.52"
10962         local param=checksum_speed
10963
10964         $LCTL get_param $param || error "reading $param failed"
10965
10966         csum_speeds=$($LCTL get_param -n $param)
10967
10968         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10969                 error "known checksum types are missing"
10970 }
10971 run_test 77m "Verify checksum_speed is correctly read"
10972
10973 check_filefrag_77n() {
10974         local nr_ext=0
10975         local starts=()
10976         local ends=()
10977
10978         while read extidx a b start end rest; do
10979                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10980                         nr_ext=$(( $nr_ext + 1 ))
10981                         starts+=( ${start%..} )
10982                         ends+=( ${end%:} )
10983                 fi
10984         done < <( filefrag -sv $1 )
10985
10986         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10987         return 1
10988 }
10989
10990 test_77n() {
10991         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10992
10993         touch $DIR/$tfile
10994         $TRUNCATE $DIR/$tfile 0
10995         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10996         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10997         check_filefrag_77n $DIR/$tfile ||
10998                 skip "$tfile blocks not contiguous around hole"
10999
11000         set_checksums 1
11001         stack_trap "set_checksums $ORIG_CSUM" EXIT
11002         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11003         stack_trap "rm -f $DIR/$tfile"
11004
11005         for algo in $CKSUM_TYPES; do
11006                 if [[ "$algo" =~ ^t10 ]]; then
11007                         set_checksum_type $algo ||
11008                                 error "fail to set checksum type $algo"
11009                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11010                                 error "fail to read $tfile with $algo"
11011                 fi
11012         done
11013         rm -f $DIR/$tfile
11014         return 0
11015 }
11016 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11017
11018 test_77o() {
11019         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11020                 skip "Need MDS version at least 2.14.55"
11021         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11022                 skip "Need OST version at least 2.14.55"
11023         local ofd=obdfilter
11024         local mdt=mdt
11025
11026         # print OST checksum_type
11027         echo "$ofd.$FSNAME-*.checksum_type:"
11028         do_nodes $(comma_list $(osts_nodes)) \
11029                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11030
11031         # print MDT checksum_type
11032         echo "$mdt.$FSNAME-*.checksum_type:"
11033         do_nodes $(comma_list $(mdts_nodes)) \
11034                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11035
11036         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11037                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11038
11039         (( $o_count == $OSTCOUNT )) ||
11040                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11041
11042         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11043                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11044
11045         (( $m_count == $MDSCOUNT )) ||
11046                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11047 }
11048 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11049
11050 cleanup_test_78() {
11051         trap 0
11052         rm -f $DIR/$tfile
11053 }
11054
11055 test_78() { # bug 10901
11056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11057         remote_ost || skip_env "local OST"
11058
11059         NSEQ=5
11060         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11061         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11062         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11063         echo "MemTotal: $MEMTOTAL"
11064
11065         # reserve 256MB of memory for the kernel and other running processes,
11066         # and then take 1/2 of the remaining memory for the read/write buffers.
11067         if [ $MEMTOTAL -gt 512 ] ;then
11068                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11069         else
11070                 # for those poor memory-starved high-end clusters...
11071                 MEMTOTAL=$((MEMTOTAL / 2))
11072         fi
11073         echo "Mem to use for directio: $MEMTOTAL"
11074
11075         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11076         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11077         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11078         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11079                 head -n1)
11080         echo "Smallest OST: $SMALLESTOST"
11081         [[ $SMALLESTOST -lt 10240 ]] &&
11082                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11083
11084         trap cleanup_test_78 EXIT
11085
11086         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11087                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11088
11089         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11090         echo "File size: $F78SIZE"
11091         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11092         for i in $(seq 1 $NSEQ); do
11093                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11094                 echo directIO rdwr round $i of $NSEQ
11095                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11096         done
11097
11098         cleanup_test_78
11099 }
11100 run_test 78 "handle large O_DIRECT writes correctly ============"
11101
11102 test_79() { # bug 12743
11103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11104
11105         wait_delete_completed
11106
11107         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11108         BKFREE=$(calc_osc_kbytes kbytesfree)
11109         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11110
11111         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11112         DFTOTAL=`echo $STRING | cut -d, -f1`
11113         DFUSED=`echo $STRING  | cut -d, -f2`
11114         DFAVAIL=`echo $STRING | cut -d, -f3`
11115         DFFREE=$(($DFTOTAL - $DFUSED))
11116
11117         ALLOWANCE=$((64 * $OSTCOUNT))
11118
11119         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11120            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11121                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11122         fi
11123         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11124            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11125                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11126         fi
11127         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11128            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11129                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11130         fi
11131 }
11132 run_test 79 "df report consistency check ======================="
11133
11134 test_80() { # bug 10718
11135         remote_ost_nodsh && skip "remote OST with nodsh"
11136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11137
11138         # relax strong synchronous semantics for slow backends like ZFS
11139         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11140                 local soc="obdfilter.*.sync_lock_cancel"
11141                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11142
11143                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11144                 if [ -z "$save" ]; then
11145                         soc="obdfilter.*.sync_on_lock_cancel"
11146                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11147                 fi
11148
11149                 if [ "$save" != "never" ]; then
11150                         local hosts=$(comma_list $(osts_nodes))
11151
11152                         do_nodes $hosts $LCTL set_param $soc=never
11153                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11154                 fi
11155         fi
11156
11157         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11158         sync; sleep 1; sync
11159         local before=$(date +%s)
11160         cancel_lru_locks osc
11161         local after=$(date +%s)
11162         local diff=$((after - before))
11163         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11164
11165         rm -f $DIR/$tfile
11166 }
11167 run_test 80 "Page eviction is equally fast at high offsets too"
11168
11169 test_81a() { # LU-456
11170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11171         remote_ost_nodsh && skip "remote OST with nodsh"
11172
11173         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11174         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11175         do_facet ost1 lctl set_param fail_loc=0x80000228
11176
11177         # write should trigger a retry and success
11178         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11179         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11180         RC=$?
11181         if [ $RC -ne 0 ] ; then
11182                 error "write should success, but failed for $RC"
11183         fi
11184 }
11185 run_test 81a "OST should retry write when get -ENOSPC ==============="
11186
11187 test_81b() { # LU-456
11188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11189         remote_ost_nodsh && skip "remote OST with nodsh"
11190
11191         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11192         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11193         do_facet ost1 lctl set_param fail_loc=0x228
11194
11195         # write should retry several times and return -ENOSPC finally
11196         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11197         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11198         RC=$?
11199         ENOSPC=28
11200         if [ $RC -ne $ENOSPC ] ; then
11201                 error "dd should fail for -ENOSPC, but succeed."
11202         fi
11203 }
11204 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11205
11206 test_99() {
11207         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11208
11209         test_mkdir $DIR/$tdir.cvsroot
11210         chown $RUNAS_ID $DIR/$tdir.cvsroot
11211
11212         cd $TMP
11213         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11214
11215         cd /etc/init.d
11216         # some versions of cvs import exit(1) when asked to import links or
11217         # files they can't read.  ignore those files.
11218         local toignore=$(find . -type l -printf '-I %f\n' -o \
11219                          ! -perm /4 -printf '-I %f\n')
11220         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11221                 $tdir.reposname vtag rtag
11222
11223         cd $DIR
11224         test_mkdir $DIR/$tdir.reposname
11225         chown $RUNAS_ID $DIR/$tdir.reposname
11226         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11227
11228         cd $DIR/$tdir.reposname
11229         $RUNAS touch foo99
11230         $RUNAS cvs add -m 'addmsg' foo99
11231         $RUNAS cvs update
11232         $RUNAS cvs commit -m 'nomsg' foo99
11233         rm -fr $DIR/$tdir.cvsroot
11234 }
11235 run_test 99 "cvs strange file/directory operations"
11236
11237 test_100() {
11238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11239         [[ "$NETTYPE" =~ tcp ]] ||
11240                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11241         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11242         remote_ost_nodsh && skip "remote OST with nodsh"
11243         remote_mds_nodsh && skip "remote MDS with nodsh"
11244         remote_servers || skip "useless for local single node setup"
11245
11246         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11247                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11248
11249                 rc=0
11250                 if (( ${LOCAL/*:/} >= 1024 )); then
11251                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11252                         ss -tna
11253                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11254                 fi
11255         done
11256         (( $rc == 0 )) || error "privileged port not found" )
11257 }
11258 run_test 100 "check local port using privileged port"
11259
11260 function get_named_value()
11261 {
11262     local tag=$1
11263
11264     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11265 }
11266
11267 test_101a() {
11268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11269
11270         local s
11271         local discard
11272         local nreads=10000
11273         local cache_limit=32
11274
11275         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11276         $LCTL set_param -n llite.*.read_ahead_stats=0
11277         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11278                               awk '/^max_cached_mb/ { print $2 }')
11279         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11280         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11281
11282         #
11283         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11284         #
11285         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11286         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11287
11288         discard=0
11289         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11290                    get_named_value 'read.but.discarded'); do
11291                         discard=$(($discard + $s))
11292         done
11293
11294         $LCTL get_param osc.*-osc*.rpc_stats
11295         $LCTL get_param llite.*.read_ahead_stats
11296
11297         # Discard is generally zero, but sometimes a few random reads line up
11298         # and trigger larger readahead, which is wasted & leads to discards.
11299         if [[ $(($discard)) -gt $nreads ]]; then
11300                 error "too many ($discard) discarded pages"
11301         fi
11302         rm -f $DIR/$tfile || true
11303 }
11304 run_test 101a "check read-ahead for random reads"
11305
11306 setup_test101bc() {
11307         test_mkdir $DIR/$tdir
11308         local ssize=$1
11309         local FILE_LENGTH=$2
11310         STRIPE_OFFSET=0
11311
11312         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11313
11314         local list=$(comma_list $(osts_nodes))
11315         set_osd_param $list '' read_cache_enable 0
11316         set_osd_param $list '' writethrough_cache_enable 0
11317
11318         trap cleanup_test101bc EXIT
11319         # prepare the read-ahead file
11320         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11321
11322         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11323                                 count=$FILE_SIZE_MB 2> /dev/null
11324
11325 }
11326
11327 cleanup_test101bc() {
11328         trap 0
11329         rm -rf $DIR/$tdir
11330         rm -f $DIR/$tfile
11331
11332         local list=$(comma_list $(osts_nodes))
11333         set_osd_param $list '' read_cache_enable 1
11334         set_osd_param $list '' writethrough_cache_enable 1
11335 }
11336
11337 ra_check_101() {
11338         local read_size=$1
11339         local stripe_size=$2
11340         local stride_length=$((stripe_size / read_size))
11341         local stride_width=$((stride_length * OSTCOUNT))
11342         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11343                                 (stride_width - stride_length) ))
11344         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11345                   get_named_value 'read.but.discarded' | calc_sum)
11346
11347         if [[ $discard -gt $discard_limit ]]; then
11348                 $LCTL get_param llite.*.read_ahead_stats
11349                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11350         else
11351                 echo "Read-ahead success for size ${read_size}"
11352         fi
11353 }
11354
11355 test_101b() {
11356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11357         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11358
11359         local STRIPE_SIZE=1048576
11360         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11361
11362         if [ $SLOW == "yes" ]; then
11363                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11364         else
11365                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11366         fi
11367
11368         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11369
11370         # prepare the read-ahead file
11371         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11372         cancel_lru_locks osc
11373         for BIDX in 2 4 8 16 32 64 128 256
11374         do
11375                 local BSIZE=$((BIDX*4096))
11376                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11377                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11378                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11379                 $LCTL set_param -n llite.*.read_ahead_stats=0
11380                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11381                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11382                 cancel_lru_locks osc
11383                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11384         done
11385         cleanup_test101bc
11386         true
11387 }
11388 run_test 101b "check stride-io mode read-ahead ================="
11389
11390 test_101c() {
11391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11392
11393         local STRIPE_SIZE=1048576
11394         local FILE_LENGTH=$((STRIPE_SIZE*100))
11395         local nreads=10000
11396         local rsize=65536
11397         local osc_rpc_stats
11398
11399         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11400
11401         cancel_lru_locks osc
11402         $LCTL set_param osc.*.rpc_stats=0
11403         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11404         $LCTL get_param osc.*.rpc_stats
11405         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11406                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11407                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11408                 local size
11409
11410                 if [ $lines -le 20 ]; then
11411                         echo "continue debug"
11412                         continue
11413                 fi
11414                 for size in 1 2 4 8; do
11415                         local rpc=$(echo "$stats" |
11416                                     awk '($1 == "'$size':") {print $2; exit; }')
11417                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11418                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11419                 done
11420                 echo "$osc_rpc_stats check passed!"
11421         done
11422         cleanup_test101bc
11423         true
11424 }
11425 run_test 101c "check stripe_size aligned read-ahead"
11426
11427 test_101d() {
11428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11429
11430         local file=$DIR/$tfile
11431         local sz_MB=${FILESIZE_101d:-80}
11432         local ra_MB=${READAHEAD_MB:-40}
11433
11434         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11435         [ $free_MB -lt $sz_MB ] &&
11436                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11437
11438         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11439         $LFS setstripe -c -1 $file || error "setstripe failed"
11440
11441         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11442         echo Cancel LRU locks on lustre client to flush the client cache
11443         cancel_lru_locks osc
11444
11445         echo Disable read-ahead
11446         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11447         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11448         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11449         $LCTL get_param -n llite.*.max_read_ahead_mb
11450
11451         echo "Reading the test file $file with read-ahead disabled"
11452         local sz_KB=$((sz_MB * 1024 / 4))
11453         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11454         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11455         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11456                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11457
11458         echo "Cancel LRU locks on lustre client to flush the client cache"
11459         cancel_lru_locks osc
11460         echo Enable read-ahead with ${ra_MB}MB
11461         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11462
11463         echo "Reading the test file $file with read-ahead enabled"
11464         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11465                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11466
11467         echo "read-ahead disabled time read $raOFF"
11468         echo "read-ahead enabled time read $raON"
11469
11470         rm -f $file
11471         wait_delete_completed
11472
11473         # use awk for this check instead of bash because it handles decimals
11474         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11475                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11476 }
11477 run_test 101d "file read with and without read-ahead enabled"
11478
11479 test_101e() {
11480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11481
11482         local file=$DIR/$tfile
11483         local size_KB=500  #KB
11484         local count=100
11485         local bsize=1024
11486
11487         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11488         local need_KB=$((count * size_KB))
11489         [[ $free_KB -le $need_KB ]] &&
11490                 skip_env "Need free space $need_KB, have $free_KB"
11491
11492         echo "Creating $count ${size_KB}K test files"
11493         for ((i = 0; i < $count; i++)); do
11494                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11495         done
11496
11497         echo "Cancel LRU locks on lustre client to flush the client cache"
11498         cancel_lru_locks $OSC
11499
11500         echo "Reset readahead stats"
11501         $LCTL set_param -n llite.*.read_ahead_stats=0
11502
11503         for ((i = 0; i < $count; i++)); do
11504                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11505         done
11506
11507         $LCTL get_param llite.*.max_cached_mb
11508         $LCTL get_param llite.*.read_ahead_stats
11509         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11510                      get_named_value 'misses' | calc_sum)
11511
11512         for ((i = 0; i < $count; i++)); do
11513                 rm -rf $file.$i 2>/dev/null
11514         done
11515
11516         #10000 means 20% reads are missing in readahead
11517         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11518 }
11519 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11520
11521 test_101f() {
11522         which iozone || skip_env "no iozone installed"
11523
11524         local old_debug=$($LCTL get_param debug)
11525         old_debug=${old_debug#*=}
11526         $LCTL set_param debug="reada mmap"
11527
11528         # create a test file
11529         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11530
11531         echo Cancel LRU locks on lustre client to flush the client cache
11532         cancel_lru_locks osc
11533
11534         echo Reset readahead stats
11535         $LCTL set_param -n llite.*.read_ahead_stats=0
11536
11537         echo mmap read the file with small block size
11538         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11539                 > /dev/null 2>&1
11540
11541         echo checking missing pages
11542         $LCTL get_param llite.*.read_ahead_stats
11543         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11544                         get_named_value 'misses' | calc_sum)
11545
11546         $LCTL set_param debug="$old_debug"
11547         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11548         rm -f $DIR/$tfile
11549 }
11550 run_test 101f "check mmap read performance"
11551
11552 test_101g_brw_size_test() {
11553         local mb=$1
11554         local pages=$((mb * 1048576 / PAGE_SIZE))
11555         local file=$DIR/$tfile
11556
11557         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11558                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11559         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11560                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11561                         return 2
11562         done
11563
11564         stack_trap "rm -f $file" EXIT
11565         $LCTL set_param -n osc.*.rpc_stats=0
11566
11567         # 10 RPCs should be enough for the test
11568         local count=10
11569         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11570                 { error "dd write ${mb} MB blocks failed"; return 3; }
11571         cancel_lru_locks osc
11572         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11573                 { error "dd write ${mb} MB blocks failed"; return 4; }
11574
11575         # calculate number of full-sized read and write RPCs
11576         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11577                 sed -n '/pages per rpc/,/^$/p' |
11578                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11579                 END { print reads,writes }'))
11580         # allow one extra full-sized read RPC for async readahead
11581         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11582                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11583         [[ ${rpcs[1]} == $count ]] ||
11584                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11585 }
11586
11587 test_101g() {
11588         remote_ost_nodsh && skip "remote OST with nodsh"
11589
11590         local rpcs
11591         local osts=$(get_facets OST)
11592         local list=$(comma_list $(osts_nodes))
11593         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11594         local brw_size="obdfilter.*.brw_size"
11595
11596         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11597
11598         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11599
11600         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11601                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11602                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11603            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11604                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11605                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11606
11607                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11608                         suffix="M"
11609
11610                 if [[ $orig_mb -lt 16 ]]; then
11611                         save_lustre_params $osts "$brw_size" > $p
11612                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11613                                 error "set 16MB RPC size failed"
11614
11615                         echo "remount client to enable new RPC size"
11616                         remount_client $MOUNT || error "remount_client failed"
11617                 fi
11618
11619                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11620                 # should be able to set brw_size=12, but no rpc_stats for that
11621                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11622         fi
11623
11624         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11625
11626         if [[ $orig_mb -lt 16 ]]; then
11627                 restore_lustre_params < $p
11628                 remount_client $MOUNT || error "remount_client restore failed"
11629         fi
11630
11631         rm -f $p $DIR/$tfile
11632 }
11633 run_test 101g "Big bulk(4/16 MiB) readahead"
11634
11635 test_101h() {
11636         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11637
11638         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11639                 error "dd 70M file failed"
11640         echo Cancel LRU locks on lustre client to flush the client cache
11641         cancel_lru_locks osc
11642
11643         echo "Reset readahead stats"
11644         $LCTL set_param -n llite.*.read_ahead_stats 0
11645
11646         echo "Read 10M of data but cross 64M bundary"
11647         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11648         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11649                      get_named_value 'misses' | calc_sum)
11650         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11651         rm -f $p $DIR/$tfile
11652 }
11653 run_test 101h "Readahead should cover current read window"
11654
11655 test_101i() {
11656         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11657                 error "dd 10M file failed"
11658
11659         local max_per_file_mb=$($LCTL get_param -n \
11660                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11661         cancel_lru_locks osc
11662         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11663         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11664                 error "set max_read_ahead_per_file_mb to 1 failed"
11665
11666         echo "Reset readahead stats"
11667         $LCTL set_param llite.*.read_ahead_stats=0
11668
11669         dd if=$DIR/$tfile of=/dev/null bs=2M
11670
11671         $LCTL get_param llite.*.read_ahead_stats
11672         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11673                      awk '/misses/ { print $2 }')
11674         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11675         rm -f $DIR/$tfile
11676 }
11677 run_test 101i "allow current readahead to exceed reservation"
11678
11679 test_101j() {
11680         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11681                 error "setstripe $DIR/$tfile failed"
11682         local file_size=$((1048576 * 16))
11683         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11684         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11685
11686         echo Disable read-ahead
11687         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11688
11689         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11690         for blk in $PAGE_SIZE 1048576 $file_size; do
11691                 cancel_lru_locks osc
11692                 echo "Reset readahead stats"
11693                 $LCTL set_param -n llite.*.read_ahead_stats=0
11694                 local count=$(($file_size / $blk))
11695                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11696                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11697                              get_named_value 'failed.to.fast.read' | calc_sum)
11698                 $LCTL get_param -n llite.*.read_ahead_stats
11699                 [ $miss -eq $count ] || error "expected $count got $miss"
11700         done
11701
11702         rm -f $p $DIR/$tfile
11703 }
11704 run_test 101j "A complete read block should be submitted when no RA"
11705
11706 test_readahead_base() {
11707         local file=$DIR/$tfile
11708         local size=$1
11709         local iosz
11710         local ramax
11711         local ranum
11712
11713         $LCTL set_param -n llite.*.read_ahead_stats=0
11714         # The first page is not accounted into readahead
11715         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11716         iosz=$(((size + 1048575) / 1048576 * 1048576))
11717         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11718
11719         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11720         fallocate -l $size $file || error "failed to fallocate $file"
11721         cancel_lru_locks osc
11722         $MULTIOP $file or${iosz}c || error "failed to read $file"
11723         $LCTL get_param -n llite.*.read_ahead_stats
11724         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11725                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11726         (( $ranum <= $ramax )) ||
11727                 error "read-ahead pages is $ranum more than $ramax"
11728         rm -rf $file || error "failed to remove $file"
11729 }
11730
11731 test_101m()
11732 {
11733         local file=$DIR/$tfile
11734         local ramax
11735         local ranum
11736         local size
11737         local iosz
11738
11739         check_set_fallocate_or_skip
11740         stack_trap "rm -f $file" EXIT
11741
11742         test_readahead_base 4096
11743
11744         # file size: 16K = 16384
11745         test_readahead_base 16384
11746         test_readahead_base 16385
11747         test_readahead_base 16383
11748
11749         # file size: 1M + 1 = 1048576 + 1
11750         test_readahead_base 1048577
11751         # file size: 1M + 16K
11752         test_readahead_base $((1048576 + 16384))
11753
11754         # file size: stripe_size * (stripe_count - 1) + 16K
11755         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11756         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11757         # file size: stripe_size * stripe_count + 16K
11758         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11759         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11760         # file size: 2 * stripe_size * stripe_count + 16K
11761         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11762         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11763 }
11764 run_test 101m "read ahead for small file and last stripe of the file"
11765
11766 setup_test102() {
11767         test_mkdir $DIR/$tdir
11768         chown $RUNAS_ID $DIR/$tdir
11769         STRIPE_SIZE=65536
11770         STRIPE_OFFSET=1
11771         STRIPE_COUNT=$OSTCOUNT
11772         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11773
11774         trap cleanup_test102 EXIT
11775         cd $DIR
11776         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11777         cd $DIR/$tdir
11778         for num in 1 2 3 4; do
11779                 for count in $(seq 1 $STRIPE_COUNT); do
11780                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11781                                 local size=`expr $STRIPE_SIZE \* $num`
11782                                 local file=file"$num-$idx-$count"
11783                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11784                         done
11785                 done
11786         done
11787
11788         cd $DIR
11789         $1 tar cf $TMP/f102.tar $tdir --xattrs
11790 }
11791
11792 cleanup_test102() {
11793         trap 0
11794         rm -f $TMP/f102.tar
11795         rm -rf $DIR/d0.sanity/d102
11796 }
11797
11798 test_102a() {
11799         [ "$UID" != 0 ] && skip "must run as root"
11800         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11801                 skip_env "must have user_xattr"
11802
11803         [ -z "$(which setfattr 2>/dev/null)" ] &&
11804                 skip_env "could not find setfattr"
11805
11806         local testfile=$DIR/$tfile
11807
11808         touch $testfile
11809         echo "set/get xattr..."
11810         setfattr -n trusted.name1 -v value1 $testfile ||
11811                 error "setfattr -n trusted.name1=value1 $testfile failed"
11812         getfattr -n trusted.name1 $testfile 2> /dev/null |
11813           grep "trusted.name1=.value1" ||
11814                 error "$testfile missing trusted.name1=value1"
11815
11816         setfattr -n user.author1 -v author1 $testfile ||
11817                 error "setfattr -n user.author1=author1 $testfile failed"
11818         getfattr -n user.author1 $testfile 2> /dev/null |
11819           grep "user.author1=.author1" ||
11820                 error "$testfile missing trusted.author1=author1"
11821
11822         echo "listxattr..."
11823         setfattr -n trusted.name2 -v value2 $testfile ||
11824                 error "$testfile unable to set trusted.name2"
11825         setfattr -n trusted.name3 -v value3 $testfile ||
11826                 error "$testfile unable to set trusted.name3"
11827         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11828             grep "trusted.name" | wc -l) -eq 3 ] ||
11829                 error "$testfile missing 3 trusted.name xattrs"
11830
11831         setfattr -n user.author2 -v author2 $testfile ||
11832                 error "$testfile unable to set user.author2"
11833         setfattr -n user.author3 -v author3 $testfile ||
11834                 error "$testfile unable to set user.author3"
11835         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11836             grep "user.author" | wc -l) -eq 3 ] ||
11837                 error "$testfile missing 3 user.author xattrs"
11838
11839         echo "remove xattr..."
11840         setfattr -x trusted.name1 $testfile ||
11841                 error "$testfile error deleting trusted.name1"
11842         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11843                 error "$testfile did not delete trusted.name1 xattr"
11844
11845         setfattr -x user.author1 $testfile ||
11846                 error "$testfile error deleting user.author1"
11847         echo "set lustre special xattr ..."
11848         $LFS setstripe -c1 $testfile
11849         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11850                 awk -F "=" '/trusted.lov/ { print $2 }' )
11851         setfattr -n "trusted.lov" -v $lovea $testfile ||
11852                 error "$testfile doesn't ignore setting trusted.lov again"
11853         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11854                 error "$testfile allow setting invalid trusted.lov"
11855         rm -f $testfile
11856 }
11857 run_test 102a "user xattr test =================================="
11858
11859 check_102b_layout() {
11860         local layout="$*"
11861         local testfile=$DIR/$tfile
11862
11863         echo "test layout '$layout'"
11864         $LFS setstripe $layout $testfile || error "setstripe failed"
11865         $LFS getstripe -y $testfile
11866
11867         echo "get/set/list trusted.lov xattr ..." # b=10930
11868         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11869         [[ "$value" =~ "trusted.lov" ]] ||
11870                 error "can't get trusted.lov from $testfile"
11871         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11872                 error "getstripe failed"
11873
11874         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11875
11876         value=$(cut -d= -f2 <<<$value)
11877         # LU-13168: truncated xattr should fail if short lov_user_md header
11878         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11879                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11880         for len in $lens; do
11881                 echo "setfattr $len $testfile.2"
11882                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11883                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11884         done
11885         local stripe_size=$($LFS getstripe -S $testfile.2)
11886         local stripe_count=$($LFS getstripe -c $testfile.2)
11887         [[ $stripe_size -eq 65536 ]] ||
11888                 error "stripe size $stripe_size != 65536"
11889         [[ $stripe_count -eq $stripe_count_orig ]] ||
11890                 error "stripe count $stripe_count != $stripe_count_orig"
11891         rm $testfile $testfile.2
11892 }
11893
11894 test_102b() {
11895         [ -z "$(which setfattr 2>/dev/null)" ] &&
11896                 skip_env "could not find setfattr"
11897         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11898
11899         # check plain layout
11900         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11901
11902         # and also check composite layout
11903         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11904
11905 }
11906 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11907
11908 test_102c() {
11909         [ -z "$(which setfattr 2>/dev/null)" ] &&
11910                 skip_env "could not find setfattr"
11911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11912
11913         # b10930: get/set/list lustre.lov xattr
11914         echo "get/set/list lustre.lov xattr ..."
11915         test_mkdir $DIR/$tdir
11916         chown $RUNAS_ID $DIR/$tdir
11917         local testfile=$DIR/$tdir/$tfile
11918         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11919                 error "setstripe failed"
11920         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11921                 error "getstripe failed"
11922         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11923         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11924
11925         local testfile2=${testfile}2
11926         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11927                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11928
11929         $RUNAS $MCREATE $testfile2
11930         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11931         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11932         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11933         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11934         [ $stripe_count -eq $STRIPECOUNT ] ||
11935                 error "stripe count $stripe_count != $STRIPECOUNT"
11936 }
11937 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11938
11939 compare_stripe_info1() {
11940         local stripe_index_all_zero=true
11941
11942         for num in 1 2 3 4; do
11943                 for count in $(seq 1 $STRIPE_COUNT); do
11944                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11945                                 local size=$((STRIPE_SIZE * num))
11946                                 local file=file"$num-$offset-$count"
11947                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11948                                 [[ $stripe_size -ne $size ]] &&
11949                                     error "$file: size $stripe_size != $size"
11950                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11951                                 # allow fewer stripes to be created, ORI-601
11952                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11953                                     error "$file: count $stripe_count != $count"
11954                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11955                                 [[ $stripe_index -ne 0 ]] &&
11956                                         stripe_index_all_zero=false
11957                         done
11958                 done
11959         done
11960         $stripe_index_all_zero &&
11961                 error "all files are being extracted starting from OST index 0"
11962         return 0
11963 }
11964
11965 have_xattrs_include() {
11966         tar --help | grep -q xattrs-include &&
11967                 echo --xattrs-include="lustre.*"
11968 }
11969
11970 test_102d() {
11971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11972         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11973
11974         XINC=$(have_xattrs_include)
11975         setup_test102
11976         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11977         cd $DIR/$tdir/$tdir
11978         compare_stripe_info1
11979 }
11980 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11981
11982 test_102f() {
11983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11985
11986         XINC=$(have_xattrs_include)
11987         setup_test102
11988         test_mkdir $DIR/$tdir.restore
11989         cd $DIR
11990         tar cf - --xattrs $tdir | tar xf - \
11991                 -C $DIR/$tdir.restore --xattrs $XINC
11992         cd $DIR/$tdir.restore/$tdir
11993         compare_stripe_info1
11994 }
11995 run_test 102f "tar copy files, not keep osts"
11996
11997 grow_xattr() {
11998         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11999                 skip "must have user_xattr"
12000         [ -z "$(which setfattr 2>/dev/null)" ] &&
12001                 skip_env "could not find setfattr"
12002         [ -z "$(which getfattr 2>/dev/null)" ] &&
12003                 skip_env "could not find getfattr"
12004
12005         local xsize=${1:-1024}  # in bytes
12006         local file=$DIR/$tfile
12007         local value="$(generate_string $xsize)"
12008         local xbig=trusted.big
12009         local toobig=$2
12010
12011         touch $file
12012         log "save $xbig on $file"
12013         if [ -z "$toobig" ]
12014         then
12015                 setfattr -n $xbig -v $value $file ||
12016                         error "saving $xbig on $file failed"
12017         else
12018                 setfattr -n $xbig -v $value $file &&
12019                         error "saving $xbig on $file succeeded"
12020                 return 0
12021         fi
12022
12023         local orig=$(get_xattr_value $xbig $file)
12024         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12025
12026         local xsml=trusted.sml
12027         log "save $xsml on $file"
12028         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12029
12030         local new=$(get_xattr_value $xbig $file)
12031         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12032
12033         log "grow $xsml on $file"
12034         setfattr -n $xsml -v "$value" $file ||
12035                 error "growing $xsml on $file failed"
12036
12037         new=$(get_xattr_value $xbig $file)
12038         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12039         log "$xbig still valid after growing $xsml"
12040
12041         rm -f $file
12042 }
12043
12044 test_102h() { # bug 15777
12045         grow_xattr 1024
12046 }
12047 run_test 102h "grow xattr from inside inode to external block"
12048
12049 test_102ha() {
12050         large_xattr_enabled || skip_env "ea_inode feature disabled"
12051
12052         echo "setting xattr of max xattr size: $(max_xattr_size)"
12053         grow_xattr $(max_xattr_size)
12054
12055         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12056         echo "This should fail:"
12057         grow_xattr $(($(max_xattr_size) + 10)) 1
12058 }
12059 run_test 102ha "grow xattr from inside inode to external inode"
12060
12061 test_102i() { # bug 17038
12062         [ -z "$(which getfattr 2>/dev/null)" ] &&
12063                 skip "could not find getfattr"
12064
12065         touch $DIR/$tfile
12066         ln -s $DIR/$tfile $DIR/${tfile}link
12067         getfattr -n trusted.lov $DIR/$tfile ||
12068                 error "lgetxattr on $DIR/$tfile failed"
12069         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12070                 grep -i "no such attr" ||
12071                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12072         rm -f $DIR/$tfile $DIR/${tfile}link
12073 }
12074 run_test 102i "lgetxattr test on symbolic link ============"
12075
12076 test_102j() {
12077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12079
12080         XINC=$(have_xattrs_include)
12081         setup_test102 "$RUNAS"
12082         chown $RUNAS_ID $DIR/$tdir
12083         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12084         cd $DIR/$tdir/$tdir
12085         compare_stripe_info1 "$RUNAS"
12086 }
12087 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12088
12089 test_102k() {
12090         [ -z "$(which setfattr 2>/dev/null)" ] &&
12091                 skip "could not find setfattr"
12092
12093         touch $DIR/$tfile
12094         # b22187 just check that does not crash for regular file.
12095         setfattr -n trusted.lov $DIR/$tfile
12096         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12097         local test_kdir=$DIR/$tdir
12098         test_mkdir $test_kdir
12099         local default_size=$($LFS getstripe -S $test_kdir)
12100         local default_count=$($LFS getstripe -c $test_kdir)
12101         local default_offset=$($LFS getstripe -i $test_kdir)
12102         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12103                 error 'dir setstripe failed'
12104         setfattr -n trusted.lov $test_kdir
12105         local stripe_size=$($LFS getstripe -S $test_kdir)
12106         local stripe_count=$($LFS getstripe -c $test_kdir)
12107         local stripe_offset=$($LFS getstripe -i $test_kdir)
12108         [ $stripe_size -eq $default_size ] ||
12109                 error "stripe size $stripe_size != $default_size"
12110         [ $stripe_count -eq $default_count ] ||
12111                 error "stripe count $stripe_count != $default_count"
12112         [ $stripe_offset -eq $default_offset ] ||
12113                 error "stripe offset $stripe_offset != $default_offset"
12114         rm -rf $DIR/$tfile $test_kdir
12115 }
12116 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12117
12118 test_102l() {
12119         [ -z "$(which getfattr 2>/dev/null)" ] &&
12120                 skip "could not find getfattr"
12121
12122         # LU-532 trusted. xattr is invisible to non-root
12123         local testfile=$DIR/$tfile
12124
12125         touch $testfile
12126
12127         echo "listxattr as user..."
12128         chown $RUNAS_ID $testfile
12129         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12130             grep -q "trusted" &&
12131                 error "$testfile trusted xattrs are user visible"
12132
12133         return 0;
12134 }
12135 run_test 102l "listxattr size test =================================="
12136
12137 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12138         local path=$DIR/$tfile
12139         touch $path
12140
12141         listxattr_size_check $path || error "listattr_size_check $path failed"
12142 }
12143 run_test 102m "Ensure listxattr fails on small bufffer ========"
12144
12145 cleanup_test102
12146
12147 getxattr() { # getxattr path name
12148         # Return the base64 encoding of the value of xattr name on path.
12149         local path=$1
12150         local name=$2
12151
12152         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12153         # file: $path
12154         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12155         #
12156         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12157
12158         getfattr --absolute-names --encoding=base64 --name=$name $path |
12159                 awk -F= -v name=$name '$1 == name {
12160                         print substr($0, index($0, "=") + 1);
12161         }'
12162 }
12163
12164 test_102n() { # LU-4101 mdt: protect internal xattrs
12165         [ -z "$(which setfattr 2>/dev/null)" ] &&
12166                 skip "could not find setfattr"
12167         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12168         then
12169                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12170         fi
12171
12172         local file0=$DIR/$tfile.0
12173         local file1=$DIR/$tfile.1
12174         local xattr0=$TMP/$tfile.0
12175         local xattr1=$TMP/$tfile.1
12176         local namelist="lov lma lmv link fid version som hsm"
12177         local name
12178         local value
12179
12180         rm -rf $file0 $file1 $xattr0 $xattr1
12181         touch $file0 $file1
12182
12183         # Get 'before' xattrs of $file1.
12184         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12185
12186         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12187                 namelist+=" lfsck_namespace"
12188         for name in $namelist; do
12189                 # Try to copy xattr from $file0 to $file1.
12190                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12191
12192                 setfattr --name=trusted.$name --value="$value" $file1 ||
12193                         error "setxattr 'trusted.$name' failed"
12194
12195                 # Try to set a garbage xattr.
12196                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12197
12198                 if [[ x$name == "xlov" ]]; then
12199                         setfattr --name=trusted.lov --value="$value" $file1 &&
12200                         error "setxattr invalid 'trusted.lov' success"
12201                 else
12202                         setfattr --name=trusted.$name --value="$value" $file1 ||
12203                                 error "setxattr invalid 'trusted.$name' failed"
12204                 fi
12205
12206                 # Try to remove the xattr from $file1. We don't care if this
12207                 # appears to succeed or fail, we just don't want there to be
12208                 # any changes or crashes.
12209                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12210         done
12211
12212         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12213         then
12214                 name="lfsck_ns"
12215                 # Try to copy xattr from $file0 to $file1.
12216                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12217
12218                 setfattr --name=trusted.$name --value="$value" $file1 ||
12219                         error "setxattr 'trusted.$name' failed"
12220
12221                 # Try to set a garbage xattr.
12222                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12223
12224                 setfattr --name=trusted.$name --value="$value" $file1 ||
12225                         error "setxattr 'trusted.$name' failed"
12226
12227                 # Try to remove the xattr from $file1. We don't care if this
12228                 # appears to succeed or fail, we just don't want there to be
12229                 # any changes or crashes.
12230                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12231         fi
12232
12233         # Get 'after' xattrs of file1.
12234         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12235
12236         if ! diff $xattr0 $xattr1; then
12237                 error "before and after xattrs of '$file1' differ"
12238         fi
12239
12240         rm -rf $file0 $file1 $xattr0 $xattr1
12241
12242         return 0
12243 }
12244 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12245
12246 test_102p() { # LU-4703 setxattr did not check ownership
12247         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12248                 skip "MDS needs to be at least 2.5.56"
12249
12250         local testfile=$DIR/$tfile
12251
12252         touch $testfile
12253
12254         echo "setfacl as user..."
12255         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12256         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12257
12258         echo "setfattr as user..."
12259         setfacl -m "u:$RUNAS_ID:---" $testfile
12260         $RUNAS setfattr -x system.posix_acl_access $testfile
12261         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12262 }
12263 run_test 102p "check setxattr(2) correctly fails without permission"
12264
12265 test_102q() {
12266         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12267                 skip "MDS needs to be at least 2.6.92"
12268
12269         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12270 }
12271 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12272
12273 test_102r() {
12274         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12275                 skip "MDS needs to be at least 2.6.93"
12276
12277         touch $DIR/$tfile || error "touch"
12278         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12279         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12280         rm $DIR/$tfile || error "rm"
12281
12282         #normal directory
12283         mkdir -p $DIR/$tdir || error "mkdir"
12284         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12285         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12286         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12287                 error "$testfile error deleting user.author1"
12288         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12289                 grep "user.$(basename $tdir)" &&
12290                 error "$tdir did not delete user.$(basename $tdir)"
12291         rmdir $DIR/$tdir || error "rmdir"
12292
12293         #striped directory
12294         test_mkdir $DIR/$tdir
12295         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12296         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12297         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12298                 error "$testfile error deleting user.author1"
12299         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12300                 grep "user.$(basename $tdir)" &&
12301                 error "$tdir did not delete user.$(basename $tdir)"
12302         rmdir $DIR/$tdir || error "rm striped dir"
12303 }
12304 run_test 102r "set EAs with empty values"
12305
12306 test_102s() {
12307         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12308                 skip "MDS needs to be at least 2.11.52"
12309
12310         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12311
12312         save_lustre_params client "llite.*.xattr_cache" > $save
12313
12314         for cache in 0 1; do
12315                 lctl set_param llite.*.xattr_cache=$cache
12316
12317                 rm -f $DIR/$tfile
12318                 touch $DIR/$tfile || error "touch"
12319                 for prefix in lustre security system trusted user; do
12320                         # Note getxattr() may fail with 'Operation not
12321                         # supported' or 'No such attribute' depending
12322                         # on prefix and cache.
12323                         getfattr -n $prefix.n102s $DIR/$tfile &&
12324                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12325                 done
12326         done
12327
12328         restore_lustre_params < $save
12329 }
12330 run_test 102s "getting nonexistent xattrs should fail"
12331
12332 test_102t() {
12333         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12334                 skip "MDS needs to be at least 2.11.52"
12335
12336         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12337
12338         save_lustre_params client "llite.*.xattr_cache" > $save
12339
12340         for cache in 0 1; do
12341                 lctl set_param llite.*.xattr_cache=$cache
12342
12343                 for buf_size in 0 256; do
12344                         rm -f $DIR/$tfile
12345                         touch $DIR/$tfile || error "touch"
12346                         setfattr -n user.multiop $DIR/$tfile
12347                         $MULTIOP $DIR/$tfile oa$buf_size ||
12348                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12349                 done
12350         done
12351
12352         restore_lustre_params < $save
12353 }
12354 run_test 102t "zero length xattr values handled correctly"
12355
12356 run_acl_subtest()
12357 {
12358         local test=$LUSTRE/tests/acl/$1.test
12359         local tmp=$(mktemp -t $1-XXXXXX).test
12360         local bin=$2
12361         local dmn=$3
12362         local grp=$4
12363         local nbd=$5
12364         export LANG=C
12365
12366
12367         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12368         local sedgroups="-e s/:users/:$grp/g"
12369         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12370
12371         sed $sedusers $sedgroups < $test > $tmp
12372         stack_trap "rm -f $tmp"
12373         [[ -s $tmp ]] || error "sed failed to create test script"
12374
12375         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12376         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12377 }
12378
12379 test_103a() {
12380         [ "$UID" != 0 ] && skip "must run as root"
12381         $GSS && skip_env "could not run under gss"
12382         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12383                 skip_env "must have acl enabled"
12384         which setfacl || skip_env "could not find setfacl"
12385         remote_mds_nodsh && skip "remote MDS with nodsh"
12386
12387         local mdts=$(comma_list $(mdts_nodes))
12388         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12389
12390         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12391         stack_trap "[[ -z \"$saved\" ]] || \
12392                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12393
12394         ACLBIN=${ACLBIN:-"bin"}
12395         ACLDMN=${ACLDMN:-"daemon"}
12396         ACLGRP=${ACLGRP:-"users"}
12397         ACLNBD=${ACLNBD:-"nobody"}
12398
12399         if ! id $ACLBIN ||
12400            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12401                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12402                 ACLBIN=$USER0
12403                 if ! id $ACLBIN ; then
12404                         cat /etc/passwd
12405                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12406                 fi
12407         fi
12408         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12409            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12410                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12411                 ACLDMN=$USER1
12412                 if ! id $ACLDMN ; then
12413                         cat /etc/passwd
12414                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12415                 fi
12416         fi
12417         if ! getent group $ACLGRP; then
12418                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12419                 ACLGRP="$TSTUSR"
12420                 if ! getent group $ACLGRP; then
12421                         echo "cannot find group '$ACLGRP', adding it"
12422                         cat /etc/group
12423                         add_group 60000 $ACLGRP
12424                 fi
12425         fi
12426
12427         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12428         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12429         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12430
12431         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12432                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12433                 ACLGRP="$TSTUSR"
12434                 if ! getent group $ACLGRP; then
12435                         echo "cannot find group '$ACLGRP', adding it"
12436                         cat /etc/group
12437                         add_group 60000 $ACLGRP
12438                 fi
12439                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12440                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12441                         cat /etc/group
12442                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12443                 fi
12444         fi
12445
12446         gpasswd -a $ACLDMN $ACLBIN ||
12447                 error "setting client group failed"             # LU-5641
12448         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12449                 error "setting MDS group failed"                # LU-5641
12450
12451         declare -a identity_old
12452
12453         for ((num = 1; num <= $MDSCOUNT; num++)); do
12454                 switch_identity $num true || identity_old[$num]=$?
12455         done
12456
12457         SAVE_UMASK=$(umask)
12458         umask 0022
12459         mkdir -p $DIR/$tdir
12460         cd $DIR/$tdir
12461
12462         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12463         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12464         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12465         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12466         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12467         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12468         if ! id -u $ACLNBD ||
12469            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12470                 ACLNBD="nfsnobody"
12471                 if ! id -u $ACLNBD; then
12472                         ACLNBD=""
12473                 fi
12474         fi
12475         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12476                 add_group $(id -u $ACLNBD) $ACLNBD
12477                 if ! getent group $ACLNBD; then
12478                         ACLNBD=""
12479                 fi
12480         fi
12481         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12482            [[ -n "$ACLNBD" ]] && which setfattr; then
12483                 run_acl_subtest permissions_xattr \
12484                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12485         elif [[ -z "$ACLNBD" ]]; then
12486                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12487         else
12488                 echo "skip 'permission_xattr' test - missing setfattr command"
12489         fi
12490         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12491
12492         # inheritance test got from HP
12493         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12494         chmod +x make-tree || error "chmod +x failed"
12495         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12496         rm -f make-tree
12497
12498         echo "LU-974 ignore umask when acl is enabled..."
12499         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12500         if [ $MDSCOUNT -ge 2 ]; then
12501                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12502         fi
12503
12504         echo "LU-2561 newly created file is same size as directory..."
12505         if [ "$mds1_FSTYPE" != "zfs" ]; then
12506                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12507         else
12508                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12509         fi
12510
12511         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12512
12513         cd $SAVE_PWD
12514         umask $SAVE_UMASK
12515
12516         for ((num = 1; num <= $MDSCOUNT; num++)); do
12517                 if [[ "${identity_old[$num]}" == 1 ]]; then
12518                         switch_identity $num false || identity_old[$num]=$?
12519                 fi
12520         done
12521 }
12522 run_test 103a "acl test"
12523
12524 test_103b() {
12525         declare -a pids
12526         local U
12527
12528         stack_trap "rm -f $DIR/$tfile.*"
12529         for U in {0..511}; do
12530                 {
12531                 local O=$(printf "%04o" $U)
12532
12533                 umask $(printf "%04o" $((511 ^ $O)))
12534                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12535                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12536
12537                 (( $S == ($O & 0666) )) ||
12538                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12539
12540                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12541                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12542                 (( $S == ($O & 0666) )) ||
12543                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12544
12545                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12546                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12547                 (( $S == ($O & 0666) )) ||
12548                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12549                 rm -f $DIR/$tfile.[smp]$0
12550                 } &
12551                 local pid=$!
12552
12553                 # limit the concurrently running threads to 64. LU-11878
12554                 local idx=$((U % 64))
12555                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12556                 pids[idx]=$pid
12557         done
12558         wait
12559 }
12560 run_test 103b "umask lfs setstripe"
12561
12562 test_103c() {
12563         mkdir -p $DIR/$tdir
12564         cp -rp $DIR/$tdir $DIR/$tdir.bak
12565
12566         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12567                 error "$DIR/$tdir shouldn't contain default ACL"
12568         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12569                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12570         true
12571 }
12572 run_test 103c "'cp -rp' won't set empty acl"
12573
12574 test_103e() {
12575         local numacl
12576         local fileacl
12577         local saved_debug=$($LCTL get_param -n debug)
12578
12579         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12580                 skip "MDS needs to be at least 2.14.52"
12581
12582         large_xattr_enabled || skip_env "ea_inode feature disabled"
12583
12584         mkdir -p $DIR/$tdir
12585         # add big LOV EA to cause reply buffer overflow earlier
12586         $LFS setstripe -C 1000 $DIR/$tdir
12587         lctl set_param mdc.*-mdc*.stats=clear
12588
12589         $LCTL set_param debug=0
12590         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12591         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12592
12593         # add a large number of default ACLs (expect 8000+ for 2.13+)
12594         for U in {2..7000}; do
12595                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12596                         error "Able to add just $U default ACLs"
12597         done
12598         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12599         echo "$numacl default ACLs created"
12600
12601         stat $DIR/$tdir || error "Cannot stat directory"
12602         # check file creation
12603         touch $DIR/$tdir/$tfile ||
12604                 error "failed to create $tfile with $numacl default ACLs"
12605         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12606         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12607         echo "$fileacl ACLs were inherited"
12608         (( $fileacl == $numacl )) ||
12609                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12610         # check that new ACLs creation adds new ACLs to inherited ACLs
12611         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12612                 error "Cannot set new ACL"
12613         numacl=$((numacl + 1))
12614         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12615         (( $fileacl == $numacl )) ||
12616                 error "failed to add new ACL: $fileacl != $numacl as expected"
12617         # adds more ACLs to a file to reach their maximum at 8000+
12618         numacl=0
12619         for U in {20000..25000}; do
12620                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12621                 numacl=$((numacl + 1))
12622         done
12623         echo "Added $numacl more ACLs to the file"
12624         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12625         echo "Total $fileacl ACLs in file"
12626         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12627         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12628         rmdir $DIR/$tdir || error "Cannot remove directory"
12629 }
12630 run_test 103e "inheritance of big amount of default ACLs"
12631
12632 test_103f() {
12633         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12634                 skip "MDS needs to be at least 2.14.51"
12635
12636         large_xattr_enabled || skip_env "ea_inode feature disabled"
12637
12638         # enable changelog to consume more internal MDD buffers
12639         changelog_register
12640
12641         mkdir -p $DIR/$tdir
12642         # add big LOV EA
12643         $LFS setstripe -C 1000 $DIR/$tdir
12644         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12645         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12646         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12647         rmdir $DIR/$tdir || error "Cannot remove directory"
12648 }
12649 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12650
12651 test_104a() {
12652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12653
12654         touch $DIR/$tfile
12655         lfs df || error "lfs df failed"
12656         lfs df -ih || error "lfs df -ih failed"
12657         lfs df -h $DIR || error "lfs df -h $DIR failed"
12658         lfs df -i $DIR || error "lfs df -i $DIR failed"
12659         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12660         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12661
12662         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12663         lctl --device %$OSC deactivate
12664         lfs df || error "lfs df with deactivated OSC failed"
12665         lctl --device %$OSC activate
12666         # wait the osc back to normal
12667         wait_osc_import_ready client ost
12668
12669         lfs df || error "lfs df with reactivated OSC failed"
12670         rm -f $DIR/$tfile
12671 }
12672 run_test 104a "lfs df [-ih] [path] test ========================="
12673
12674 test_104b() {
12675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12676         [ $RUNAS_ID -eq $UID ] &&
12677                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12678
12679         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12680                         grep "Permission denied" | wc -l)))
12681         if [ $denied_cnt -ne 0 ]; then
12682                 error "lfs check servers test failed"
12683         fi
12684 }
12685 run_test 104b "$RUNAS lfs check servers test ===================="
12686
12687 #
12688 # Verify $1 is within range of $2.
12689 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12690 # $1 is <= 2% of $2. Else Fail.
12691 #
12692 value_in_range() {
12693         # Strip all units (M, G, T)
12694         actual=$(echo $1 | tr -d A-Z)
12695         expect=$(echo $2 | tr -d A-Z)
12696
12697         expect_lo=$(($expect * 98 / 100)) # 2% below
12698         expect_hi=$(($expect * 102 / 100)) # 2% above
12699
12700         # permit 2% drift above and below
12701         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12702 }
12703
12704 test_104c() {
12705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12706         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12707
12708         local ost_param="osd-zfs.$FSNAME-OST0000."
12709         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12710         local ofacets=$(get_facets OST)
12711         local mfacets=$(get_facets MDS)
12712         local saved_ost_blocks=
12713         local saved_mdt_blocks=
12714
12715         echo "Before recordsize change"
12716         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12717         df=($(df -h | grep "$MOUNT"$))
12718
12719         # For checking.
12720         echo "lfs output : ${lfs_df[*]}"
12721         echo "df  output : ${df[*]}"
12722
12723         for facet in ${ofacets//,/ }; do
12724                 if [ -z $saved_ost_blocks ]; then
12725                         saved_ost_blocks=$(do_facet $facet \
12726                                 lctl get_param -n $ost_param.blocksize)
12727                         echo "OST Blocksize: $saved_ost_blocks"
12728                 fi
12729                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12730                 do_facet $facet zfs set recordsize=32768 $ost
12731         done
12732
12733         # BS too small. Sufficient for functional testing.
12734         for facet in ${mfacets//,/ }; do
12735                 if [ -z $saved_mdt_blocks ]; then
12736                         saved_mdt_blocks=$(do_facet $facet \
12737                                 lctl get_param -n $mdt_param.blocksize)
12738                         echo "MDT Blocksize: $saved_mdt_blocks"
12739                 fi
12740                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12741                 do_facet $facet zfs set recordsize=32768 $mdt
12742         done
12743
12744         # Give new values chance to reflect change
12745         sleep 2
12746
12747         echo "After recordsize change"
12748         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12749         df_after=($(df -h | grep "$MOUNT"$))
12750
12751         # For checking.
12752         echo "lfs output : ${lfs_df_after[*]}"
12753         echo "df  output : ${df_after[*]}"
12754
12755         # Verify lfs df
12756         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12757                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12758         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12759                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12760         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12761                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12762
12763         # Verify df
12764         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12765                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12766         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12767                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12768         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12769                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12770
12771         # Restore MDT recordize back to original
12772         for facet in ${mfacets//,/ }; do
12773                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12774                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12775         done
12776
12777         # Restore OST recordize back to original
12778         for facet in ${ofacets//,/ }; do
12779                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12780                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12781         done
12782
12783         return 0
12784 }
12785 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12786
12787 test_104d() {
12788         (( $RUNAS_ID != $UID )) ||
12789                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12790
12791         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12792                 skip "lustre version doesn't support lctl dl with non-root"
12793
12794         # debugfs only allows root users to access files, so the
12795         # previous move of the "devices" file to debugfs broke
12796         # "lctl dl" for non-root users. The LU-9680 Netlink
12797         # interface again allows non-root users to list devices.
12798         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12799                 error "lctl dl doesn't work for non root"
12800
12801         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12802         [ "$ost_count" -eq $OSTCOUNT ]  ||
12803                 error "lctl dl reports wrong number of OST devices"
12804
12805         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12806         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12807                 error "lctl dl reports wrong number of MDT devices"
12808 }
12809 run_test 104d "$RUNAS lctl dl test"
12810
12811 test_105a() {
12812         # doesn't work on 2.4 kernels
12813         touch $DIR/$tfile
12814         if $(flock_is_enabled); then
12815                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12816         else
12817                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12818         fi
12819         rm -f $DIR/$tfile
12820 }
12821 run_test 105a "flock when mounted without -o flock test ========"
12822
12823 test_105b() {
12824         touch $DIR/$tfile
12825         if $(flock_is_enabled); then
12826                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12827         else
12828                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12829         fi
12830         rm -f $DIR/$tfile
12831 }
12832 run_test 105b "fcntl when mounted without -o flock test ========"
12833
12834 test_105c() {
12835         touch $DIR/$tfile
12836         if $(flock_is_enabled); then
12837                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12838         else
12839                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12840         fi
12841         rm -f $DIR/$tfile
12842 }
12843 run_test 105c "lockf when mounted without -o flock test"
12844
12845 test_105d() { # bug 15924
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12847
12848         test_mkdir $DIR/$tdir
12849         flock_is_enabled || skip_env "mount w/o flock enabled"
12850         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12851         $LCTL set_param fail_loc=0x80000315
12852         flocks_test 2 $DIR/$tdir
12853 }
12854 run_test 105d "flock race (should not freeze) ========"
12855
12856 test_105e() { # bug 22660 && 22040
12857         flock_is_enabled || skip_env "mount w/o flock enabled"
12858
12859         touch $DIR/$tfile
12860         flocks_test 3 $DIR/$tfile
12861 }
12862 run_test 105e "Two conflicting flocks from same process"
12863
12864 test_106() { #bug 10921
12865         test_mkdir $DIR/$tdir
12866         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12867         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12868 }
12869 run_test 106 "attempt exec of dir followed by chown of that dir"
12870
12871 test_107() {
12872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12873
12874         CDIR=`pwd`
12875         local file=core
12876
12877         cd $DIR
12878         rm -f $file
12879
12880         local save_pattern=$(sysctl -n kernel.core_pattern)
12881         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12882         sysctl -w kernel.core_pattern=$file
12883         sysctl -w kernel.core_uses_pid=0
12884
12885         ulimit -c unlimited
12886         sleep 60 &
12887         SLEEPPID=$!
12888
12889         sleep 1
12890
12891         kill -s 11 $SLEEPPID
12892         wait $SLEEPPID
12893         if [ -e $file ]; then
12894                 size=`stat -c%s $file`
12895                 [ $size -eq 0 ] && error "Fail to create core file $file"
12896         else
12897                 error "Fail to create core file $file"
12898         fi
12899         rm -f $file
12900         sysctl -w kernel.core_pattern=$save_pattern
12901         sysctl -w kernel.core_uses_pid=$save_uses_pid
12902         cd $CDIR
12903 }
12904 run_test 107 "Coredump on SIG"
12905
12906 test_110() {
12907         test_mkdir $DIR/$tdir
12908         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12909         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12910                 error "mkdir with 256 char should fail, but did not"
12911         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12912                 error "create with 255 char failed"
12913         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12914                 error "create with 256 char should fail, but did not"
12915
12916         ls -l $DIR/$tdir
12917         rm -rf $DIR/$tdir
12918 }
12919 run_test 110 "filename length checking"
12920
12921 test_116a() { # was previously test_116()
12922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12924         remote_mds_nodsh && skip "remote MDS with nodsh"
12925
12926         echo -n "Free space priority "
12927         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12928                 head -n1
12929         declare -a AVAIL
12930         free_min_max
12931
12932         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12933         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12934         stack_trap simple_cleanup_common
12935
12936         # Check if we need to generate uneven OSTs
12937         test_mkdir -p $DIR/$tdir/OST${MINI}
12938         local FILL=$((MINV / 4))
12939         local DIFF=$((MAXV - MINV))
12940         local DIFF2=$((DIFF * 100 / MINV))
12941
12942         local threshold=$(do_facet $SINGLEMDS \
12943                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12944         threshold=${threshold%%%}
12945         echo -n "Check for uneven OSTs: "
12946         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12947
12948         if [[ $DIFF2 -gt $threshold ]]; then
12949                 echo "ok"
12950                 echo "Don't need to fill OST$MINI"
12951         else
12952                 # generate uneven OSTs. Write 2% over the QOS threshold value
12953                 echo "no"
12954                 DIFF=$((threshold - DIFF2 + 2))
12955                 DIFF2=$((MINV * DIFF / 100))
12956                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12957                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12958                         error "setstripe failed"
12959                 DIFF=$((DIFF2 / 2048))
12960                 i=0
12961                 while [ $i -lt $DIFF ]; do
12962                         i=$((i + 1))
12963                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12964                                 bs=2M count=1 2>/dev/null
12965                         echo -n .
12966                 done
12967                 echo .
12968                 sync
12969                 sleep_maxage
12970                 free_min_max
12971         fi
12972
12973         DIFF=$((MAXV - MINV))
12974         DIFF2=$((DIFF * 100 / MINV))
12975         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12976         if [ $DIFF2 -gt $threshold ]; then
12977                 echo "ok"
12978         else
12979                 skip "QOS imbalance criteria not met"
12980         fi
12981
12982         MINI1=$MINI
12983         MINV1=$MINV
12984         MAXI1=$MAXI
12985         MAXV1=$MAXV
12986
12987         # now fill using QOS
12988         $LFS setstripe -c 1 $DIR/$tdir
12989         FILL=$((FILL / 200))
12990         if [ $FILL -gt 600 ]; then
12991                 FILL=600
12992         fi
12993         echo "writing $FILL files to QOS-assigned OSTs"
12994         i=0
12995         while [ $i -lt $FILL ]; do
12996                 i=$((i + 1))
12997                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12998                         count=1 2>/dev/null
12999                 echo -n .
13000         done
13001         echo "wrote $i 200k files"
13002         sync
13003         sleep_maxage
13004
13005         echo "Note: free space may not be updated, so measurements might be off"
13006         free_min_max
13007         DIFF2=$((MAXV - MINV))
13008         echo "free space delta: orig $DIFF final $DIFF2"
13009         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13010         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13011         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13012         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13013         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13014         if [[ $DIFF -gt 0 ]]; then
13015                 FILL=$((DIFF2 * 100 / DIFF - 100))
13016                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13017         fi
13018
13019         # Figure out which files were written where
13020         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13021                awk '/'$MINI1': / {print $2; exit}')
13022         echo $UUID
13023         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13024         echo "$MINC files created on smaller OST $MINI1"
13025         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13026                awk '/'$MAXI1': / {print $2; exit}')
13027         echo $UUID
13028         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13029         echo "$MAXC files created on larger OST $MAXI1"
13030         if [[ $MINC -gt 0 ]]; then
13031                 FILL=$((MAXC * 100 / MINC - 100))
13032                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13033         fi
13034         [[ $MAXC -gt $MINC ]] ||
13035                 error_ignore LU-9 "stripe QOS didn't balance free space"
13036 }
13037 run_test 116a "stripe QOS: free space balance ==================="
13038
13039 test_116b() { # LU-2093
13040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13041         remote_mds_nodsh && skip "remote MDS with nodsh"
13042
13043 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13044         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13045                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13046         [ -z "$old_rr" ] && skip "no QOS"
13047         do_facet $SINGLEMDS lctl set_param \
13048                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13049         mkdir -p $DIR/$tdir
13050         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13051         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13052         do_facet $SINGLEMDS lctl set_param fail_loc=0
13053         rm -rf $DIR/$tdir
13054         do_facet $SINGLEMDS lctl set_param \
13055                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13056 }
13057 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13058
13059 test_117() # bug 10891
13060 {
13061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13062
13063         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13064         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13065         lctl set_param fail_loc=0x21e
13066         > $DIR/$tfile || error "truncate failed"
13067         lctl set_param fail_loc=0
13068         echo "Truncate succeeded."
13069         rm -f $DIR/$tfile
13070 }
13071 run_test 117 "verify osd extend =========="
13072
13073 NO_SLOW_RESENDCOUNT=4
13074 export OLD_RESENDCOUNT=""
13075 set_resend_count () {
13076         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13077         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13078         lctl set_param -n $PROC_RESENDCOUNT $1
13079         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13080 }
13081
13082 # for reduce test_118* time (b=14842)
13083 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13084
13085 # Reset async IO behavior after error case
13086 reset_async() {
13087         FILE=$DIR/reset_async
13088
13089         # Ensure all OSCs are cleared
13090         $LFS setstripe -c -1 $FILE
13091         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13092         sync
13093         rm $FILE
13094 }
13095
13096 test_118a() #bug 11710
13097 {
13098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13099
13100         reset_async
13101
13102         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13103         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13104         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13105
13106         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13107                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13108                 return 1;
13109         fi
13110         rm -f $DIR/$tfile
13111 }
13112 run_test 118a "verify O_SYNC works =========="
13113
13114 test_118b()
13115 {
13116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13117         remote_ost_nodsh && skip "remote OST with nodsh"
13118
13119         reset_async
13120
13121         #define OBD_FAIL_SRV_ENOENT 0x217
13122         set_nodes_failloc "$(osts_nodes)" 0x217
13123         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13124         RC=$?
13125         set_nodes_failloc "$(osts_nodes)" 0
13126         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13127         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13128                     grep -c writeback)
13129
13130         if [[ $RC -eq 0 ]]; then
13131                 error "Must return error due to dropped pages, rc=$RC"
13132                 return 1;
13133         fi
13134
13135         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13136                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13137                 return 1;
13138         fi
13139
13140         echo "Dirty pages not leaked on ENOENT"
13141
13142         # Due to the above error the OSC will issue all RPCs syncronously
13143         # until a subsequent RPC completes successfully without error.
13144         $MULTIOP $DIR/$tfile Ow4096yc
13145         rm -f $DIR/$tfile
13146
13147         return 0
13148 }
13149 run_test 118b "Reclaim dirty pages on fatal error =========="
13150
13151 test_118c()
13152 {
13153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13154
13155         # for 118c, restore the original resend count, LU-1940
13156         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13157                                 set_resend_count $OLD_RESENDCOUNT
13158         remote_ost_nodsh && skip "remote OST with nodsh"
13159
13160         reset_async
13161
13162         #define OBD_FAIL_OST_EROFS               0x216
13163         set_nodes_failloc "$(osts_nodes)" 0x216
13164
13165         # multiop should block due to fsync until pages are written
13166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13167         MULTIPID=$!
13168         sleep 1
13169
13170         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13171                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13172         fi
13173
13174         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13175                     grep -c writeback)
13176         if [[ $WRITEBACK -eq 0 ]]; then
13177                 error "No page in writeback, writeback=$WRITEBACK"
13178         fi
13179
13180         set_nodes_failloc "$(osts_nodes)" 0
13181         wait $MULTIPID
13182         RC=$?
13183         if [[ $RC -ne 0 ]]; then
13184                 error "Multiop fsync failed, rc=$RC"
13185         fi
13186
13187         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13188         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13189                     grep -c writeback)
13190         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13191                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13192         fi
13193
13194         rm -f $DIR/$tfile
13195         echo "Dirty pages flushed via fsync on EROFS"
13196         return 0
13197 }
13198 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13199
13200 # continue to use small resend count to reduce test_118* time (b=14842)
13201 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13202
13203 test_118d()
13204 {
13205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13206         remote_ost_nodsh && skip "remote OST with nodsh"
13207
13208         reset_async
13209
13210         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13211         set_nodes_failloc "$(osts_nodes)" 0x214
13212         # multiop should block due to fsync until pages are written
13213         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13214         MULTIPID=$!
13215         sleep 1
13216
13217         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13218                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13219         fi
13220
13221         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13222                     grep -c writeback)
13223         if [[ $WRITEBACK -eq 0 ]]; then
13224                 error "No page in writeback, writeback=$WRITEBACK"
13225         fi
13226
13227         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13228         set_nodes_failloc "$(osts_nodes)" 0
13229
13230         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13231         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13232                     grep -c writeback)
13233         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13234                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13235         fi
13236
13237         rm -f $DIR/$tfile
13238         echo "Dirty pages gaurenteed flushed via fsync"
13239         return 0
13240 }
13241 run_test 118d "Fsync validation inject a delay of the bulk =========="
13242
13243 test_118f() {
13244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13245
13246         reset_async
13247
13248         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13249         lctl set_param fail_loc=0x8000040a
13250
13251         # Should simulate EINVAL error which is fatal
13252         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13253         RC=$?
13254         if [[ $RC -eq 0 ]]; then
13255                 error "Must return error due to dropped pages, rc=$RC"
13256         fi
13257
13258         lctl set_param fail_loc=0x0
13259
13260         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13261         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13262         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13263                     grep -c writeback)
13264         if [[ $LOCKED -ne 0 ]]; then
13265                 error "Locked pages remain in cache, locked=$LOCKED"
13266         fi
13267
13268         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13269                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13270         fi
13271
13272         rm -f $DIR/$tfile
13273         echo "No pages locked after fsync"
13274
13275         reset_async
13276         return 0
13277 }
13278 run_test 118f "Simulate unrecoverable OSC side error =========="
13279
13280 test_118g() {
13281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13282
13283         reset_async
13284
13285         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13286         lctl set_param fail_loc=0x406
13287
13288         # simulate local -ENOMEM
13289         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13290         RC=$?
13291
13292         lctl set_param fail_loc=0
13293         if [[ $RC -eq 0 ]]; then
13294                 error "Must return error due to dropped pages, rc=$RC"
13295         fi
13296
13297         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13298         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13299         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13300                         grep -c writeback)
13301         if [[ $LOCKED -ne 0 ]]; then
13302                 error "Locked pages remain in cache, locked=$LOCKED"
13303         fi
13304
13305         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13306                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13307         fi
13308
13309         rm -f $DIR/$tfile
13310         echo "No pages locked after fsync"
13311
13312         reset_async
13313         return 0
13314 }
13315 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13316
13317 test_118h() {
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319         remote_ost_nodsh && skip "remote OST with nodsh"
13320
13321         reset_async
13322
13323         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13324         set_nodes_failloc "$(osts_nodes)" 0x20e
13325         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13326         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13327         RC=$?
13328
13329         set_nodes_failloc "$(osts_nodes)" 0
13330         if [[ $RC -eq 0 ]]; then
13331                 error "Must return error due to dropped pages, rc=$RC"
13332         fi
13333
13334         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13335         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13336         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13337                     grep -c writeback)
13338         if [[ $LOCKED -ne 0 ]]; then
13339                 error "Locked pages remain in cache, locked=$LOCKED"
13340         fi
13341
13342         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13343                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13344         fi
13345
13346         rm -f $DIR/$tfile
13347         echo "No pages locked after fsync"
13348
13349         return 0
13350 }
13351 run_test 118h "Verify timeout in handling recoverables errors  =========="
13352
13353 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13354
13355 test_118i() {
13356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13357         remote_ost_nodsh && skip "remote OST with nodsh"
13358
13359         reset_async
13360
13361         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13362         set_nodes_failloc "$(osts_nodes)" 0x20e
13363
13364         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13365         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13366         PID=$!
13367         sleep 5
13368         set_nodes_failloc "$(osts_nodes)" 0
13369
13370         wait $PID
13371         RC=$?
13372         if [[ $RC -ne 0 ]]; then
13373                 error "got error, but should be not, rc=$RC"
13374         fi
13375
13376         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13377         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13378         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13379         if [[ $LOCKED -ne 0 ]]; then
13380                 error "Locked pages remain in cache, locked=$LOCKED"
13381         fi
13382
13383         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13384                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13385         fi
13386
13387         rm -f $DIR/$tfile
13388         echo "No pages locked after fsync"
13389
13390         return 0
13391 }
13392 run_test 118i "Fix error before timeout in recoverable error  =========="
13393
13394 [ "$SLOW" = "no" ] && set_resend_count 4
13395
13396 test_118j() {
13397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13398         remote_ost_nodsh && skip "remote OST with nodsh"
13399
13400         reset_async
13401
13402         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13403         set_nodes_failloc "$(osts_nodes)" 0x220
13404
13405         # return -EIO from OST
13406         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13407         RC=$?
13408         set_nodes_failloc "$(osts_nodes)" 0x0
13409         if [[ $RC -eq 0 ]]; then
13410                 error "Must return error due to dropped pages, rc=$RC"
13411         fi
13412
13413         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13414         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13415         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13416         if [[ $LOCKED -ne 0 ]]; then
13417                 error "Locked pages remain in cache, locked=$LOCKED"
13418         fi
13419
13420         # in recoverable error on OST we want resend and stay until it finished
13421         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13422                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13423         fi
13424
13425         rm -f $DIR/$tfile
13426         echo "No pages locked after fsync"
13427
13428         return 0
13429 }
13430 run_test 118j "Simulate unrecoverable OST side error =========="
13431
13432 test_118k()
13433 {
13434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13435         remote_ost_nodsh && skip "remote OSTs with nodsh"
13436
13437         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13438         set_nodes_failloc "$(osts_nodes)" 0x20e
13439         test_mkdir $DIR/$tdir
13440
13441         for ((i=0;i<10;i++)); do
13442                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13443                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13444                 SLEEPPID=$!
13445                 sleep 0.500s
13446                 kill $SLEEPPID
13447                 wait $SLEEPPID
13448         done
13449
13450         set_nodes_failloc "$(osts_nodes)" 0
13451         rm -rf $DIR/$tdir
13452 }
13453 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13454
13455 test_118l() # LU-646
13456 {
13457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13458
13459         test_mkdir $DIR/$tdir
13460         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13461         rm -rf $DIR/$tdir
13462 }
13463 run_test 118l "fsync dir"
13464
13465 test_118m() # LU-3066
13466 {
13467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13468
13469         test_mkdir $DIR/$tdir
13470         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13471         rm -rf $DIR/$tdir
13472 }
13473 run_test 118m "fdatasync dir ========="
13474
13475 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13476
13477 test_118n()
13478 {
13479         local begin
13480         local end
13481
13482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13483         remote_ost_nodsh && skip "remote OSTs with nodsh"
13484
13485         # Sleep to avoid a cached response.
13486         #define OBD_STATFS_CACHE_SECONDS 1
13487         sleep 2
13488
13489         # Inject a 10 second delay in the OST_STATFS handler.
13490         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13491         set_nodes_failloc "$(osts_nodes)" 0x242
13492
13493         begin=$SECONDS
13494         stat --file-system $MOUNT > /dev/null
13495         end=$SECONDS
13496
13497         set_nodes_failloc "$(osts_nodes)" 0
13498
13499         if ((end - begin > 20)); then
13500             error "statfs took $((end - begin)) seconds, expected 10"
13501         fi
13502 }
13503 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13504
13505 test_119a() # bug 11737
13506 {
13507         BSIZE=$((512 * 1024))
13508         directio write $DIR/$tfile 0 1 $BSIZE
13509         # We ask to read two blocks, which is more than a file size.
13510         # directio will indicate an error when requested and actual
13511         # sizes aren't equeal (a normal situation in this case) and
13512         # print actual read amount.
13513         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13514         if [ "$NOB" != "$BSIZE" ]; then
13515                 error "read $NOB bytes instead of $BSIZE"
13516         fi
13517         rm -f $DIR/$tfile
13518 }
13519 run_test 119a "Short directIO read must return actual read amount"
13520
13521 test_119b() # bug 11737
13522 {
13523         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13524
13525         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13527         sync
13528         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13529                 error "direct read failed"
13530         rm -f $DIR/$tfile
13531 }
13532 run_test 119b "Sparse directIO read must return actual read amount"
13533
13534 test_119c() # bug 13099
13535 {
13536         BSIZE=1048576
13537         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13538         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13539         rm -f $DIR/$tfile
13540 }
13541 run_test 119c "Testing for direct read hitting hole"
13542
13543 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13544 # Maloo test history
13545
13546 test_119e()
13547 {
13548         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13549                 skip "Need server version at least 2.15.58"
13550         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13551
13552         local stripe_size=$((1024 * 1024)) #1 MiB
13553         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13554         local file_size=$((25 * stripe_size))
13555         local bsizes
13556
13557         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13558         stack_trap "rm -f $DIR/$tfile*"
13559
13560         # Just a bit bigger than the largest size in the test set below
13561         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13562                 error "buffered i/o to create file failed"
13563
13564         # trivial test of unaligned DIO
13565         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13566                 iflag=direct oflag=direct ||
13567                 error "trivial unaligned dio failed"
13568
13569         # Test of disabling unaligned DIO support
13570         $LCTL set_param llite.*.unaligned_dio=0
13571         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13572         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13573         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13574                 iflag=direct oflag=direct &&
13575                 error "unaligned dio succeeded when disabled"
13576         $LCTL set_param llite.*.unaligned_dio=1
13577
13578         # Clean up before next part of test
13579         rm -f $DIR/$tfile.2
13580
13581         if zfs_or_rotational; then
13582                 # DIO on ZFS can take up to 2 seconds per IO
13583                 # rotational is better, but still slow.
13584                 # Limit testing on those media to larger sizes
13585                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13586                         $((stripe_size + 1024))"
13587         else
13588                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13589                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13590                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13591                         $((stripe_size - 1)) $stripe_size \
13592                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13593                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13594         fi
13595
13596         for bs in $bsizes; do
13597                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13598                 echo "Read/write with DIO at size $bs"
13599                 # Read and write with DIO from source to dest
13600                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13601                         iflag=direct oflag=direct ||
13602                         error "dio failed"
13603
13604                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13605                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13606                         error "size incorrect, file copy read/write bsize: $bs"
13607                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13608                         error "files differ, bsize $bs"
13609                 rm -f $DIR/$tfile.2
13610         done
13611 }
13612 run_test 119e "Basic tests of dio read and write at various sizes"
13613
13614 test_119f()
13615 {
13616         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13617
13618         local stripe_size=$((1024 * 1024)) #1 MiB
13619         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13620         local file_size=$((25 * stripe_size))
13621         local bsizes
13622
13623         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13624         stack_trap "rm -f $DIR/$tfile*"
13625
13626         # Just a bit bigger than the largest size in the test set below
13627         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13628                 error "buffered i/o to create file failed"
13629
13630         if zfs_or_rotational; then
13631                 # DIO on ZFS can take up to 2 seconds per IO
13632                 # rotational is better, but still slow.
13633                 # Limit testing on those media to larger sizes
13634                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13635                         $((stripe_size + 1024))"
13636         else
13637                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13638                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13639                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13640                         $((stripe_size - 1)) $stripe_size \
13641                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13642                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13643         fi
13644
13645         for bs in $bsizes; do
13646                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13647                 # Read and write with DIO from source to dest in two
13648                 # threads - should give correct copy of file
13649
13650                 echo "bs: $bs"
13651                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13652                         oflag=direct conv=notrunc &
13653                 pid_dio1=$!
13654                 # Note block size is different here for a more interesting race
13655                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13656                         iflag=direct oflag=direct conv=notrunc &
13657                 pid_dio2=$!
13658                 wait $pid_dio1
13659                 rc1=$?
13660                 wait $pid_dio2
13661                 rc2=$?
13662                 if (( rc1 != 0 )); then
13663                         error "dio copy 1 w/bsize $bs failed: $rc1"
13664                 fi
13665                 if (( rc2 != 0 )); then
13666                         error "dio copy 2 w/bsize $bs failed: $rc2"
13667                 fi
13668
13669
13670                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13671                         error "size incorrect, file copy read/write bsize: $bs"
13672                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13673                         error "files differ, bsize $bs"
13674                 rm -f $DIR/$tfile.2
13675         done
13676 }
13677 run_test 119f "dio vs dio race"
13678
13679 test_119g()
13680 {
13681         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13682
13683         local stripe_size=$((1024 * 1024)) #1 MiB
13684         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13685         local file_size=$((25 * stripe_size))
13686         local bsizes
13687
13688         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13689         stack_trap "rm -f $DIR/$tfile*"
13690
13691         # Just a bit bigger than the largest size in the test set below
13692         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13693                 error "buffered i/o to create file failed"
13694
13695         if zfs_or_rotational; then
13696                 # DIO on ZFS can take up to 2 seconds per IO
13697                 # rotational is better, but still slow.
13698                 # Limit testing on those media to larger sizes
13699                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13700                         $((stripe_size + 1024))"
13701         else
13702                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13703                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13704                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13705                         $((stripe_size - 1)) $stripe_size \
13706                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13707                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13708         fi
13709
13710         for bs in $bsizes; do
13711                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13712                 echo "bs: $bs"
13713                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13714                         oflag=direct conv=notrunc &
13715                 pid_dio1=$!
13716                 # Buffered I/O with similar but not the same block size
13717                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13718                 pid_bio2=$!
13719                 wait $pid_dio1
13720                 rc1=$?
13721                 wait $pid_bio2
13722                 rc2=$?
13723                 if (( rc1 != 0 )); then
13724                         error "dio copy 1 w/bsize $bs failed: $rc1"
13725                 fi
13726                 if (( rc2 != 0 )); then
13727                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13728                 fi
13729
13730                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13731                         error "size incorrect"
13732                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13733                         error "files differ, bsize $bs"
13734                 rm -f $DIR/$tfile.2
13735         done
13736 }
13737 run_test 119g "dio vs buffered I/O race"
13738
13739 test_119h()
13740 {
13741         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13742
13743         local stripe_size=$((1024 * 1024)) #1 MiB
13744         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13745         local file_size=$((25 * stripe_size))
13746         local bsizes
13747
13748         stack_trap "rm -f $DIR/$tfile.*"
13749
13750         if zfs_or_rotational; then
13751                 # DIO on ZFS can take up to 2 seconds per IO
13752                 # rotational is better, but still slow.
13753                 # Limit testing on those media to larger sizes
13754                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13755                         $((stripe_size + 1024))"
13756         else
13757                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13758                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13759                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13760                         $((stripe_size - 1)) $stripe_size \
13761                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13762                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13763         fi
13764
13765         for bs in $bsizes; do
13766                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13767                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13768                 echo "unaligned writes of blocksize: $bs"
13769                 # Write a file with unaligned DIO and regular DIO, and compare
13770                 # them
13771                 # with 'u', multiop randomly unaligns the io from the buffer
13772                 $MULTIOP $DIR/$tfile.1 \
13773                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13774                         error "multiop memory unaligned write failed, $bs"
13775                 $MULTIOP $DIR/$tfile.2 \
13776                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13777                         error "multiop memory aligned write failed, $bs"
13778
13779                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13780                         error "files differ, bsize $bs"
13781                 rm -f $DIR/$tfile.*
13782         done
13783
13784         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13785         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13786                 error "dd to create source file for read failed"
13787
13788         # Just a few quick tests to make sure unaligned DIO reads don't crash
13789         for bs in $bsizes; do
13790
13791                 echo "unaligned reads of blocksize: $bs"
13792                 # with 'u', multiop randomly unaligns the io from the buffer
13793                 $MULTIOP $DIR/$tfile.1 \
13794                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13795                         error "multiop memory unaligned read failed, $bs"
13796
13797         done
13798         rm -f $DIR/$tfile*
13799 }
13800 run_test 119h "basic tests of memory unaligned dio"
13801
13802 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13803 test_119i()
13804 {
13805         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13806         which aiocp || skip_env "no aiocp installed"
13807
13808         local stripe_size=$((1024 * 1024)) #1 MiB
13809         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13810         local file_size=$((25 * stripe_size))
13811         local bsizes
13812
13813         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13814         stack_trap "rm -f $DIR/$tfile.*"
13815
13816         # Just a bit bigger than the largest size in the test set below
13817         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13818                 error "buffered i/o to create file failed"
13819
13820         if zfs_or_rotational; then
13821                 # DIO on ZFS can take up to 2 seconds per IO
13822                 # rotational is better, but still slow.
13823                 # Limit testing on those media to larger sizes
13824                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13825                         $((stripe_size + 1024))"
13826         else
13827                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13828                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13829                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13830                         $((stripe_size - 1)) $stripe_size \
13831                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13832                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13833         fi
13834
13835         # Do page aligned and NOT page aligned AIO
13836         for align in 8 512 $((PAGE_SIZE)); do
13837         # Deliberately includes a few aligned sizes
13838         for bs in $bsizes; do
13839                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13840
13841                 echo "bs: $bs, align: $align, file_size $file_size"
13842                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13843                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13844                         error "unaligned aio failed, bs: $bs, align: $align"
13845
13846                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13847                         error "size incorrect"
13848                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13849                         error "files differ"
13850                 rm -f $DIR/$tfile.2
13851         done
13852         done
13853 }
13854 run_test 119i "test unaligned aio at varying sizes"
13855
13856 test_120a() {
13857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13858         remote_mds_nodsh && skip "remote MDS with nodsh"
13859         test_mkdir -i0 -c1 $DIR/$tdir
13860         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13861                 skip_env "no early lock cancel on server"
13862
13863         lru_resize_disable mdc
13864         lru_resize_disable osc
13865         cancel_lru_locks mdc
13866         # asynchronous object destroy at MDT could cause bl ast to client
13867         cancel_lru_locks osc
13868
13869         stat $DIR/$tdir > /dev/null
13870         can1=$(do_facet mds1 \
13871                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13872                awk '/ldlm_cancel/ {print $2}')
13873         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13874                awk '/ldlm_bl_callback/ {print $2}')
13875         test_mkdir -i0 -c1 $DIR/$tdir/d1
13876         can2=$(do_facet mds1 \
13877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13878                awk '/ldlm_cancel/ {print $2}')
13879         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13880                awk '/ldlm_bl_callback/ {print $2}')
13881         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13882         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13883         lru_resize_enable mdc
13884         lru_resize_enable osc
13885 }
13886 run_test 120a "Early Lock Cancel: mkdir test"
13887
13888 test_120b() {
13889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13890         remote_mds_nodsh && skip "remote MDS with nodsh"
13891         test_mkdir $DIR/$tdir
13892         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13893                 skip_env "no early lock cancel on server"
13894
13895         lru_resize_disable mdc
13896         lru_resize_disable osc
13897         cancel_lru_locks mdc
13898         stat $DIR/$tdir > /dev/null
13899         can1=$(do_facet $SINGLEMDS \
13900                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13901                awk '/ldlm_cancel/ {print $2}')
13902         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13903                awk '/ldlm_bl_callback/ {print $2}')
13904         touch $DIR/$tdir/f1
13905         can2=$(do_facet $SINGLEMDS \
13906                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13907                awk '/ldlm_cancel/ {print $2}')
13908         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13909                awk '/ldlm_bl_callback/ {print $2}')
13910         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13911         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13912         lru_resize_enable mdc
13913         lru_resize_enable osc
13914 }
13915 run_test 120b "Early Lock Cancel: create test"
13916
13917 test_120c() {
13918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13919         remote_mds_nodsh && skip "remote MDS with nodsh"
13920         test_mkdir -i0 -c1 $DIR/$tdir
13921         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13922                 skip "no early lock cancel on server"
13923
13924         lru_resize_disable mdc
13925         lru_resize_disable osc
13926         test_mkdir -i0 -c1 $DIR/$tdir/d1
13927         test_mkdir -i0 -c1 $DIR/$tdir/d2
13928         touch $DIR/$tdir/d1/f1
13929         cancel_lru_locks mdc
13930         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13931         can1=$(do_facet mds1 \
13932                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13933                awk '/ldlm_cancel/ {print $2}')
13934         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13935                awk '/ldlm_bl_callback/ {print $2}')
13936         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13937         can2=$(do_facet mds1 \
13938                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13939                awk '/ldlm_cancel/ {print $2}')
13940         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13941                awk '/ldlm_bl_callback/ {print $2}')
13942         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13943         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13944         lru_resize_enable mdc
13945         lru_resize_enable osc
13946 }
13947 run_test 120c "Early Lock Cancel: link test"
13948
13949 test_120d() {
13950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13951         remote_mds_nodsh && skip "remote MDS with nodsh"
13952         test_mkdir -i0 -c1 $DIR/$tdir
13953         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13954                 skip_env "no early lock cancel on server"
13955
13956         lru_resize_disable mdc
13957         lru_resize_disable osc
13958         touch $DIR/$tdir
13959         cancel_lru_locks mdc
13960         stat $DIR/$tdir > /dev/null
13961         can1=$(do_facet mds1 \
13962                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13963                awk '/ldlm_cancel/ {print $2}')
13964         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13965                awk '/ldlm_bl_callback/ {print $2}')
13966         chmod a+x $DIR/$tdir
13967         can2=$(do_facet mds1 \
13968                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13969                awk '/ldlm_cancel/ {print $2}')
13970         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13971                awk '/ldlm_bl_callback/ {print $2}')
13972         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13973         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13974         lru_resize_enable mdc
13975         lru_resize_enable osc
13976 }
13977 run_test 120d "Early Lock Cancel: setattr test"
13978
13979 test_120e() {
13980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13981         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13982                 skip_env "no early lock cancel on server"
13983         remote_mds_nodsh && skip "remote MDS with nodsh"
13984
13985         local dlmtrace_set=false
13986
13987         test_mkdir -i0 -c1 $DIR/$tdir
13988         lru_resize_disable mdc
13989         lru_resize_disable osc
13990         ! $LCTL get_param debug | grep -q dlmtrace &&
13991                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13992         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13993         cancel_lru_locks mdc
13994         cancel_lru_locks osc
13995         dd if=$DIR/$tdir/f1 of=/dev/null
13996         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13997         # XXX client can not do early lock cancel of OST lock
13998         # during unlink (LU-4206), so cancel osc lock now.
13999         sleep 2
14000         cancel_lru_locks osc
14001         can1=$(do_facet mds1 \
14002                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14003                awk '/ldlm_cancel/ {print $2}')
14004         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14005                awk '/ldlm_bl_callback/ {print $2}')
14006         unlink $DIR/$tdir/f1
14007         sleep 5
14008         can2=$(do_facet mds1 \
14009                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14010                awk '/ldlm_cancel/ {print $2}')
14011         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14012                awk '/ldlm_bl_callback/ {print $2}')
14013         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14014                 $LCTL dk $TMP/cancel.debug.txt
14015         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14016                 $LCTL dk $TMP/blocking.debug.txt
14017         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14018         lru_resize_enable mdc
14019         lru_resize_enable osc
14020 }
14021 run_test 120e "Early Lock Cancel: unlink test"
14022
14023 test_120f() {
14024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14025         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14026                 skip_env "no early lock cancel on server"
14027         remote_mds_nodsh && skip "remote MDS with nodsh"
14028
14029         test_mkdir -i0 -c1 $DIR/$tdir
14030         lru_resize_disable mdc
14031         lru_resize_disable osc
14032         test_mkdir -i0 -c1 $DIR/$tdir/d1
14033         test_mkdir -i0 -c1 $DIR/$tdir/d2
14034         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14035         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14036         cancel_lru_locks mdc
14037         cancel_lru_locks osc
14038         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14039         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14040         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14041         # XXX client can not do early lock cancel of OST lock
14042         # during rename (LU-4206), so cancel osc lock now.
14043         sleep 2
14044         cancel_lru_locks osc
14045         can1=$(do_facet mds1 \
14046                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14047                awk '/ldlm_cancel/ {print $2}')
14048         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14049                awk '/ldlm_bl_callback/ {print $2}')
14050         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14051         sleep 5
14052         can2=$(do_facet mds1 \
14053                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14054                awk '/ldlm_cancel/ {print $2}')
14055         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14056                awk '/ldlm_bl_callback/ {print $2}')
14057         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14058         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14059         lru_resize_enable mdc
14060         lru_resize_enable osc
14061 }
14062 run_test 120f "Early Lock Cancel: rename test"
14063
14064 test_120g() {
14065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14066         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14067                 skip_env "no early lock cancel on server"
14068         remote_mds_nodsh && skip "remote MDS with nodsh"
14069
14070         lru_resize_disable mdc
14071         lru_resize_disable osc
14072         count=10000
14073         echo create $count files
14074         test_mkdir $DIR/$tdir
14075         cancel_lru_locks mdc
14076         cancel_lru_locks osc
14077         t0=$(date +%s)
14078
14079         can0=$(do_facet $SINGLEMDS \
14080                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14081                awk '/ldlm_cancel/ {print $2}')
14082         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14083                awk '/ldlm_bl_callback/ {print $2}')
14084         createmany -o $DIR/$tdir/f $count
14085         sync
14086         can1=$(do_facet $SINGLEMDS \
14087                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14088                awk '/ldlm_cancel/ {print $2}')
14089         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14090                awk '/ldlm_bl_callback/ {print $2}')
14091         t1=$(date +%s)
14092         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14093         echo rm $count files
14094         rm -r $DIR/$tdir
14095         sync
14096         can2=$(do_facet $SINGLEMDS \
14097                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14098                awk '/ldlm_cancel/ {print $2}')
14099         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14100                awk '/ldlm_bl_callback/ {print $2}')
14101         t2=$(date +%s)
14102         echo total: $count removes in $((t2-t1))
14103         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14104         sleep 2
14105         # wait for commitment of removal
14106         lru_resize_enable mdc
14107         lru_resize_enable osc
14108 }
14109 run_test 120g "Early Lock Cancel: performance test"
14110
14111 test_121() { #bug #10589
14112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14113
14114         rm -rf $DIR/$tfile
14115         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14116 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14117         lctl set_param fail_loc=0x310
14118         cancel_lru_locks osc > /dev/null
14119         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14120         lctl set_param fail_loc=0
14121         [[ $reads -eq $writes ]] ||
14122                 error "read $reads blocks, must be $writes blocks"
14123 }
14124 run_test 121 "read cancel race ========="
14125
14126 test_123a_base() { # was test 123, statahead(bug 11401)
14127         local lsx="$1"
14128
14129         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14130
14131         SLOWOK=0
14132         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14133                 log "testing UP system. Performance may be lower than expected."
14134                 SLOWOK=1
14135         fi
14136         running_in_vm && SLOWOK=1
14137
14138         $LCTL set_param mdc.*.batch_stats=0
14139
14140         rm -rf $DIR/$tdir
14141         test_mkdir $DIR/$tdir
14142         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14143         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14144         MULT=10
14145         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14146                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14147
14148                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14149                 lctl set_param -n llite.*.statahead_max 0
14150                 lctl get_param llite.*.statahead_max
14151                 cancel_lru_locks mdc
14152                 cancel_lru_locks osc
14153                 stime=$(date +%s)
14154                 time $lsx $DIR/$tdir | wc -l
14155                 etime=$(date +%s)
14156                 delta=$((etime - stime))
14157                 log "$lsx $i files without statahead: $delta sec"
14158                 lctl set_param llite.*.statahead_max=$max
14159
14160                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14161                          awk '/statahead.wrong:/ { print $NF }')
14162                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14163                 cancel_lru_locks mdc
14164                 cancel_lru_locks osc
14165                 stime=$(date +%s)
14166                 time $lsx $DIR/$tdir | wc -l
14167                 etime=$(date +%s)
14168                 delta_sa=$((etime - stime))
14169                 log "$lsx $i files with statahead: $delta_sa sec"
14170                 lctl get_param -n llite.*.statahead_stats
14171                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14172                          awk '/statahead.wrong:/ { print $NF }')
14173
14174                 [[ $swrong -lt $ewrong ]] &&
14175                         log "statahead was stopped, maybe too many locks held!"
14176                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14177
14178                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14179                         max=$(lctl get_param -n llite.*.statahead_max |
14180                                 head -n 1)
14181                         lctl set_param -n llite.*.statahead_max 0
14182                         lctl get_param llite.*.statahead_max
14183                         cancel_lru_locks mdc
14184                         cancel_lru_locks osc
14185                         stime=$(date +%s)
14186                         time $lsx $DIR/$tdir | wc -l
14187                         etime=$(date +%s)
14188                         delta=$((etime - stime))
14189                         log "$lsx $i files again without statahead: $delta sec"
14190                         lctl set_param llite.*.statahead_max=$max
14191                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14192                                 if [ $SLOWOK -eq 0 ]; then
14193                                         error "$lsx $i files is slower with statahead!"
14194                                 else
14195                                         log "$lsx $i files is slower with statahead!"
14196                                 fi
14197                                 break
14198                         fi
14199                 fi
14200
14201                 [ $delta -gt 20 ] && break
14202                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14203                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14204         done
14205         log "$lsx done"
14206
14207         stime=$(date +%s)
14208         rm -r $DIR/$tdir
14209         sync
14210         etime=$(date +%s)
14211         delta=$((etime - stime))
14212         log "rm -r $DIR/$tdir/: $delta seconds"
14213         log "rm done"
14214         lctl get_param -n llite.*.statahead_stats
14215         $LCTL get_param mdc.*.batch_stats
14216 }
14217
14218 test_123aa() {
14219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14220
14221         test_123a_base "ls -l"
14222 }
14223 run_test 123aa "verify statahead work"
14224
14225 test_123ab() {
14226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14227
14228         statx_supported || skip_env "Test must be statx() syscall supported"
14229
14230         test_123a_base "$STATX -l"
14231 }
14232 run_test 123ab "verify statahead work by using statx"
14233
14234 test_123ac() {
14235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14236
14237         statx_supported || skip_env "Test must be statx() syscall supported"
14238
14239         local rpcs_before
14240         local rpcs_after
14241         local agl_before
14242         local agl_after
14243
14244         cancel_lru_locks $OSC
14245         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14246         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14247                      awk '/agl.total:/ { print $NF }')
14248         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14249         test_123a_base "$STATX --cached=always -D"
14250         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14251                     awk '/agl.total:/ { print $NF }')
14252         [ $agl_before -eq $agl_after ] ||
14253                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14254         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14255         [ $rpcs_after -eq $rpcs_before ] ||
14256                 error "$STATX should not send glimpse RPCs to $OSC"
14257 }
14258 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14259
14260 test_batch_statahead() {
14261         local max=$1
14262         local batch_max=$2
14263         local num=10000
14264         local batch_rpcs
14265         local unbatch_rpcs
14266         local hit_total
14267
14268         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14269         $LCTL set_param mdc.*.batch_stats=0
14270         $LCTL set_param llite.*.statahead_max=$max
14271         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14272         # Verify that batched statahead is faster than one without statahead
14273         test_123a_base "ls -l"
14274
14275         stack_trap "rm -rf $DIR/$tdir" EXIT
14276         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14277         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14278
14279         # unbatched statahead
14280         $LCTL set_param llite.*.statahead_batch_max=0
14281         $LCTL set_param llite.*.statahead_stats=clear
14282         $LCTL set_param mdc.*.stats=clear
14283         cancel_lru_locks mdc
14284         cancel_lru_locks osc
14285         time ls -l $DIR/$tdir | wc -l
14286         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14287         sleep 2
14288         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14289                     awk '/hit.total:/ { print $NF }')
14290         # hit ratio should be larger than 75% (7500).
14291         (( $hit_total > 7500 )) ||
14292                 error "unbatched statahead hit count ($hit_total) is too low"
14293
14294         # batched statahead
14295         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14296         $LCTL set_param llite.*.statahead_stats=clear
14297         $LCTL set_param mdc.*.batch_stats=clear
14298         $LCTL set_param mdc.*.stats=clear
14299         cancel_lru_locks mdc
14300         cancel_lru_locks osc
14301         time ls -l $DIR/$tdir | wc -l
14302         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14303         # wait for statahead thread to quit and update statahead stats
14304         sleep 2
14305         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14306                     awk '/hit.total:/ { print $NF }')
14307         # hit ratio should be larger than 75% (7500).
14308         (( $hit_total > 7500 )) ||
14309                 error "batched statahead hit count ($hit_total) is too low"
14310
14311         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14312         (( $unbatch_rpcs > $batch_rpcs )) ||
14313                 error "batched statahead does not reduce RPC count"
14314         $LCTL get_param mdc.*.batch_stats
14315 }
14316
14317 test_123ad() {
14318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14319
14320         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14321                 skip "Need server version at least 2.15.53"
14322
14323         local max
14324         local batch_max
14325
14326         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14327         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14328
14329         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14330         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14331
14332         test_batch_statahead 32 32
14333         test_batch_statahead 2048 256
14334 }
14335 run_test 123ad "Verify batching statahead works correctly"
14336
14337 test_123b () { # statahead(bug 15027)
14338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14339
14340         test_mkdir $DIR/$tdir
14341         createmany -o $DIR/$tdir/$tfile-%d 1000
14342
14343         cancel_lru_locks mdc
14344         cancel_lru_locks osc
14345
14346 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14347         lctl set_param fail_loc=0x80000803
14348         ls -lR $DIR/$tdir > /dev/null
14349         log "ls done"
14350         lctl set_param fail_loc=0x0
14351         lctl get_param -n llite.*.statahead_stats
14352         rm -r $DIR/$tdir
14353         sync
14354
14355 }
14356 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14357
14358 test_123c() {
14359         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14360
14361         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14362         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14363         touch $DIR/$tdir.1/{1..3}
14364         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14365
14366         remount_client $MOUNT
14367
14368         $MULTIOP $DIR/$tdir.0 Q
14369
14370         # let statahead to complete
14371         ls -l $DIR/$tdir.0 > /dev/null
14372
14373         testid=$(echo $TESTNAME | tr '_' ' ')
14374         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14375                 error "statahead warning" || true
14376 }
14377 run_test 123c "Can not initialize inode warning on DNE statahead"
14378
14379 test_123d() {
14380         local num=100
14381         local swrong
14382         local ewrong
14383
14384         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14385         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14386                 error "setdirstripe $DIR/$tdir failed"
14387         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14388         remount_client $MOUNT
14389         $LCTL get_param llite.*.statahead_max
14390         $LCTL set_param llite.*.statahead_stats=0 ||
14391                 error "clear statahead_stats failed"
14392         swrong=$(lctl get_param -n llite.*.statahead_stats |
14393                  awk '/statahead.wrong:/ { print $NF }')
14394         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14395         # wait for statahead thread finished to update hit/miss stats.
14396         sleep 1
14397         $LCTL get_param -n llite.*.statahead_stats
14398         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14399                  awk '/statahead.wrong:/ { print $NF }')
14400         (( $swrong == $ewrong )) ||
14401                 log "statahead was stopped, maybe too many locks held!"
14402 }
14403 run_test 123d "Statahead on striped directories works correctly"
14404
14405 test_123e() {
14406         local max
14407         local batch_max
14408         local dir=$DIR/$tdir
14409
14410         mkdir $dir || error "mkdir $dir failed"
14411         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14412         stack_trap "rm -rf $dir"
14413
14414         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14415
14416         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14417         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14418         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14419         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14420
14421         $LCTL set_param llite.*.statahead_max=2048
14422         $LCTL set_param llite.*.statahead_batch_max=1024
14423
14424         ls -l $dir
14425         $LCTL get_param mdc.*.batch_stats
14426         $LCTL get_param llite.*.statahead_*
14427 }
14428 run_test 123e "statahead with large wide striping"
14429
14430 test_123f() {
14431         local max
14432         local batch_max
14433         local dir=$DIR/$tdir
14434
14435         mkdir $dir || error "mkdir $dir failed"
14436         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14437         stack_trap "rm -rf $dir"
14438
14439         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14440
14441         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14442         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14443
14444         $LCTL set_param llite.*.statahead_max=64
14445         $LCTL set_param llite.*.statahead_batch_max=64
14446
14447         ls -l $dir
14448         lctl get_param mdc.*.batch_stats
14449         lctl get_param llite.*.statahead_*
14450
14451         $LCTL set_param llite.*.statahead_max=$max
14452         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14453 }
14454 run_test 123f "Retry mechanism with large wide striping files"
14455
14456 test_123g() {
14457         local dir=$DIR/$tdir
14458         local num=1000
14459
14460         mkdir $dir || error "failed to mkdir $dir"
14461         createmany -o $dir/$tfile $num || error "failed creatmany files"
14462         cancel_lru_locks mdc
14463         cancel_lru_locks osc
14464
14465         $LCTL set_param llite.*.statahead_stats=clear
14466         $LCTL set_param mdc.*.batch_stats=clear
14467         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14468                 error "aheadmany $dir with $tfile failed"
14469         wait_update_facet client "pgrep ll_sa" "" 35 ||
14470                 error "ll_sa thread is still running"
14471         $LCTL get_param -n llite.*.statahead_stats
14472         $LCTL get_param -n mdc.*.batch_stats
14473
14474         local count
14475
14476         count=$($LCTL get_param -n llite.*.statahead_stats |
14477                 awk '/hit.total:/ {print $2}')
14478         echo "Hit total: $count"
14479         # Hit ratio should be >= 75%
14480         (( $count > num * 75 / 100)) ||
14481                 error "hit total $count is be > 75% of $num"
14482 }
14483 run_test 123g "Test for stat-ahead advise"
14484
14485 test_124a() {
14486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14487         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14488                 skip_env "no lru resize on server"
14489
14490         local NR=2000
14491
14492         test_mkdir $DIR/$tdir
14493
14494         log "create $NR files at $DIR/$tdir"
14495         createmany -o $DIR/$tdir/f $NR ||
14496                 error "failed to create $NR files in $DIR/$tdir"
14497
14498         cancel_lru_locks mdc
14499         ls -l $DIR/$tdir > /dev/null
14500
14501         local NSDIR=""
14502         local LRU_SIZE=0
14503         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14504                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14505                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14506                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14507                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14508                         log "NSDIR=$NSDIR"
14509                         log "NS=$(basename $NSDIR)"
14510                         break
14511                 fi
14512         done
14513
14514         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14515                 skip "Not enough cached locks created!"
14516         fi
14517         log "LRU=$LRU_SIZE"
14518
14519         local SLEEP=30
14520
14521         # We know that lru resize allows one client to hold $LIMIT locks
14522         # for 10h. After that locks begin to be killed by client.
14523         local MAX_HRS=10
14524         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14525         log "LIMIT=$LIMIT"
14526         if [ $LIMIT -lt $LRU_SIZE ]; then
14527                 skip "Limit is too small $LIMIT"
14528         fi
14529
14530         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14531         # killing locks. Some time was spent for creating locks. This means
14532         # that up to the moment of sleep finish we must have killed some of
14533         # them (10-100 locks). This depends on how fast ther were created.
14534         # Many of them were touched in almost the same moment and thus will
14535         # be killed in groups.
14536         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14537
14538         # Use $LRU_SIZE_B here to take into account real number of locks
14539         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14540         local LRU_SIZE_B=$LRU_SIZE
14541         log "LVF=$LVF"
14542         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14543         log "OLD_LVF=$OLD_LVF"
14544         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14545
14546         # Let's make sure that we really have some margin. Client checks
14547         # cached locks every 10 sec.
14548         SLEEP=$((SLEEP+20))
14549         log "Sleep ${SLEEP} sec"
14550         local SEC=0
14551         while ((SEC<$SLEEP)); do
14552                 echo -n "..."
14553                 sleep 5
14554                 SEC=$((SEC+5))
14555                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14556                 echo -n "$LRU_SIZE"
14557         done
14558         echo ""
14559         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14560         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14561
14562         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14563                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14564                 unlinkmany $DIR/$tdir/f $NR
14565                 return
14566         }
14567
14568         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14569         log "unlink $NR files at $DIR/$tdir"
14570         unlinkmany $DIR/$tdir/f $NR
14571 }
14572 run_test 124a "lru resize ======================================="
14573
14574 get_max_pool_limit()
14575 {
14576         local limit=$($LCTL get_param \
14577                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14578         local max=0
14579         for l in $limit; do
14580                 if [[ $l -gt $max ]]; then
14581                         max=$l
14582                 fi
14583         done
14584         echo $max
14585 }
14586
14587 test_124b() {
14588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14589         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14590                 skip_env "no lru resize on server"
14591
14592         LIMIT=$(get_max_pool_limit)
14593
14594         NR=$(($(default_lru_size)*20))
14595         if [[ $NR -gt $LIMIT ]]; then
14596                 log "Limit lock number by $LIMIT locks"
14597                 NR=$LIMIT
14598         fi
14599
14600         IFree=$(mdsrate_inodes_available)
14601         if [ $IFree -lt $NR ]; then
14602                 log "Limit lock number by $IFree inodes"
14603                 NR=$IFree
14604         fi
14605
14606         lru_resize_disable mdc
14607         test_mkdir -p $DIR/$tdir/disable_lru_resize
14608
14609         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14610         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14611         cancel_lru_locks mdc
14612         stime=`date +%s`
14613         PID=""
14614         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14615         PID="$PID $!"
14616         sleep 2
14617         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14618         PID="$PID $!"
14619         sleep 2
14620         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14621         PID="$PID $!"
14622         wait $PID
14623         etime=`date +%s`
14624         nolruresize_delta=$((etime-stime))
14625         log "ls -la time: $nolruresize_delta seconds"
14626         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14627         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14628
14629         lru_resize_enable mdc
14630         test_mkdir -p $DIR/$tdir/enable_lru_resize
14631
14632         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14633         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14634         cancel_lru_locks mdc
14635         stime=`date +%s`
14636         PID=""
14637         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14638         PID="$PID $!"
14639         sleep 2
14640         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14641         PID="$PID $!"
14642         sleep 2
14643         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14644         PID="$PID $!"
14645         wait $PID
14646         etime=`date +%s`
14647         lruresize_delta=$((etime-stime))
14648         log "ls -la time: $lruresize_delta seconds"
14649         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14650
14651         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14652                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14653         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14654                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14655         else
14656                 log "lru resize performs the same with no lru resize"
14657         fi
14658         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14659 }
14660 run_test 124b "lru resize (performance test) ======================="
14661
14662 test_124c() {
14663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14664         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14665                 skip_env "no lru resize on server"
14666
14667         # cache ununsed locks on client
14668         local nr=100
14669         cancel_lru_locks mdc
14670         test_mkdir $DIR/$tdir
14671         createmany -o $DIR/$tdir/f $nr ||
14672                 error "failed to create $nr files in $DIR/$tdir"
14673         ls -l $DIR/$tdir > /dev/null
14674
14675         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14676         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14677         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14678         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14679         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14680
14681         # set lru_max_age to 1 sec
14682         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14683         echo "sleep $((recalc_p * 2)) seconds..."
14684         sleep $((recalc_p * 2))
14685
14686         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14687         # restore lru_max_age
14688         $LCTL set_param -n $nsdir.lru_max_age $max_age
14689         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14690         unlinkmany $DIR/$tdir/f $nr
14691 }
14692 run_test 124c "LRUR cancel very aged locks"
14693
14694 test_124d() {
14695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14696         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14697                 skip_env "no lru resize on server"
14698
14699         # cache ununsed locks on client
14700         local nr=100
14701
14702         lru_resize_disable mdc
14703         stack_trap "lru_resize_enable mdc" EXIT
14704
14705         cancel_lru_locks mdc
14706
14707         # asynchronous object destroy at MDT could cause bl ast to client
14708         test_mkdir $DIR/$tdir
14709         createmany -o $DIR/$tdir/f $nr ||
14710                 error "failed to create $nr files in $DIR/$tdir"
14711         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14712
14713         ls -l $DIR/$tdir > /dev/null
14714
14715         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14716         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14717         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14718         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14719
14720         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14721
14722         # set lru_max_age to 1 sec
14723         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14724         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14725
14726         echo "sleep $((recalc_p * 2)) seconds..."
14727         sleep $((recalc_p * 2))
14728
14729         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14730
14731         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14732 }
14733 run_test 124d "cancel very aged locks if lru-resize disabled"
14734
14735 test_125() { # 13358
14736         $LCTL get_param -n llite.*.client_type | grep -q local ||
14737                 skip "must run as local client"
14738         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14739                 skip_env "must have acl enabled"
14740         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14741         id $USER0 || skip_env "missing user $USER0"
14742
14743         test_mkdir $DIR/$tdir
14744         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14745         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14746                 error "setfacl $DIR/$tdir failed"
14747         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14748 }
14749 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14750
14751 test_126() { # bug 12829/13455
14752         $GSS && skip_env "must run as gss disabled"
14753         $LCTL get_param -n llite.*.client_type | grep -q local ||
14754                 skip "must run as local client"
14755         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14756
14757         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14758         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14759         rm -f $DIR/$tfile
14760         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14761 }
14762 run_test 126 "check that the fsgid provided by the client is taken into account"
14763
14764 test_127a() { # bug 15521
14765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14766         local name count samp unit min max sum sumsq
14767         local tmpfile=$TMP/$tfile.tmp
14768
14769         # enable stats header if it is disabled
14770         $LCTL set_param enable_stats_header=1
14771
14772         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14773         echo "stats before reset"
14774         stack_trap "rm -f $tmpfile"
14775         local now=$(date +%s)
14776
14777         $LCTL get_param osc.*.stats | tee $tmpfile
14778
14779         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14780         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14781         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14782         local uptime=$(awk '{ print $1 }' /proc/uptime)
14783
14784         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14785         (( ${snapshot_time%\.*} >= $now - 5 &&
14786            ${snapshot_time%\.*} <= $now + 5 )) ||
14787                 error "snapshot_time=$snapshot_time != now=$now"
14788         # elapsed _should_ be from mount, but at least less than uptime
14789         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14790                 error "elapsed=$elapsed > uptime=$uptime"
14791         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14792            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14793                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14794
14795         $LCTL set_param osc.*.stats=0
14796         local reset=$(date +%s)
14797         local fsize=$((2048 * 1024))
14798
14799         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14800         cancel_lru_locks osc
14801         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14802
14803         now=$(date +%s)
14804         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14805         while read name count samp unit min max sum sumsq; do
14806                 [[ "$samp" == "samples" ]] || continue
14807
14808                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14809                 [ ! $min ] && error "Missing min value for $name proc entry"
14810                 eval $name=$count || error "Wrong proc format"
14811
14812                 case $name in
14813                 read_bytes|write_bytes)
14814                         [[ "$unit" =~ "bytes" ]] ||
14815                                 error "unit is not 'bytes': $unit"
14816                         (( $min >= 4096 )) || error "min is too small: $min"
14817                         (( $min <= $fsize )) || error "min is too big: $min"
14818                         (( $max >= 4096 )) || error "max is too small: $max"
14819                         (( $max <= $fsize )) || error "max is too big: $max"
14820                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14821                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14822                                 error "sumsquare is too small: $sumsq"
14823                         (( $sumsq <= $fsize * $fsize )) ||
14824                                 error "sumsquare is too big: $sumsq"
14825                         ;;
14826                 ost_read|ost_write)
14827                         [[ "$unit" =~ "usec" ]] ||
14828                                 error "unit is not 'usec': $unit"
14829                         ;;
14830                 *)      ;;
14831                 esac
14832         done < $tmpfile
14833
14834         #check that we actually got some stats
14835         [ "$read_bytes" ] || error "Missing read_bytes stats"
14836         [ "$write_bytes" ] || error "Missing write_bytes stats"
14837         [ "$read_bytes" != 0 ] || error "no read done"
14838         [ "$write_bytes" != 0 ] || error "no write done"
14839
14840         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14841         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14842         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14843
14844         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14845         (( ${snapshot_time%\.*} >= $now - 5 &&
14846            ${snapshot_time%\.*} <= $now + 5 )) ||
14847                 error "reset snapshot_time=$snapshot_time != now=$now"
14848         # elapsed should be from time of stats reset
14849         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14850            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14851                 error "reset elapsed=$elapsed > $now - $reset"
14852         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14853            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14854                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14855 }
14856 run_test 127a "verify the client stats are sane"
14857
14858 test_127b() { # bug LU-333
14859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14860         local name count samp unit min max sum sumsq
14861
14862         echo "stats before reset"
14863         $LCTL get_param llite.*.stats
14864         $LCTL set_param llite.*.stats=0
14865
14866         # perform 2 reads and writes so MAX is different from SUM.
14867         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14868         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14869         cancel_lru_locks osc
14870         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14871         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14872
14873         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14874         stack_trap "rm -f $TMP/$tfile.tmp"
14875         while read name count samp unit min max sum sumsq; do
14876                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14877                 eval $name=$count || error "Wrong proc format"
14878
14879                 case $name in
14880                 read_bytes|write_bytes)
14881                         [[ "$unit" =~ "bytes" ]] ||
14882                                 error "unit is not 'bytes': $unit"
14883                         (( $count == 2 )) || error "count is not 2: $count"
14884                         (( $min == $PAGE_SIZE )) ||
14885                                 error "min is not $PAGE_SIZE: $min"
14886                         (( $max == $PAGE_SIZE )) ||
14887                                 error "max is not $PAGE_SIZE: $max"
14888                         (( $sum == $PAGE_SIZE * 2 )) ||
14889                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14890                         ;;
14891                 read|write)
14892                         [[ "$unit" =~ "usec" ]] ||
14893                                 error "unit is not 'usec': $unit"
14894                         ;;
14895                 *)      ;;
14896                 esac
14897         done < $TMP/$tfile.tmp
14898
14899         #check that we actually got some stats
14900         [ "$read_bytes" ] || error "Missing read_bytes stats"
14901         [ "$write_bytes" ] || error "Missing write_bytes stats"
14902         [ "$read_bytes" != 0 ] || error "no read done"
14903         [ "$write_bytes" != 0 ] || error "no write done"
14904 }
14905 run_test 127b "verify the llite client stats are sane"
14906
14907 test_127c() { # LU-12394
14908         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14909         local size
14910         local bsize
14911         local reads
14912         local writes
14913         local count
14914
14915         $LCTL set_param llite.*.extents_stats=1
14916         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14917
14918         # Use two stripes so there is enough space in default config
14919         $LFS setstripe -c 2 $DIR/$tfile
14920
14921         # Extent stats start at 0-4K and go in power of two buckets
14922         # LL_HIST_START = 12 --> 2^12 = 4K
14923         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14924         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14925         # small configs
14926         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14927                 do
14928                 # Write and read, 2x each, second time at a non-zero offset
14929                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14930                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14931                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14932                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14933                 rm -f $DIR/$tfile
14934         done
14935
14936         $LCTL get_param llite.*.extents_stats
14937
14938         count=2
14939         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14940                 do
14941                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14942                                 grep -m 1 $bsize)
14943                 reads=$(echo $bucket | awk '{print $5}')
14944                 writes=$(echo $bucket | awk '{print $9}')
14945                 [ "$reads" -eq $count ] ||
14946                         error "$reads reads in < $bsize bucket, expect $count"
14947                 [ "$writes" -eq $count ] ||
14948                         error "$writes writes in < $bsize bucket, expect $count"
14949         done
14950
14951         # Test mmap write and read
14952         $LCTL set_param llite.*.extents_stats=c
14953         size=512
14954         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14955         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14956         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14957
14958         $LCTL get_param llite.*.extents_stats
14959
14960         count=$(((size*1024) / PAGE_SIZE))
14961
14962         bsize=$((2 * PAGE_SIZE / 1024))K
14963
14964         bucket=$($LCTL get_param -n llite.*.extents_stats |
14965                         grep -m 1 $bsize)
14966         reads=$(echo $bucket | awk '{print $5}')
14967         writes=$(echo $bucket | awk '{print $9}')
14968         # mmap writes fault in the page first, creating an additonal read
14969         [ "$reads" -eq $((2 * count)) ] ||
14970                 error "$reads reads in < $bsize bucket, expect $count"
14971         [ "$writes" -eq $count ] ||
14972                 error "$writes writes in < $bsize bucket, expect $count"
14973 }
14974 run_test 127c "test llite extent stats with regular & mmap i/o"
14975
14976 test_128() { # bug 15212
14977         touch $DIR/$tfile
14978         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14979                 find $DIR/$tfile
14980                 find $DIR/$tfile
14981         EOF
14982
14983         result=$(grep error $TMP/$tfile.log)
14984         rm -f $DIR/$tfile $TMP/$tfile.log
14985         [ -z "$result" ] ||
14986                 error "consecutive find's under interactive lfs failed"
14987 }
14988 run_test 128 "interactive lfs for 2 consecutive find's"
14989
14990 set_dir_limits () {
14991         local mntdev
14992         local canondev
14993         local node
14994
14995         local ldproc=/proc/fs/ldiskfs
14996         local facets=$(get_facets MDS)
14997
14998         for facet in ${facets//,/ }; do
14999                 canondev=$(ldiskfs_canon \
15000                            *.$(convert_facet2label $facet).mntdev $facet)
15001                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15002                         ldproc=/sys/fs/ldiskfs
15003                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15004                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15005         done
15006 }
15007
15008 check_mds_dmesg() {
15009         local facets=$(get_facets MDS)
15010         for facet in ${facets//,/ }; do
15011                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15012         done
15013         return 1
15014 }
15015
15016 test_129() {
15017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15018         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15019                 skip "Need MDS version with at least 2.5.56"
15020         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15021                 skip_env "ldiskfs only test"
15022         fi
15023         remote_mds_nodsh && skip "remote MDS with nodsh"
15024
15025         local ENOSPC=28
15026         local has_warning=false
15027
15028         rm -rf $DIR/$tdir
15029         mkdir -p $DIR/$tdir
15030
15031         # block size of mds1
15032         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15033         set_dir_limits $maxsize $((maxsize * 6 / 8))
15034         stack_trap "set_dir_limits 0 0"
15035         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15036         local dirsize=$(stat -c%s "$DIR/$tdir")
15037         local nfiles=0
15038         while (( $dirsize <= $maxsize )); do
15039                 $MCREATE $DIR/$tdir/file_base_$nfiles
15040                 rc=$?
15041                 # check two errors:
15042                 # ENOSPC for ext4 max_dir_size, which has been used since
15043                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15044                 if (( rc == ENOSPC )); then
15045                         set_dir_limits 0 0
15046                         echo "rc=$rc returned as expected after $nfiles files"
15047
15048                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15049                                 error "create failed w/o dir size limit"
15050
15051                         # messages may be rate limited if test is run repeatedly
15052                         check_mds_dmesg '"is approaching max"' ||
15053                                 echo "warning message should be output"
15054                         check_mds_dmesg '"has reached max"' ||
15055                                 echo "reached message should be output"
15056
15057                         dirsize=$(stat -c%s "$DIR/$tdir")
15058
15059                         [[ $dirsize -ge $maxsize ]] && return 0
15060                         error "dirsize $dirsize < $maxsize after $nfiles files"
15061                 elif (( rc != 0 )); then
15062                         break
15063                 fi
15064                 nfiles=$((nfiles + 1))
15065                 dirsize=$(stat -c%s "$DIR/$tdir")
15066         done
15067
15068         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15069 }
15070 run_test 129 "test directory size limit ========================"
15071
15072 OLDIFS="$IFS"
15073 cleanup_130() {
15074         trap 0
15075         IFS="$OLDIFS"
15076         rm -f $DIR/$tfile
15077 }
15078
15079 test_130a() {
15080         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15081         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15082
15083         trap cleanup_130 EXIT RETURN
15084
15085         local fm_file=$DIR/$tfile
15086         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15087         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15088                 error "dd failed for $fm_file"
15089
15090         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15091         filefrag -ves $fm_file
15092         local rc=$?
15093         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15094                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15095         (( $rc == 0 )) || error "filefrag $fm_file failed"
15096
15097         filefrag_op=$(filefrag -ve -k $fm_file |
15098                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15099         local lun=$($LFS getstripe -i $fm_file)
15100
15101         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15102         IFS=$'\n'
15103         local tot_len=0
15104         for line in $filefrag_op; do
15105                 local frag_lun=$(echo $line | cut -d: -f5)
15106                 local ext_len=$(echo $line | cut -d: -f4)
15107
15108                 if (( $frag_lun != $lun )); then
15109                         error "FIEMAP on 1-stripe file($fm_file) failed"
15110                         return
15111                 fi
15112                 (( tot_len += ext_len ))
15113         done
15114
15115         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15116                 error "FIEMAP on 1-stripe file($fm_file) failed"
15117                 return
15118         fi
15119
15120         echo "FIEMAP on single striped file succeeded"
15121 }
15122 run_test 130a "FIEMAP (1-stripe file)"
15123
15124 test_130b() {
15125         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15126
15127         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15128         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15129         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15130                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15131
15132         trap cleanup_130 EXIT RETURN
15133
15134         local fm_file=$DIR/$tfile
15135         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15136                 error "setstripe on $fm_file"
15137
15138         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15139                 error "dd failed on $fm_file"
15140
15141         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15142         filefrag_op=$(filefrag -ve -k $fm_file |
15143                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15144
15145         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15146                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15147
15148         IFS=$'\n'
15149         local tot_len=0
15150         local num_luns=1
15151
15152         for line in $filefrag_op; do
15153                 local frag_lun=$(echo $line | cut -d: -f5 |
15154                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15155                 local ext_len=$(echo $line | cut -d: -f4)
15156                 if (( $frag_lun != $last_lun )); then
15157                         if (( tot_len != 1024 )); then
15158                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15159                                 return
15160                         else
15161                                 (( num_luns += 1 ))
15162                                 tot_len=0
15163                         fi
15164                 fi
15165                 (( tot_len += ext_len ))
15166                 last_lun=$frag_lun
15167         done
15168         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15169                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15170                 return
15171         fi
15172
15173         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15174 }
15175 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15176
15177 test_130c() {
15178         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15179
15180         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15181         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15182         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15183                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15184
15185         trap cleanup_130 EXIT RETURN
15186
15187         local fm_file=$DIR/$tfile
15188         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15189
15190         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15191                 error "dd failed on $fm_file"
15192
15193         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15194         filefrag_op=$(filefrag -ve -k $fm_file |
15195                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15196
15197         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15198                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15199
15200         IFS=$'\n'
15201         local tot_len=0
15202         local num_luns=1
15203         for line in $filefrag_op; do
15204                 local frag_lun=$(echo $line | cut -d: -f5 |
15205                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15206                 local ext_len=$(echo $line | cut -d: -f4)
15207                 if (( $frag_lun != $last_lun )); then
15208                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15209                         if (( logical != 512 )); then
15210                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15211                                 return
15212                         fi
15213                         if (( tot_len != 512 )); then
15214                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15215                                 return
15216                         else
15217                                 (( num_luns += 1 ))
15218                                 tot_len=0
15219                         fi
15220                 fi
15221                 (( tot_len += ext_len ))
15222                 last_lun=$frag_lun
15223         done
15224         if (( num_luns != 2 || tot_len != 512 )); then
15225                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15226                 return
15227         fi
15228
15229         echo "FIEMAP on 2-stripe file with hole succeeded"
15230 }
15231 run_test 130c "FIEMAP (2-stripe file with hole)"
15232
15233 test_130d() {
15234         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15235
15236         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15237         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15238         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15239                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15240
15241         trap cleanup_130 EXIT RETURN
15242
15243         local fm_file=$DIR/$tfile
15244         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15245                         error "setstripe on $fm_file"
15246
15247         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15248         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15249                 error "dd failed on $fm_file"
15250
15251         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15252         filefrag_op=$(filefrag -ve -k $fm_file |
15253                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15254
15255         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15256                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15257
15258         IFS=$'\n'
15259         local tot_len=0
15260         local num_luns=1
15261         for line in $filefrag_op; do
15262                 local frag_lun=$(echo $line | cut -d: -f5 |
15263                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15264                 local ext_len=$(echo $line | cut -d: -f4)
15265                 if (( $frag_lun != $last_lun )); then
15266                         if (( tot_len != 1024 )); then
15267                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15268                                 return
15269                         else
15270                                 (( num_luns += 1 ))
15271                                 local tot_len=0
15272                         fi
15273                 fi
15274                 (( tot_len += ext_len ))
15275                 last_lun=$frag_lun
15276         done
15277         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15278                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15279                 return
15280         fi
15281
15282         echo "FIEMAP on N-stripe file succeeded"
15283 }
15284 run_test 130d "FIEMAP (N-stripe file)"
15285
15286 test_130e() {
15287         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15288
15289         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15290         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15291         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15292                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15293
15294         trap cleanup_130 EXIT RETURN
15295
15296         local fm_file=$DIR/$tfile
15297         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15298         stack_trap "rm -f $fm_file"
15299
15300         local num_blks=512
15301         local expected_len=$(( (num_blks / 2) * 64 ))
15302         for ((i = 0; i < $num_blks; i++)); do
15303                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15304                         conv=notrunc > /dev/null 2>&1
15305         done
15306
15307         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15308         filefrag_op=$(filefrag -ve -k $fm_file |
15309                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15310
15311         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15312
15313         IFS=$'\n'
15314         local tot_len=0
15315         local num_luns=1
15316         for line in $filefrag_op; do
15317                 local frag_lun=$(echo $line | cut -d: -f5)
15318                 local ext_len=$(echo $line | cut -d: -f4)
15319                 if (( $frag_lun != $last_lun )); then
15320                         if (( tot_len != $expected_len )); then
15321                                 error "OST$last_lun $tot_len != $expected_len"
15322                         else
15323                                 (( num_luns += 1 ))
15324                                 tot_len=0
15325                         fi
15326                 fi
15327                 (( tot_len += ext_len ))
15328                 last_lun=$frag_lun
15329         done
15330         if (( num_luns != 2 || tot_len != $expected_len )); then
15331                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15332         fi
15333
15334         echo "FIEMAP with continuation calls succeeded"
15335 }
15336 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15337
15338 test_130f() {
15339         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15340         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15341         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15342                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15343
15344         local fm_file=$DIR/$tfile
15345         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15346                 error "multiop create with lov_delay_create on $fm_file"
15347
15348         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15349         filefrag_extents=$(filefrag -vek $fm_file |
15350                            awk '/extents? found/ { print $2 }')
15351         if (( $filefrag_extents != 0 )); then
15352                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15353         fi
15354
15355         rm -f $fm_file
15356 }
15357 run_test 130f "FIEMAP (unstriped file)"
15358
15359 test_130g() {
15360         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15361                 skip "Need MDS version with at least 2.12.53 for overstriping"
15362         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15363         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15364         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15365                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15366
15367         local file=$DIR/$tfile
15368         local nr=$((OSTCOUNT * 100))
15369
15370         $LFS setstripe -C $nr -S1M $file ||
15371                 error "failed to setstripe -C $nr $file"
15372
15373         stack_trap "rm -f $file"
15374         dd if=/dev/zero of=$file count=$nr bs=1M
15375         sync
15376         nr=$($LFS getstripe -c $file)
15377
15378         local extents=$(filefrag -v $file |
15379                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15380
15381         echo "filefrag list $extents extents in file with stripecount $nr"
15382         if (( extents < nr )); then
15383                 $LFS getstripe $file
15384                 filefrag -v $file
15385                 error "filefrag printed $extents < $nr extents"
15386         fi
15387 }
15388 run_test 130g "FIEMAP (overstripe file)"
15389
15390 # Test for writev/readv
15391 test_131a() {
15392         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15393                 error "writev test failed"
15394         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15395                 error "readv failed"
15396         rm -f $DIR/$tfile
15397 }
15398 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15399
15400 test_131b() {
15401         local fsize=$((524288 + 1048576 + 1572864))
15402         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15403                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15404                         error "append writev test failed"
15405
15406         ((fsize += 1572864 + 1048576))
15407         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15408                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15409                         error "append writev test failed"
15410         rm -f $DIR/$tfile
15411 }
15412 run_test 131b "test append writev"
15413
15414 test_131c() {
15415         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15416         error "NOT PASS"
15417 }
15418 run_test 131c "test read/write on file w/o objects"
15419
15420 test_131d() {
15421         rwv -f $DIR/$tfile -w -n 1 1572864
15422         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15423         if [ "$NOB" != 1572864 ]; then
15424                 error "Short read filed: read $NOB bytes instead of 1572864"
15425         fi
15426         rm -f $DIR/$tfile
15427 }
15428 run_test 131d "test short read"
15429
15430 test_131e() {
15431         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15432         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15433         error "read hitting hole failed"
15434         rm -f $DIR/$tfile
15435 }
15436 run_test 131e "test read hitting hole"
15437
15438 check_stats() {
15439         local facet=$1
15440         local op=$2
15441         local want=${3:-0}
15442         local res
15443
15444         # open             11 samples [usecs] 468 4793 13658 35791898
15445         case $facet in
15446         mds*) res=($(do_facet $facet \
15447                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15448                  ;;
15449         ost*) res=($(do_facet $facet \
15450                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15451                  ;;
15452         *) error "Wrong facet '$facet'" ;;
15453         esac
15454         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15455         # if $want is zero, it means any stat increment is ok.
15456         if (( $want > 0 )); then
15457                 local count=${res[1]}
15458
15459                 if (( $count != $want )); then
15460                         if [[ $facet =~ "mds" ]]; then
15461                                 do_nodes $(comma_list $(mdts_nodes)) \
15462                                         $LCTL get_param mdt.*.md_stats
15463                         else
15464                                 do_nodes $(comma_list $(osts-nodes)) \
15465                                         $LCTL get_param obdfilter.*.stats
15466                         fi
15467                         error "The $op counter on $facet is $count, not $want"
15468                 fi
15469         fi
15470 }
15471
15472 test_133a() {
15473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15474         remote_ost_nodsh && skip "remote OST with nodsh"
15475         remote_mds_nodsh && skip "remote MDS with nodsh"
15476         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15477                 skip_env "MDS doesn't support rename stats"
15478
15479         local testdir=$DIR/${tdir}/stats_testdir
15480
15481         mkdir -p $DIR/${tdir}
15482
15483         # clear stats.
15484         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15485         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15486
15487         # verify mdt stats first.
15488         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15489         check_stats $SINGLEMDS "mkdir" 1
15490
15491         # clear "open" from "lfs mkdir" above
15492         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15493         touch ${testdir}/${tfile} || error "touch failed"
15494         check_stats $SINGLEMDS "open" 1
15495         check_stats $SINGLEMDS "close" 1
15496         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15497                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15498                 check_stats $SINGLEMDS "mknod" 2
15499         }
15500         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15501         check_stats $SINGLEMDS "unlink" 1
15502         rm -f ${testdir}/${tfile} || error "file remove failed"
15503         check_stats $SINGLEMDS "unlink" 2
15504
15505         # remove working dir and check mdt stats again.
15506         rmdir ${testdir} || error "rmdir failed"
15507         check_stats $SINGLEMDS "rmdir" 1
15508
15509         local testdir1=$DIR/${tdir}/stats_testdir1
15510         mkdir_on_mdt0 -p ${testdir}
15511         mkdir_on_mdt0 -p ${testdir1}
15512         touch ${testdir1}/test1
15513         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15514         check_stats $SINGLEMDS "crossdir_rename" 1
15515
15516         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15517         check_stats $SINGLEMDS "samedir_rename" 1
15518
15519         rm -rf $DIR/${tdir}
15520 }
15521 run_test 133a "Verifying MDT stats ========================================"
15522
15523 test_133b() {
15524         local res
15525
15526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15527         remote_ost_nodsh && skip "remote OST with nodsh"
15528         remote_mds_nodsh && skip "remote MDS with nodsh"
15529
15530         local testdir=$DIR/${tdir}/stats_testdir
15531
15532         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15533         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15534         touch ${testdir}/${tfile} || error "touch failed"
15535         cancel_lru_locks mdc
15536
15537         # clear stats.
15538         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15539         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15540
15541         # extra mdt stats verification.
15542         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15543         check_stats $SINGLEMDS "setattr" 1
15544         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15545         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15546         then            # LU-1740
15547                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15548                 check_stats $SINGLEMDS "getattr" 1
15549         fi
15550         rm -rf $DIR/${tdir}
15551
15552         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15553         # so the check below is not reliable
15554         [ $MDSCOUNT -eq 1 ] || return 0
15555
15556         # Sleep to avoid a cached response.
15557         #define OBD_STATFS_CACHE_SECONDS 1
15558         sleep 2
15559         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15560         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15561         $LFS df || error "lfs failed"
15562         check_stats $SINGLEMDS "statfs" 1
15563
15564         # check aggregated statfs (LU-10018)
15565         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15566                 return 0
15567         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15568                 return 0
15569         sleep 2
15570         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15571         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15572         df $DIR
15573         check_stats $SINGLEMDS "statfs" 1
15574
15575         # We want to check that the client didn't send OST_STATFS to
15576         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15577         # extra care is needed here.
15578         if remote_mds; then
15579                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15580                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15581
15582                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15583                 [ "$res" ] && error "OST got STATFS"
15584         fi
15585
15586         return 0
15587 }
15588 run_test 133b "Verifying extra MDT stats =================================="
15589
15590 test_133c() {
15591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15592         remote_ost_nodsh && skip "remote OST with nodsh"
15593         remote_mds_nodsh && skip "remote MDS with nodsh"
15594
15595         local testdir=$DIR/$tdir/stats_testdir
15596
15597         test_mkdir -p $testdir
15598
15599         # verify obdfilter stats.
15600         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15601         sync
15602         cancel_lru_locks osc
15603         wait_delete_completed
15604
15605         # clear stats.
15606         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15607         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15608
15609         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15610                 error "dd failed"
15611         sync
15612         cancel_lru_locks osc
15613         check_stats ost1 "write" 1
15614
15615         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15616         check_stats ost1 "read" 1
15617
15618         > $testdir/$tfile || error "truncate failed"
15619         check_stats ost1 "punch" 1
15620
15621         rm -f $testdir/$tfile || error "file remove failed"
15622         wait_delete_completed
15623         check_stats ost1 "destroy" 1
15624
15625         rm -rf $DIR/$tdir
15626 }
15627 run_test 133c "Verifying OST stats ========================================"
15628
15629 order_2() {
15630         local value=$1
15631         local orig=$value
15632         local order=1
15633
15634         while [ $value -ge 2 ]; do
15635                 order=$((order*2))
15636                 value=$((value/2))
15637         done
15638
15639         if [ $orig -gt $order ]; then
15640                 order=$((order*2))
15641         fi
15642         echo $order
15643 }
15644
15645 size_in_KMGT() {
15646     local value=$1
15647     local size=('K' 'M' 'G' 'T');
15648     local i=0
15649     local size_string=$value
15650
15651     while [ $value -ge 1024 ]; do
15652         if [ $i -gt 3 ]; then
15653             #T is the biggest unit we get here, if that is bigger,
15654             #just return XXXT
15655             size_string=${value}T
15656             break
15657         fi
15658         value=$((value >> 10))
15659         if [ $value -lt 1024 ]; then
15660             size_string=${value}${size[$i]}
15661             break
15662         fi
15663         i=$((i + 1))
15664     done
15665
15666     echo $size_string
15667 }
15668
15669 get_rename_size() {
15670         local size=$1
15671         local context=${2:-.}
15672         local sample=$(do_facet $SINGLEMDS $LCTL \
15673                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15674                 grep -A1 $context |
15675                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15676         echo $sample
15677 }
15678
15679 test_133d() {
15680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15681         remote_ost_nodsh && skip "remote OST with nodsh"
15682         remote_mds_nodsh && skip "remote MDS with nodsh"
15683         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15684                 skip_env "MDS doesn't support rename stats"
15685
15686         local testdir1=$DIR/${tdir}/stats_testdir1
15687         local testdir2=$DIR/${tdir}/stats_testdir2
15688         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15689
15690         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15691
15692         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15693         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15694
15695         createmany -o $testdir1/test 512 || error "createmany failed"
15696
15697         # check samedir rename size
15698         mv ${testdir1}/test0 ${testdir1}/test_0
15699
15700         local testdir1_size=$(ls -l $DIR/${tdir} |
15701                 awk '/stats_testdir1/ {print $5}')
15702         local testdir2_size=$(ls -l $DIR/${tdir} |
15703                 awk '/stats_testdir2/ {print $5}')
15704
15705         testdir1_size=$(order_2 $testdir1_size)
15706         testdir2_size=$(order_2 $testdir2_size)
15707
15708         testdir1_size=$(size_in_KMGT $testdir1_size)
15709         testdir2_size=$(size_in_KMGT $testdir2_size)
15710
15711         echo "source rename dir size: ${testdir1_size}"
15712         echo "target rename dir size: ${testdir2_size}"
15713
15714         local cmd="do_facet $SINGLEMDS $LCTL "
15715         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15716
15717         eval $cmd || error "$cmd failed"
15718         local samedir=$($cmd | grep 'same_dir')
15719         local same_sample=$(get_rename_size $testdir1_size)
15720         [ -z "$samedir" ] && error "samedir_rename_size count error"
15721         [[ $same_sample -eq 1 ]] ||
15722                 error "samedir_rename_size error $same_sample"
15723         echo "Check same dir rename stats success"
15724
15725         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15726
15727         # check crossdir rename size
15728         mv ${testdir1}/test_0 ${testdir2}/test_0
15729
15730         testdir1_size=$(ls -l $DIR/${tdir} |
15731                 awk '/stats_testdir1/ {print $5}')
15732         testdir2_size=$(ls -l $DIR/${tdir} |
15733                 awk '/stats_testdir2/ {print $5}')
15734
15735         testdir1_size=$(order_2 $testdir1_size)
15736         testdir2_size=$(order_2 $testdir2_size)
15737
15738         testdir1_size=$(size_in_KMGT $testdir1_size)
15739         testdir2_size=$(size_in_KMGT $testdir2_size)
15740
15741         echo "source rename dir size: ${testdir1_size}"
15742         echo "target rename dir size: ${testdir2_size}"
15743
15744         eval $cmd || error "$cmd failed"
15745         local crossdir=$($cmd | grep 'crossdir')
15746         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15747         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15748         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15749         [[ $src_sample -eq 1 ]] ||
15750                 error "crossdir_rename_size error $src_sample"
15751         [[ $tgt_sample -eq 1 ]] ||
15752                 error "crossdir_rename_size error $tgt_sample"
15753         echo "Check cross dir rename stats success"
15754         rm -rf $DIR/${tdir}
15755 }
15756 run_test 133d "Verifying rename_stats ========================================"
15757
15758 test_133e() {
15759         remote_mds_nodsh && skip "remote MDS with nodsh"
15760         remote_ost_nodsh && skip "remote OST with nodsh"
15761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15762
15763         local testdir=$DIR/${tdir}/stats_testdir
15764         local ctr f0 f1 bs=32768 count=42 sum
15765
15766         mkdir -p ${testdir} || error "mkdir failed"
15767
15768         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15769
15770         for ctr in {write,read}_bytes; do
15771                 sync
15772                 cancel_lru_locks osc
15773
15774                 do_facet ost1 $LCTL set_param -n \
15775                         "obdfilter.*.exports.clear=clear"
15776
15777                 if [ $ctr = write_bytes ]; then
15778                         f0=/dev/zero
15779                         f1=${testdir}/${tfile}
15780                 else
15781                         f0=${testdir}/${tfile}
15782                         f1=/dev/null
15783                 fi
15784
15785                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15786                         error "dd failed"
15787                 sync
15788                 cancel_lru_locks osc
15789
15790                 sum=$(do_facet ost1 $LCTL get_param \
15791                         "obdfilter.*.exports.*.stats" |
15792                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15793                                 $1 == ctr { sum += $7 }
15794                                 END { printf("%0.0f", sum) }')
15795
15796                 if ((sum != bs * count)); then
15797                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15798                 fi
15799         done
15800
15801         rm -rf $DIR/${tdir}
15802 }
15803 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15804
15805 test_133f() {
15806         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15807                 skip "too old lustre for get_param -R ($facet_ver)"
15808
15809         # verifying readability.
15810         $LCTL get_param -R '*' &> /dev/null
15811
15812         # Verifing writability with badarea_io.
15813         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15814         local skipped_params='force_lbug|changelog_mask|daemon_file'
15815         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15816                 egrep -v "$skipped_params" |
15817                 xargs -n 1 find $proc_dirs -name |
15818                 xargs -n 1 badarea_io ||
15819                 error "client badarea_io failed"
15820
15821         # remount the FS in case writes/reads /proc break the FS
15822         cleanup || error "failed to unmount"
15823         setup || error "failed to setup"
15824 }
15825 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15826
15827 test_133g() {
15828         remote_mds_nodsh && skip "remote MDS with nodsh"
15829         remote_ost_nodsh && skip "remote OST with nodsh"
15830
15831         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15832         local proc_dirs_str=$(eval echo $proc_dirs)
15833         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15834         local facet
15835         for facet in mds1 ost1; do
15836                 local facet_ver=$(lustre_version_code $facet)
15837                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15838                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15839                 else
15840                         log "$facet: too old lustre for get_param -R"
15841                 fi
15842                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15843                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15844                                 tr -d = | egrep -v $skipped_params |
15845                                 xargs -n 1 find $proc_dirs_str -name |
15846                                 xargs -n 1 badarea_io" ||
15847                                         error "$facet badarea_io failed"
15848                 else
15849                         skip_noexit "$facet: too old lustre for get_param -R"
15850                 fi
15851         done
15852
15853         # remount the FS in case writes/reads /proc break the FS
15854         cleanup || error "failed to unmount"
15855         setup || error "failed to setup"
15856 }
15857 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15858
15859 test_133h() {
15860         remote_mds_nodsh && skip "remote MDS with nodsh"
15861         remote_ost_nodsh && skip "remote OST with nodsh"
15862         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15863                 skip "Need MDS version at least 2.9.54"
15864
15865         local facet
15866         for facet in client mds1 ost1; do
15867                 # Get the list of files that are missing the terminating newline
15868                 local plist=$(do_facet $facet
15869                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15870                 local ent
15871                 for ent in $plist; do
15872                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15873                                 awk -v FS='\v' -v RS='\v\v' \
15874                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15875                                         print FILENAME}'" 2>/dev/null)
15876                         [ -z $missing ] || {
15877                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15878                                 error "file does not end with newline: $facet-$ent"
15879                         }
15880                 done
15881         done
15882 }
15883 run_test 133h "Proc files should end with newlines"
15884
15885 test_134a() {
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15888                 skip "Need MDS version at least 2.7.54"
15889
15890         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15891         cancel_lru_locks mdc
15892
15893         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15894         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15895         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15896
15897         local nr=1000
15898         createmany -o $DIR/$tdir/f $nr ||
15899                 error "failed to create $nr files in $DIR/$tdir"
15900         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15901
15902         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15903         do_facet mds1 $LCTL set_param fail_loc=0x327
15904         do_facet mds1 $LCTL set_param fail_val=500
15905         touch $DIR/$tdir/m
15906
15907         echo "sleep 10 seconds ..."
15908         sleep 10
15909         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15910
15911         do_facet mds1 $LCTL set_param fail_loc=0
15912         do_facet mds1 $LCTL set_param fail_val=0
15913         [ $lck_cnt -lt $unused ] ||
15914                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15915
15916         rm $DIR/$tdir/m
15917         unlinkmany $DIR/$tdir/f $nr
15918 }
15919 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15920
15921 test_134b() {
15922         remote_mds_nodsh && skip "remote MDS with nodsh"
15923         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15924                 skip "Need MDS version at least 2.7.54"
15925
15926         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15927         cancel_lru_locks mdc
15928
15929         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15930                         ldlm.lock_reclaim_threshold_mb)
15931         # disable reclaim temporarily
15932         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15933
15934         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15935         do_facet mds1 $LCTL set_param fail_loc=0x328
15936         do_facet mds1 $LCTL set_param fail_val=500
15937
15938         $LCTL set_param debug=+trace
15939
15940         local nr=600
15941         createmany -o $DIR/$tdir/f $nr &
15942         local create_pid=$!
15943
15944         echo "Sleep $TIMEOUT seconds ..."
15945         sleep $TIMEOUT
15946         if ! ps -p $create_pid  > /dev/null 2>&1; then
15947                 do_facet mds1 $LCTL set_param fail_loc=0
15948                 do_facet mds1 $LCTL set_param fail_val=0
15949                 do_facet mds1 $LCTL set_param \
15950                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15951                 error "createmany finished incorrectly!"
15952         fi
15953         do_facet mds1 $LCTL set_param fail_loc=0
15954         do_facet mds1 $LCTL set_param fail_val=0
15955         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15956         wait $create_pid || return 1
15957
15958         unlinkmany $DIR/$tdir/f $nr
15959 }
15960 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15961
15962 test_135() {
15963         remote_mds_nodsh && skip "remote MDS with nodsh"
15964         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15965                 skip "Need MDS version at least 2.13.50"
15966         local fname
15967
15968         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15969
15970 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15971         #set only one record at plain llog
15972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15973
15974         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15975
15976         #fill already existed plain llog each 64767
15977         #wrapping whole catalog
15978         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15979
15980         createmany -o $DIR/$tdir/$tfile_ 64700
15981         for (( i = 0; i < 64700; i = i + 2 ))
15982         do
15983                 rm $DIR/$tdir/$tfile_$i &
15984                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15985                 local pid=$!
15986                 wait $pid
15987         done
15988
15989         #waiting osp synchronization
15990         wait_delete_completed
15991 }
15992 run_test 135 "Race catalog processing"
15993
15994 test_136() {
15995         remote_mds_nodsh && skip "remote MDS with nodsh"
15996         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15997                 skip "Need MDS version at least 2.13.50"
15998         local fname
15999
16000         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16001         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16002         #set only one record at plain llog
16003 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16004         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16005
16006         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16007
16008         #fill already existed 2 plain llogs each 64767
16009         #wrapping whole catalog
16010         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16011         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16012         wait_delete_completed
16013
16014         createmany -o $DIR/$tdir/$tfile_ 10
16015         sleep 25
16016
16017         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16018         for (( i = 0; i < 10; i = i + 3 ))
16019         do
16020                 rm $DIR/$tdir/$tfile_$i &
16021                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16022                 local pid=$!
16023                 wait $pid
16024                 sleep 7
16025                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16026         done
16027
16028         #waiting osp synchronization
16029         wait_delete_completed
16030 }
16031 run_test 136 "Race catalog processing 2"
16032
16033 test_140() { #bug-17379
16034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16035
16036         test_mkdir $DIR/$tdir
16037         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16038         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16039
16040         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16041         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16042         local i=0
16043         while i=$((i + 1)); do
16044                 test_mkdir $i
16045                 cd $i || error "Changing to $i"
16046                 ln -s ../stat stat || error "Creating stat symlink"
16047                 # Read the symlink until ELOOP present,
16048                 # not LBUGing the system is considered success,
16049                 # we didn't overrun the stack.
16050                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16051                 if [ $ret -ne 0 ]; then
16052                         if [ $ret -eq 40 ]; then
16053                                 break  # -ELOOP
16054                         else
16055                                 error "Open stat symlink"
16056                                         return
16057                         fi
16058                 fi
16059         done
16060         i=$((i - 1))
16061         echo "The symlink depth = $i"
16062         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16063                 error "Invalid symlink depth"
16064
16065         # Test recursive symlink
16066         ln -s symlink_self symlink_self
16067         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16068         echo "open symlink_self returns $ret"
16069         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16070 }
16071 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16072
16073 test_150a() {
16074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16075
16076         local TF="$TMP/$tfile"
16077
16078         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16079         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16080         cp $TF $DIR/$tfile
16081         cancel_lru_locks $OSC
16082         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16083         remount_client $MOUNT
16084         df -P $MOUNT
16085         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16086
16087         $TRUNCATE $TF 6000
16088         $TRUNCATE $DIR/$tfile 6000
16089         cancel_lru_locks $OSC
16090         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16091
16092         echo "12345" >>$TF
16093         echo "12345" >>$DIR/$tfile
16094         cancel_lru_locks $OSC
16095         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16096
16097         echo "12345" >>$TF
16098         echo "12345" >>$DIR/$tfile
16099         cancel_lru_locks $OSC
16100         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16101 }
16102 run_test 150a "truncate/append tests"
16103
16104 test_150b() {
16105         check_set_fallocate_or_skip
16106         local out
16107
16108         touch $DIR/$tfile
16109         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16110         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16111                 skip_eopnotsupp "$out|check_fallocate failed"
16112 }
16113 run_test 150b "Verify fallocate (prealloc) functionality"
16114
16115 test_150bb() {
16116         check_set_fallocate_or_skip
16117
16118         touch $DIR/$tfile
16119         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16120         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16121         > $DIR/$tfile
16122         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16123         # precomputed md5sum for 20MB of zeroes
16124         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16125         local sum=($(md5sum $DIR/$tfile))
16126
16127         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16128
16129         check_set_fallocate 1
16130
16131         > $DIR/$tfile
16132         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16133         sum=($(md5sum $DIR/$tfile))
16134
16135         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16136 }
16137 run_test 150bb "Verify fallocate modes both zero space"
16138
16139 test_150c() {
16140         check_set_fallocate_or_skip
16141         local striping="-c2"
16142
16143         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16144         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16145         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16146         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16147         local want=$((OSTCOUNT * 1048576))
16148
16149         # Must allocate all requested space, not more than 5% extra
16150         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16151                 error "bytes $bytes is not $want"
16152
16153         rm -f $DIR/$tfile
16154
16155         echo "verify fallocate on PFL file"
16156
16157         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16158
16159         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16160                 error "Create $DIR/$tfile failed"
16161         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16162         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16163         want=$((512 * 1048576))
16164
16165         # Must allocate all requested space, not more than 5% extra
16166         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16167                 error "bytes $bytes is not $want"
16168 }
16169 run_test 150c "Verify fallocate Size and Blocks"
16170
16171 test_150d() {
16172         check_set_fallocate_or_skip
16173         local striping="-c2"
16174
16175         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16176
16177         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16178         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16179                 error "setstripe failed"
16180         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16181         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16182         local want=$((OSTCOUNT * 1048576))
16183
16184         # Must allocate all requested space, not more than 5% extra
16185         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16186                 error "bytes $bytes is not $want"
16187 }
16188 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16189
16190 test_150e() {
16191         check_set_fallocate_or_skip
16192
16193         echo "df before:"
16194         $LFS df
16195         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16196         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16197                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16198
16199         # Find OST with Minimum Size
16200         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16201                        sort -un | head -1)
16202
16203         # Get 100MB per OST of the available space to reduce run time
16204         # else 60% of the available space if we are running SLOW tests
16205         if [ $SLOW == "no" ]; then
16206                 local space=$((1024 * 100 * OSTCOUNT))
16207         else
16208                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16209         fi
16210
16211         fallocate -l${space}k $DIR/$tfile ||
16212                 error "fallocate ${space}k $DIR/$tfile failed"
16213         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16214
16215         # get size immediately after fallocate. This should be correctly
16216         # updated
16217         local size=$(stat -c '%s' $DIR/$tfile)
16218         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16219
16220         # Sleep for a while for statfs to get updated. And not pull from cache.
16221         sleep 2
16222
16223         echo "df after fallocate:"
16224         $LFS df
16225
16226         (( size / 1024 == space )) || error "size $size != requested $space"
16227         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16228                 error "used $used < space $space"
16229
16230         rm $DIR/$tfile || error "rm failed"
16231         sync
16232         wait_delete_completed
16233
16234         echo "df after unlink:"
16235         $LFS df
16236 }
16237 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16238
16239 test_150f() {
16240         local size
16241         local blocks
16242         local want_size_before=20480 # in bytes
16243         local want_blocks_before=40 # 512 sized blocks
16244         local want_blocks_after=24  # 512 sized blocks
16245         local length=$(((want_blocks_before - want_blocks_after) * 512))
16246
16247         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16248                 skip "need at least 2.14.0 for fallocate punch"
16249
16250         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16251                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16252         fi
16253
16254         check_set_fallocate_or_skip
16255         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16256
16257         [[ "x$DOM" == "xyes" ]] &&
16258                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16259
16260         echo "Verify fallocate punch: Range within the file range"
16261         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16262                 error "dd failed for bs 4096 and count 5"
16263
16264         # Call fallocate with punch range which is within the file range
16265         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16266                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16267         # client must see changes immediately after fallocate
16268         size=$(stat -c '%s' $DIR/$tfile)
16269         blocks=$(stat -c '%b' $DIR/$tfile)
16270
16271         # Verify punch worked.
16272         (( blocks == want_blocks_after )) ||
16273                 error "punch failed: blocks $blocks != $want_blocks_after"
16274
16275         (( size == want_size_before )) ||
16276                 error "punch failed: size $size != $want_size_before"
16277
16278         # Verify there is hole in file
16279         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16280         # precomputed md5sum
16281         local expect="4a9a834a2db02452929c0a348273b4aa"
16282
16283         cksum=($(md5sum $DIR/$tfile))
16284         [[ "${cksum[0]}" == "$expect" ]] ||
16285                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16286
16287         # Start second sub-case for fallocate punch.
16288         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16289         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16290                 error "dd failed for bs 4096 and count 5"
16291
16292         # Punch range less than block size will have no change in block count
16293         want_blocks_after=40  # 512 sized blocks
16294
16295         # Punch overlaps two blocks and less than blocksize
16296         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16297                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16298         size=$(stat -c '%s' $DIR/$tfile)
16299         blocks=$(stat -c '%b' $DIR/$tfile)
16300
16301         # Verify punch worked.
16302         (( blocks == want_blocks_after )) ||
16303                 error "punch failed: blocks $blocks != $want_blocks_after"
16304
16305         (( size == want_size_before )) ||
16306                 error "punch failed: size $size != $want_size_before"
16307
16308         # Verify if range is really zero'ed out. We expect Zeros.
16309         # precomputed md5sum
16310         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16311         cksum=($(md5sum $DIR/$tfile))
16312         [[ "${cksum[0]}" == "$expect" ]] ||
16313                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16314 }
16315 run_test 150f "Verify fallocate punch functionality"
16316
16317 test_150g() {
16318         local space
16319         local size
16320         local blocks
16321         local blocks_after
16322         local size_after
16323         local BS=4096 # Block size in bytes
16324
16325         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16326                 skip "need at least 2.14.0 for fallocate punch"
16327
16328         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16329                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16330         fi
16331
16332         check_set_fallocate_or_skip
16333         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16334
16335         if [[ "x$DOM" == "xyes" ]]; then
16336                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16337                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16338         else
16339                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16340                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16341         fi
16342
16343         # Get 100MB per OST of the available space to reduce run time
16344         # else 60% of the available space if we are running SLOW tests
16345         if [ $SLOW == "no" ]; then
16346                 space=$((1024 * 100 * OSTCOUNT))
16347         else
16348                 # Find OST with Minimum Size
16349                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16350                         sort -un | head -1)
16351                 echo "min size OST: $space"
16352                 space=$(((space * 60)/100 * OSTCOUNT))
16353         fi
16354         # space in 1k units, round to 4k blocks
16355         local blkcount=$((space * 1024 / $BS))
16356
16357         echo "Verify fallocate punch: Very large Range"
16358         fallocate -l${space}k $DIR/$tfile ||
16359                 error "fallocate ${space}k $DIR/$tfile failed"
16360         # write 1M at the end, start and in the middle
16361         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16362                 error "dd failed: bs $BS count 256"
16363         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16364                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16365         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16366                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16367
16368         # Gather stats.
16369         size=$(stat -c '%s' $DIR/$tfile)
16370
16371         # gather punch length.
16372         local punch_size=$((size - (BS * 2)))
16373
16374         echo "punch_size = $punch_size"
16375         echo "size - punch_size: $((size - punch_size))"
16376         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16377
16378         # Call fallocate to punch all except 2 blocks. We leave the
16379         # first and the last block
16380         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16381         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16382                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16383
16384         size_after=$(stat -c '%s' $DIR/$tfile)
16385         blocks_after=$(stat -c '%b' $DIR/$tfile)
16386
16387         # Verify punch worked.
16388         # Size should be kept
16389         (( size == size_after )) ||
16390                 error "punch failed: size $size != $size_after"
16391
16392         # two 4k data blocks to remain plus possible 1 extra extent block
16393         (( blocks_after <= ((BS / 512) * 3) )) ||
16394                 error "too many blocks remains: $blocks_after"
16395
16396         # Verify that file has hole between the first and the last blocks
16397         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16398         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16399
16400         echo "Hole at [$hole_start, $hole_end)"
16401         (( hole_start == BS )) ||
16402                 error "no hole at offset $BS after punch"
16403
16404         (( hole_end == BS + punch_size )) ||
16405                 error "data at offset $hole_end < $((BS + punch_size))"
16406 }
16407 run_test 150g "Verify fallocate punch on large range"
16408
16409 test_150h() {
16410         local file=$DIR/$tfile
16411         local size
16412
16413         check_set_fallocate_or_skip
16414         statx_supported || skip_env "Test must be statx() syscall supported"
16415
16416         # fallocate() does not update the size information on the MDT
16417         fallocate -l 16K $file || error "failed to fallocate $file"
16418         cancel_lru_locks $OSC
16419         # STATX with cached-always mode will not send glimpse RPCs to OST,
16420         # it uses the caching attrs on the client side as much as possible.
16421         size=$($STATX --cached=always -c %s $file)
16422         [ $size == 16384 ] ||
16423                 error "size after fallocate() is $size, expected 16384"
16424 }
16425 run_test 150h "Verify extend fallocate updates the file size"
16426
16427 #LU-2902 roc_hit was not able to read all values from lproc
16428 function roc_hit_init() {
16429         local list=$(comma_list $(osts_nodes))
16430         local dir=$DIR/$tdir-check
16431         local file=$dir/$tfile
16432         local BEFORE
16433         local AFTER
16434         local idx
16435
16436         test_mkdir $dir
16437         #use setstripe to do a write to every ost
16438         for i in $(seq 0 $((OSTCOUNT-1))); do
16439                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16440                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16441                 idx=$(printf %04x $i)
16442                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16443                         awk '$1 == "cache_access" {sum += $7}
16444                                 END { printf("%0.0f", sum) }')
16445
16446                 cancel_lru_locks osc
16447                 cat $file >/dev/null
16448
16449                 AFTER=$(get_osd_param $list *OST*$idx stats |
16450                         awk '$1 == "cache_access" {sum += $7}
16451                                 END { printf("%0.0f", sum) }')
16452
16453                 echo BEFORE:$BEFORE AFTER:$AFTER
16454                 if ! let "AFTER - BEFORE == 4"; then
16455                         rm -rf $dir
16456                         error "roc_hit is not safe to use"
16457                 fi
16458                 rm $file
16459         done
16460
16461         rm -rf $dir
16462 }
16463
16464 function roc_hit() {
16465         local list=$(comma_list $(osts_nodes))
16466         echo $(get_osd_param $list '' stats |
16467                 awk '$1 == "cache_hit" {sum += $7}
16468                         END { printf("%0.0f", sum) }')
16469 }
16470
16471 function set_cache() {
16472         local on=1
16473
16474         if [ "$2" == "off" ]; then
16475                 on=0;
16476         fi
16477         local list=$(comma_list $(osts_nodes))
16478         set_osd_param $list '' $1_cache_enable $on
16479
16480         cancel_lru_locks osc
16481 }
16482
16483 test_151() {
16484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16485         remote_ost_nodsh && skip "remote OST with nodsh"
16486         (( CLIENT_VERSION == OST1_VERSION )) ||
16487                 skip "LU-13081: no interop testing for OSS cache"
16488
16489         local CPAGES=3
16490         local list=$(comma_list $(osts_nodes))
16491
16492         # check whether obdfilter is cache capable at all
16493         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16494                 skip "not cache-capable obdfilter"
16495         fi
16496
16497         # check cache is enabled on all obdfilters
16498         if get_osd_param $list '' read_cache_enable | grep 0; then
16499                 skip "oss cache is disabled"
16500         fi
16501
16502         set_osd_param $list '' writethrough_cache_enable 1
16503
16504         # check write cache is enabled on all obdfilters
16505         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16506                 skip "oss write cache is NOT enabled"
16507         fi
16508
16509         roc_hit_init
16510
16511         #define OBD_FAIL_OBD_NO_LRU  0x609
16512         do_nodes $list $LCTL set_param fail_loc=0x609
16513
16514         # pages should be in the case right after write
16515         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16516                 error "dd failed"
16517
16518         local BEFORE=$(roc_hit)
16519         cancel_lru_locks osc
16520         cat $DIR/$tfile >/dev/null
16521         local AFTER=$(roc_hit)
16522
16523         do_nodes $list $LCTL set_param fail_loc=0
16524
16525         if ! let "AFTER - BEFORE == CPAGES"; then
16526                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16527         fi
16528
16529         cancel_lru_locks osc
16530         # invalidates OST cache
16531         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16532         set_osd_param $list '' read_cache_enable 0
16533         cat $DIR/$tfile >/dev/null
16534
16535         # now data shouldn't be found in the cache
16536         BEFORE=$(roc_hit)
16537         cancel_lru_locks osc
16538         cat $DIR/$tfile >/dev/null
16539         AFTER=$(roc_hit)
16540         if let "AFTER - BEFORE != 0"; then
16541                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16542         fi
16543
16544         set_osd_param $list '' read_cache_enable 1
16545         rm -f $DIR/$tfile
16546 }
16547 run_test 151 "test cache on oss and controls ==============================="
16548
16549 test_152() {
16550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16551
16552         local TF="$TMP/$tfile"
16553
16554         # simulate ENOMEM during write
16555 #define OBD_FAIL_OST_NOMEM      0x226
16556         lctl set_param fail_loc=0x80000226
16557         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16558         cp $TF $DIR/$tfile
16559         sync || error "sync failed"
16560         lctl set_param fail_loc=0
16561
16562         # discard client's cache
16563         cancel_lru_locks osc
16564
16565         # simulate ENOMEM during read
16566         lctl set_param fail_loc=0x80000226
16567         cmp $TF $DIR/$tfile || error "cmp failed"
16568         lctl set_param fail_loc=0
16569
16570         rm -f $TF
16571 }
16572 run_test 152 "test read/write with enomem ============================"
16573
16574 test_153() {
16575         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16576 }
16577 run_test 153 "test if fdatasync does not crash ======================="
16578
16579 dot_lustre_fid_permission_check() {
16580         local fid=$1
16581         local ffid=$MOUNT/.lustre/fid/$fid
16582         local test_dir=$2
16583
16584         echo "stat fid $fid"
16585         stat $ffid || error "stat $ffid failed."
16586         echo "touch fid $fid"
16587         touch $ffid || error "touch $ffid failed."
16588         echo "write to fid $fid"
16589         cat /etc/hosts > $ffid || error "write $ffid failed."
16590         echo "read fid $fid"
16591         diff /etc/hosts $ffid || error "read $ffid failed."
16592         echo "append write to fid $fid"
16593         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16594         echo "rename fid $fid"
16595         mv $ffid $test_dir/$tfile.1 &&
16596                 error "rename $ffid to $tfile.1 should fail."
16597         touch $test_dir/$tfile.1
16598         mv $test_dir/$tfile.1 $ffid &&
16599                 error "rename $tfile.1 to $ffid should fail."
16600         rm -f $test_dir/$tfile.1
16601         echo "truncate fid $fid"
16602         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16603         echo "link fid $fid"
16604         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16605         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16606                 id $USER0 || skip_env "missing user $USER0"
16607                 echo "setfacl fid $fid"
16608                 setfacl -R -m u:$USER0:rwx $ffid ||
16609                         error "setfacl $ffid failed"
16610                 echo "getfacl fid $fid"
16611                 getfacl $ffid || error "getfacl $ffid failed."
16612         fi
16613         echo "unlink fid $fid"
16614         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16615         echo "mknod fid $fid"
16616         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16617
16618         fid=[0xf00000400:0x1:0x0]
16619         ffid=$MOUNT/.lustre/fid/$fid
16620
16621         echo "stat non-exist fid $fid"
16622         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16623         echo "write to non-exist fid $fid"
16624         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16625         echo "link new fid $fid"
16626         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16627
16628         mkdir -p $test_dir/$tdir
16629         touch $test_dir/$tdir/$tfile
16630         fid=$($LFS path2fid $test_dir/$tdir)
16631         rc=$?
16632         [ $rc -ne 0 ] &&
16633                 error "error: could not get fid for $test_dir/$dir/$tfile."
16634
16635         ffid=$MOUNT/.lustre/fid/$fid
16636
16637         echo "ls $fid"
16638         ls $ffid || error "ls $ffid failed."
16639         echo "touch $fid/$tfile.1"
16640         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16641
16642         echo "touch $MOUNT/.lustre/fid/$tfile"
16643         touch $MOUNT/.lustre/fid/$tfile && \
16644                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16645
16646         echo "setxattr to $MOUNT/.lustre/fid"
16647         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16648
16649         echo "listxattr for $MOUNT/.lustre/fid"
16650         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16651
16652         echo "delxattr from $MOUNT/.lustre/fid"
16653         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16654
16655         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16656         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16657                 error "touch invalid fid should fail."
16658
16659         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16660         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16661                 error "touch non-normal fid should fail."
16662
16663         echo "rename $tdir to $MOUNT/.lustre/fid"
16664         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16665                 error "rename to $MOUNT/.lustre/fid should fail."
16666
16667         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16668         then            # LU-3547
16669                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16670                 local new_obf_mode=777
16671
16672                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16673                 chmod $new_obf_mode $DIR/.lustre/fid ||
16674                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16675
16676                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16677                 [ $obf_mode -eq $new_obf_mode ] ||
16678                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16679
16680                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16681                 chmod $old_obf_mode $DIR/.lustre/fid ||
16682                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16683         fi
16684
16685         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16686         fid=$($LFS path2fid $test_dir/$tfile-2)
16687
16688         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16689         then # LU-5424
16690                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16691                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16692                         error "create lov data thru .lustre failed"
16693         fi
16694         echo "cp /etc/passwd $test_dir/$tfile-2"
16695         cp /etc/passwd $test_dir/$tfile-2 ||
16696                 error "copy to $test_dir/$tfile-2 failed."
16697         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16698         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16699                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16700
16701         rm -rf $test_dir/tfile.lnk
16702         rm -rf $test_dir/$tfile-2
16703 }
16704
16705 test_154A() {
16706         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16707                 skip "Need MDS version at least 2.4.1"
16708
16709         local tf=$DIR/$tfile
16710         touch $tf
16711
16712         local fid=$($LFS path2fid $tf)
16713         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16714
16715         # check that we get the same pathname back
16716         local rootpath
16717         local found
16718         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16719                 echo "$rootpath $fid"
16720                 found=$($LFS fid2path $rootpath "$fid")
16721                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16722                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16723         done
16724
16725         # check wrong root path format
16726         rootpath=$MOUNT"_wrong"
16727         found=$($LFS fid2path $rootpath "$fid")
16728         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16729 }
16730 run_test 154A "lfs path2fid and fid2path basic checks"
16731
16732 test_154B() {
16733         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16734                 skip "Need MDS version at least 2.4.1"
16735
16736         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16737         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16738         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16739         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16740
16741         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16742         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16743
16744         # check that we get the same pathname
16745         echo "PFID: $PFID, name: $name"
16746         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16747         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16748         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16749                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16750
16751         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16752 }
16753 run_test 154B "verify the ll_decode_linkea tool"
16754
16755 test_154a() {
16756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16757         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16758         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16759                 skip "Need MDS version at least 2.2.51"
16760         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16761
16762         cp /etc/hosts $DIR/$tfile
16763
16764         fid=$($LFS path2fid $DIR/$tfile)
16765         rc=$?
16766         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16767
16768         dot_lustre_fid_permission_check "$fid" $DIR ||
16769                 error "dot lustre permission check $fid failed"
16770
16771         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16772
16773         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16774
16775         touch $MOUNT/.lustre/file &&
16776                 error "creation is not allowed under .lustre"
16777
16778         mkdir $MOUNT/.lustre/dir &&
16779                 error "mkdir is not allowed under .lustre"
16780
16781         rm -rf $DIR/$tfile
16782 }
16783 run_test 154a "Open-by-FID"
16784
16785 test_154b() {
16786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16787         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16789         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16790                 skip "Need MDS version at least 2.2.51"
16791
16792         local remote_dir=$DIR/$tdir/remote_dir
16793         local MDTIDX=1
16794         local rc=0
16795
16796         mkdir -p $DIR/$tdir
16797         $LFS mkdir -i $MDTIDX $remote_dir ||
16798                 error "create remote directory failed"
16799
16800         cp /etc/hosts $remote_dir/$tfile
16801
16802         fid=$($LFS path2fid $remote_dir/$tfile)
16803         rc=$?
16804         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16805
16806         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16807                 error "dot lustre permission check $fid failed"
16808         rm -rf $DIR/$tdir
16809 }
16810 run_test 154b "Open-by-FID for remote directory"
16811
16812 test_154c() {
16813         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16814                 skip "Need MDS version at least 2.4.1"
16815
16816         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16817         local FID1=$($LFS path2fid $DIR/$tfile.1)
16818         local FID2=$($LFS path2fid $DIR/$tfile.2)
16819         local FID3=$($LFS path2fid $DIR/$tfile.3)
16820
16821         local N=1
16822         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16823                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16824                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16825                 local want=FID$N
16826                 [ "$FID" = "${!want}" ] ||
16827                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16828                 N=$((N + 1))
16829         done
16830
16831         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16832         do
16833                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16834                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16835                 N=$((N + 1))
16836         done
16837 }
16838 run_test 154c "lfs path2fid and fid2path multiple arguments"
16839
16840 test_154d() {
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16843                 skip "Need MDS version at least 2.5.53"
16844
16845         if remote_mds; then
16846                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16847         else
16848                 nid="0@lo"
16849         fi
16850         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16851         local fd
16852         local cmd
16853
16854         rm -f $DIR/$tfile
16855         touch $DIR/$tfile
16856
16857         local fid=$($LFS path2fid $DIR/$tfile)
16858         # Open the file
16859         fd=$(free_fd)
16860         cmd="exec $fd<$DIR/$tfile"
16861         eval $cmd
16862         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16863         echo "$fid_list" | grep "$fid"
16864         rc=$?
16865
16866         cmd="exec $fd>/dev/null"
16867         eval $cmd
16868         if [ $rc -ne 0 ]; then
16869                 error "FID $fid not found in open files list $fid_list"
16870         fi
16871 }
16872 run_test 154d "Verify open file fid"
16873
16874 test_154e()
16875 {
16876         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16877                 skip "Need MDS version at least 2.6.50"
16878
16879         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16880                 error ".lustre returned by readdir"
16881         fi
16882 }
16883 run_test 154e ".lustre is not returned by readdir"
16884
16885 test_154f() {
16886         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16887
16888         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16889         mkdir_on_mdt0 $DIR/$tdir
16890         # test dirs inherit from its stripe
16891         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16892         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16893         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16894         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16895         touch $DIR/f
16896
16897         # get fid of parents
16898         local FID0=$($LFS path2fid $DIR/$tdir)
16899         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16900         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16901         local FID3=$($LFS path2fid $DIR)
16902
16903         # check that path2fid --parents returns expected <parent_fid>/name
16904         # 1) test for a directory (single parent)
16905         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16906         [ "$parent" == "$FID0/foo1" ] ||
16907                 error "expected parent: $FID0/foo1, got: $parent"
16908
16909         # 2) test for a file with nlink > 1 (multiple parents)
16910         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16911         echo "$parent" | grep -F "$FID1/$tfile" ||
16912                 error "$FID1/$tfile not returned in parent list"
16913         echo "$parent" | grep -F "$FID2/link" ||
16914                 error "$FID2/link not returned in parent list"
16915
16916         # 3) get parent by fid
16917         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16918         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16919         echo "$parent" | grep -F "$FID1/$tfile" ||
16920                 error "$FID1/$tfile not returned in parent list (by fid)"
16921         echo "$parent" | grep -F "$FID2/link" ||
16922                 error "$FID2/link not returned in parent list (by fid)"
16923
16924         # 4) test for entry in root directory
16925         parent=$($LFS path2fid --parents $DIR/f)
16926         echo "$parent" | grep -F "$FID3/f" ||
16927                 error "$FID3/f not returned in parent list"
16928
16929         # 5) test it on root directory
16930         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16931                 error "$MOUNT should not have parents"
16932
16933         # enable xattr caching and check that linkea is correctly updated
16934         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16935         save_lustre_params client "llite.*.xattr_cache" > $save
16936         lctl set_param llite.*.xattr_cache 1
16937
16938         # 6.1) linkea update on rename
16939         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16940
16941         # get parents by fid
16942         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16943         # foo1 should no longer be returned in parent list
16944         echo "$parent" | grep -F "$FID1" &&
16945                 error "$FID1 should no longer be in parent list"
16946         # the new path should appear
16947         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16948                 error "$FID2/$tfile.moved is not in parent list"
16949
16950         # 6.2) linkea update on unlink
16951         rm -f $DIR/$tdir/foo2/link
16952         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16953         # foo2/link should no longer be returned in parent list
16954         echo "$parent" | grep -F "$FID2/link" &&
16955                 error "$FID2/link should no longer be in parent list"
16956         true
16957
16958         rm -f $DIR/f
16959         restore_lustre_params < $save
16960         rm -f $save
16961 }
16962 run_test 154f "get parent fids by reading link ea"
16963
16964 test_154g()
16965 {
16966         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16967            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16968                 skip "Need MDS version at least 2.6.92"
16969
16970         mkdir_on_mdt0 $DIR/$tdir
16971         llapi_fid_test -d $DIR/$tdir
16972 }
16973 run_test 154g "various llapi FID tests"
16974
16975 test_154h()
16976 {
16977         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16978                 skip "Need client at least version 2.15.55.1"
16979
16980         # Create an empty file
16981         touch $DIR/$tfile
16982
16983         # Get FID (interactive mode) and save under $TMP/$tfile.log
16984         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16985                 path2fid $DIR/$tfile
16986         EOF
16987
16988         fid=$(cat $TMP/$tfile.log)
16989         # $fid should not be empty
16990         [[ ! -z $fid ]] || error "FID is empty"
16991         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16992 }
16993 run_test 154h "Verify interactive path2fid"
16994
16995 test_155_small_load() {
16996     local temp=$TMP/$tfile
16997     local file=$DIR/$tfile
16998
16999     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17000         error "dd of=$temp bs=6096 count=1 failed"
17001     cp $temp $file
17002     cancel_lru_locks $OSC
17003     cmp $temp $file || error "$temp $file differ"
17004
17005     $TRUNCATE $temp 6000
17006     $TRUNCATE $file 6000
17007     cmp $temp $file || error "$temp $file differ (truncate1)"
17008
17009     echo "12345" >>$temp
17010     echo "12345" >>$file
17011     cmp $temp $file || error "$temp $file differ (append1)"
17012
17013     echo "12345" >>$temp
17014     echo "12345" >>$file
17015     cmp $temp $file || error "$temp $file differ (append2)"
17016
17017     rm -f $temp $file
17018     true
17019 }
17020
17021 test_155_big_load() {
17022         remote_ost_nodsh && skip "remote OST with nodsh"
17023
17024         local temp=$TMP/$tfile
17025         local file=$DIR/$tfile
17026
17027         free_min_max
17028         local cache_size=$(do_facet ost$((MAXI+1)) \
17029                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17030
17031         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17032         # pre-set value
17033         if [ -z "$cache_size" ]; then
17034                 cache_size=256
17035         fi
17036         local large_file_size=$((cache_size * 2))
17037
17038         echo "OSS cache size: $cache_size KB"
17039         echo "Large file size: $large_file_size KB"
17040
17041         [ $MAXV -le $large_file_size ] &&
17042                 skip_env "max available OST size needs > $large_file_size KB"
17043
17044         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17045
17046         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17047                 error "dd of=$temp bs=$large_file_size count=1k failed"
17048         cp $temp $file
17049         ls -lh $temp $file
17050         cancel_lru_locks osc
17051         cmp $temp $file || error "$temp $file differ"
17052
17053         rm -f $temp $file
17054         true
17055 }
17056
17057 save_writethrough() {
17058         local facets=$(get_facets OST)
17059
17060         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17061 }
17062
17063 test_155a() {
17064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17065
17066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17067
17068         save_writethrough $p
17069
17070         set_cache read on
17071         set_cache writethrough on
17072         test_155_small_load
17073         restore_lustre_params < $p
17074         rm -f $p
17075 }
17076 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17077
17078 test_155b() {
17079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17080
17081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17082
17083         save_writethrough $p
17084
17085         set_cache read on
17086         set_cache writethrough off
17087         test_155_small_load
17088         restore_lustre_params < $p
17089         rm -f $p
17090 }
17091 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17092
17093 test_155c() {
17094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17095
17096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17097
17098         save_writethrough $p
17099
17100         set_cache read off
17101         set_cache writethrough on
17102         test_155_small_load
17103         restore_lustre_params < $p
17104         rm -f $p
17105 }
17106 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17107
17108 test_155d() {
17109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17110
17111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17112
17113         save_writethrough $p
17114
17115         set_cache read off
17116         set_cache writethrough off
17117         test_155_small_load
17118         restore_lustre_params < $p
17119         rm -f $p
17120 }
17121 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17122
17123 test_155e() {
17124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17125
17126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17127
17128         save_writethrough $p
17129
17130         set_cache read on
17131         set_cache writethrough on
17132         test_155_big_load
17133         restore_lustre_params < $p
17134         rm -f $p
17135 }
17136 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17137
17138 test_155f() {
17139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17140
17141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17142
17143         save_writethrough $p
17144
17145         set_cache read on
17146         set_cache writethrough off
17147         test_155_big_load
17148         restore_lustre_params < $p
17149         rm -f $p
17150 }
17151 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17152
17153 test_155g() {
17154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17155
17156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17157
17158         save_writethrough $p
17159
17160         set_cache read off
17161         set_cache writethrough on
17162         test_155_big_load
17163         restore_lustre_params < $p
17164         rm -f $p
17165 }
17166 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17167
17168 test_155h() {
17169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17170
17171         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17172
17173         save_writethrough $p
17174
17175         set_cache read off
17176         set_cache writethrough off
17177         test_155_big_load
17178         restore_lustre_params < $p
17179         rm -f $p
17180 }
17181 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17182
17183 test_156() {
17184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17185         remote_ost_nodsh && skip "remote OST with nodsh"
17186         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17187                 skip "stats not implemented on old servers"
17188         [ "$ost1_FSTYPE" = "zfs" ] &&
17189                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17190         (( CLIENT_VERSION == OST1_VERSION )) ||
17191                 skip "LU-13081: no interop testing for OSS cache"
17192
17193         local CPAGES=3
17194         local BEFORE
17195         local AFTER
17196         local file="$DIR/$tfile"
17197         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17198
17199         save_writethrough $p
17200         roc_hit_init
17201
17202         log "Turn on read and write cache"
17203         set_cache read on
17204         set_cache writethrough on
17205
17206         log "Write data and read it back."
17207         log "Read should be satisfied from the cache."
17208         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17209         BEFORE=$(roc_hit)
17210         cancel_lru_locks osc
17211         cat $file >/dev/null
17212         AFTER=$(roc_hit)
17213         if ! let "AFTER - BEFORE == CPAGES"; then
17214                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17215         else
17216                 log "cache hits: before: $BEFORE, after: $AFTER"
17217         fi
17218
17219         log "Read again; it should be satisfied from the cache."
17220         BEFORE=$AFTER
17221         cancel_lru_locks osc
17222         cat $file >/dev/null
17223         AFTER=$(roc_hit)
17224         if ! let "AFTER - BEFORE == CPAGES"; then
17225                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17226         else
17227                 log "cache hits:: before: $BEFORE, after: $AFTER"
17228         fi
17229
17230         log "Turn off the read cache and turn on the write cache"
17231         set_cache read off
17232         set_cache writethrough on
17233
17234         log "Read again; it should be satisfied from the cache."
17235         BEFORE=$(roc_hit)
17236         cancel_lru_locks osc
17237         cat $file >/dev/null
17238         AFTER=$(roc_hit)
17239         if ! let "AFTER - BEFORE == CPAGES"; then
17240                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17241         else
17242                 log "cache hits:: before: $BEFORE, after: $AFTER"
17243         fi
17244
17245         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17246                 # > 2.12.56 uses pagecache if cached
17247                 log "Read again; it should not be satisfied from the cache."
17248                 BEFORE=$AFTER
17249                 cancel_lru_locks osc
17250                 cat $file >/dev/null
17251                 AFTER=$(roc_hit)
17252                 if ! let "AFTER - BEFORE == 0"; then
17253                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17254                 else
17255                         log "cache hits:: before: $BEFORE, after: $AFTER"
17256                 fi
17257         fi
17258
17259         log "Write data and read it back."
17260         log "Read should be satisfied from the cache."
17261         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17262         BEFORE=$(roc_hit)
17263         cancel_lru_locks osc
17264         cat $file >/dev/null
17265         AFTER=$(roc_hit)
17266         if ! let "AFTER - BEFORE == CPAGES"; then
17267                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17268         else
17269                 log "cache hits:: before: $BEFORE, after: $AFTER"
17270         fi
17271
17272         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17273                 # > 2.12.56 uses pagecache if cached
17274                 log "Read again; it should not be satisfied from the cache."
17275                 BEFORE=$AFTER
17276                 cancel_lru_locks osc
17277                 cat $file >/dev/null
17278                 AFTER=$(roc_hit)
17279                 if ! let "AFTER - BEFORE == 0"; then
17280                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17281                 else
17282                         log "cache hits:: before: $BEFORE, after: $AFTER"
17283                 fi
17284         fi
17285
17286         log "Turn off read and write cache"
17287         set_cache read off
17288         set_cache writethrough off
17289
17290         log "Write data and read it back"
17291         log "It should not be satisfied from the cache."
17292         rm -f $file
17293         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17294         cancel_lru_locks osc
17295         BEFORE=$(roc_hit)
17296         cat $file >/dev/null
17297         AFTER=$(roc_hit)
17298         if ! let "AFTER - BEFORE == 0"; then
17299                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17300         else
17301                 log "cache hits:: before: $BEFORE, after: $AFTER"
17302         fi
17303
17304         log "Turn on the read cache and turn off the write cache"
17305         set_cache read on
17306         set_cache writethrough off
17307
17308         log "Write data and read it back"
17309         log "It should not be satisfied from the cache."
17310         rm -f $file
17311         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17312         BEFORE=$(roc_hit)
17313         cancel_lru_locks osc
17314         cat $file >/dev/null
17315         AFTER=$(roc_hit)
17316         if ! let "AFTER - BEFORE == 0"; then
17317                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17318         else
17319                 log "cache hits:: before: $BEFORE, after: $AFTER"
17320         fi
17321
17322         log "Read again; it should be satisfied from the cache."
17323         BEFORE=$(roc_hit)
17324         cancel_lru_locks osc
17325         cat $file >/dev/null
17326         AFTER=$(roc_hit)
17327         if ! let "AFTER - BEFORE == CPAGES"; then
17328                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17329         else
17330                 log "cache hits:: before: $BEFORE, after: $AFTER"
17331         fi
17332
17333         restore_lustre_params < $p
17334         rm -f $p $file
17335 }
17336 run_test 156 "Verification of tunables"
17337
17338 test_160a() {
17339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17340         remote_mds_nodsh && skip "remote MDS with nodsh"
17341         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17342                 skip "Need MDS version at least 2.2.0"
17343
17344         changelog_register || error "changelog_register failed"
17345         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17346         changelog_users $SINGLEMDS | grep -q $cl_user ||
17347                 error "User $cl_user not found in changelog_users"
17348
17349         mkdir_on_mdt0 $DIR/$tdir
17350
17351         # change something
17352         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17353         changelog_clear 0 || error "changelog_clear failed"
17354         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17355         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17356         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17357         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17358         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17359         rm $DIR/$tdir/pics/desktop.jpg
17360
17361         echo "verifying changelog mask"
17362         changelog_chmask "-MKDIR"
17363         changelog_chmask "-CLOSE"
17364
17365         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17366         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17367
17368         changelog_chmask "+MKDIR"
17369         changelog_chmask "+CLOSE"
17370
17371         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17372         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17373
17374         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17375         CLOSES=$(changelog_dump | grep -c "CLOSE")
17376         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17377         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17378
17379         # verify contents
17380         echo "verifying target fid"
17381         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17382         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17383         [ "$fidc" == "$fidf" ] ||
17384                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17385         echo "verifying parent fid"
17386         # The FID returned from the Changelog may be the directory shard on
17387         # a different MDT, and not the FID returned by path2fid on the parent.
17388         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17389         # since this is what will matter when recreating this file in the tree.
17390         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17391         local pathp=$($LFS fid2path $MOUNT "$fidp")
17392         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17393                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17394
17395         echo "getting records for $cl_user"
17396         changelog_users $SINGLEMDS
17397         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17398         local nclr=3
17399         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17400                 error "changelog_clear failed"
17401         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17402         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17403         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17404                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17405
17406         local min0_rec=$(changelog_users $SINGLEMDS |
17407                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17408         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17409                           awk '{ print $1; exit; }')
17410
17411         changelog_dump | tail -n 5
17412         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17413         [ $first_rec == $((min0_rec + 1)) ] ||
17414                 error "first index should be $min0_rec + 1 not $first_rec"
17415
17416         # LU-3446 changelog index reset on MDT restart
17417         local cur_rec1=$(changelog_users $SINGLEMDS |
17418                          awk '/^current.index:/ { print $NF }')
17419         changelog_clear 0 ||
17420                 error "clear all changelog records for $cl_user failed"
17421         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17422         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17423                 error "Fail to start $SINGLEMDS"
17424         local cur_rec2=$(changelog_users $SINGLEMDS |
17425                          awk '/^current.index:/ { print $NF }')
17426         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17427         [ $cur_rec1 == $cur_rec2 ] ||
17428                 error "current index should be $cur_rec1 not $cur_rec2"
17429
17430         echo "verifying users from this test are deregistered"
17431         changelog_deregister || error "changelog_deregister failed"
17432         changelog_users $SINGLEMDS | grep -q $cl_user &&
17433                 error "User '$cl_user' still in changelog_users"
17434
17435         # lctl get_param -n mdd.*.changelog_users
17436         # current_index: 144
17437         # ID    index (idle seconds)
17438         # cl3   144   (2) mask=<list>
17439         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17440                 # this is the normal case where all users were deregistered
17441                 # make sure no new records are added when no users are present
17442                 local last_rec1=$(changelog_users $SINGLEMDS |
17443                                   awk '/^current.index:/ { print $NF }')
17444                 touch $DIR/$tdir/chloe
17445                 local last_rec2=$(changelog_users $SINGLEMDS |
17446                                   awk '/^current.index:/ { print $NF }')
17447                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17448                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17449         else
17450                 # any changelog users must be leftovers from a previous test
17451                 changelog_users $SINGLEMDS
17452                 echo "other changelog users; can't verify off"
17453         fi
17454 }
17455 run_test 160a "changelog sanity"
17456
17457 test_160b() { # LU-3587
17458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17459         remote_mds_nodsh && skip "remote MDS with nodsh"
17460         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17461                 skip "Need MDS version at least 2.2.0"
17462
17463         changelog_register || error "changelog_register failed"
17464         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17465         changelog_users $SINGLEMDS | grep -q $cl_user ||
17466                 error "User '$cl_user' not found in changelog_users"
17467
17468         local longname1=$(str_repeat a 255)
17469         local longname2=$(str_repeat b 255)
17470
17471         cd $DIR
17472         echo "creating very long named file"
17473         touch $longname1 || error "create of '$longname1' failed"
17474         echo "renaming very long named file"
17475         mv $longname1 $longname2
17476
17477         changelog_dump | grep RENME | tail -n 5
17478         rm -f $longname2
17479 }
17480 run_test 160b "Verify that very long rename doesn't crash in changelog"
17481
17482 test_160c() {
17483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17484         remote_mds_nodsh && skip "remote MDS with nodsh"
17485
17486         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17487                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17488                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17489                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17490
17491         local rc=0
17492
17493         # Registration step
17494         changelog_register || error "changelog_register failed"
17495
17496         rm -rf $DIR/$tdir
17497         mkdir -p $DIR/$tdir
17498         $MCREATE $DIR/$tdir/foo_160c
17499         changelog_chmask "-TRUNC"
17500         $TRUNCATE $DIR/$tdir/foo_160c 200
17501         changelog_chmask "+TRUNC"
17502         $TRUNCATE $DIR/$tdir/foo_160c 199
17503         changelog_dump | tail -n 5
17504         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17505         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17506 }
17507 run_test 160c "verify that changelog log catch the truncate event"
17508
17509 test_160d() {
17510         remote_mds_nodsh && skip "remote MDS with nodsh"
17511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17513         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17514                 skip "Need MDS version at least 2.7.60"
17515
17516         # Registration step
17517         changelog_register || error "changelog_register failed"
17518
17519         mkdir -p $DIR/$tdir/migrate_dir
17520         changelog_clear 0 || error "changelog_clear failed"
17521
17522         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17523         changelog_dump | tail -n 5
17524         local migrates=$(changelog_dump | grep -c "MIGRT")
17525         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17526 }
17527 run_test 160d "verify that changelog log catch the migrate event"
17528
17529 test_160e() {
17530         remote_mds_nodsh && skip "remote MDS with nodsh"
17531
17532         # Create a user
17533         changelog_register || error "changelog_register failed"
17534
17535         local MDT0=$(facet_svc $SINGLEMDS)
17536         local rc
17537
17538         # No user (expect fail)
17539         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17540         rc=$?
17541         if [ $rc -eq 0 ]; then
17542                 error "Should fail without user"
17543         elif [ $rc -ne 4 ]; then
17544                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17545         fi
17546
17547         # Delete a future user (expect fail)
17548         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17549         rc=$?
17550         if [ $rc -eq 0 ]; then
17551                 error "Deleted non-existant user cl77"
17552         elif [ $rc -ne 2 ]; then
17553                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17554         fi
17555
17556         # Clear to a bad index (1 billion should be safe)
17557         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17558         rc=$?
17559
17560         if [ $rc -eq 0 ]; then
17561                 error "Successfully cleared to invalid CL index"
17562         elif [ $rc -ne 22 ]; then
17563                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17564         fi
17565 }
17566 run_test 160e "changelog negative testing (should return errors)"
17567
17568 test_160f() {
17569         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17570         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17571                 skip "Need MDS version at least 2.10.56"
17572
17573         local mdts=$(comma_list $(mdts_nodes))
17574
17575         # Create a user
17576         changelog_register || error "first changelog_register failed"
17577         changelog_register || error "second changelog_register failed"
17578         local cl_users
17579         declare -A cl_user1
17580         declare -A cl_user2
17581         local user_rec1
17582         local user_rec2
17583         local i
17584
17585         # generate some changelog records to accumulate on each MDT
17586         # use all_char because created files should be evenly distributed
17587         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17588                 error "test_mkdir $tdir failed"
17589         log "$(date +%s): creating first files"
17590         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17591                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17592                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17593         done
17594
17595         # check changelogs have been generated
17596         local start=$SECONDS
17597         local idle_time=$((MDSCOUNT * 5 + 5))
17598         local nbcl=$(changelog_dump | wc -l)
17599         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17600
17601         for param in "changelog_max_idle_time=$idle_time" \
17602                      "changelog_gc=1" \
17603                      "changelog_min_gc_interval=2" \
17604                      "changelog_min_free_cat_entries=3"; do
17605                 local MDT0=$(facet_svc $SINGLEMDS)
17606                 local var="${param%=*}"
17607                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17608
17609                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17610                 do_nodes $mdts $LCTL set_param mdd.*.$param
17611         done
17612
17613         # force cl_user2 to be idle (1st part), but also cancel the
17614         # cl_user1 records so that it is not evicted later in the test.
17615         local sleep1=$((idle_time / 2))
17616         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17617         sleep $sleep1
17618
17619         # simulate changelog catalog almost full
17620         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17621         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17622
17623         for i in $(seq $MDSCOUNT); do
17624                 cl_users=(${CL_USERS[mds$i]})
17625                 cl_user1[mds$i]="${cl_users[0]}"
17626                 cl_user2[mds$i]="${cl_users[1]}"
17627
17628                 [ -n "${cl_user1[mds$i]}" ] ||
17629                         error "mds$i: no user registered"
17630                 [ -n "${cl_user2[mds$i]}" ] ||
17631                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17632
17633                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17634                 [ -n "$user_rec1" ] ||
17635                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17636                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17637                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17638                 [ -n "$user_rec2" ] ||
17639                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17640                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17641                      "$user_rec1 + 2 == $user_rec2"
17642                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17643                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17644                               "$user_rec1 + 2, but is $user_rec2"
17645                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17646                 [ -n "$user_rec2" ] ||
17647                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17648                 [ $user_rec1 == $user_rec2 ] ||
17649                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17650                               "$user_rec1, but is $user_rec2"
17651         done
17652
17653         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17654         local sleep2=$((idle_time - (SECONDS - start) + 1))
17655         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17656         sleep $sleep2
17657
17658         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17659         # cl_user1 should be OK because it recently processed records.
17660         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17661         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17662                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17663                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17664         done
17665
17666         # ensure gc thread is done
17667         for i in $(mdts_nodes); do
17668                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17669                         error "$i: GC-thread not done"
17670         done
17671
17672         local first_rec
17673         for (( i = 1; i <= MDSCOUNT; i++ )); do
17674                 # check cl_user1 still registered
17675                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17676                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17677                 # check cl_user2 unregistered
17678                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17679                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17680
17681                 # check changelogs are present and starting at $user_rec1 + 1
17682                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17683                 [ -n "$user_rec1" ] ||
17684                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17685                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17686                             awk '{ print $1; exit; }')
17687
17688                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17689                 [ $((user_rec1 + 1)) == $first_rec ] ||
17690                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17691         done
17692 }
17693 run_test 160f "changelog garbage collect (timestamped users)"
17694
17695 test_160g() {
17696         remote_mds_nodsh && skip "remote MDS with nodsh"
17697         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17698                 skip "Need MDS version at least 2.14.55"
17699
17700         local mdts=$(comma_list $(mdts_nodes))
17701
17702         # Create a user
17703         changelog_register || error "first changelog_register failed"
17704         changelog_register || error "second changelog_register failed"
17705         local cl_users
17706         declare -A cl_user1
17707         declare -A cl_user2
17708         local user_rec1
17709         local user_rec2
17710         local i
17711
17712         # generate some changelog records to accumulate on each MDT
17713         # use all_char because created files should be evenly distributed
17714         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17715                 error "test_mkdir $tdir failed"
17716         for ((i = 0; i < MDSCOUNT; i++)); do
17717                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17718                         error "create $DIR/$tdir/d$i.1 failed"
17719         done
17720
17721         # check changelogs have been generated
17722         local nbcl=$(changelog_dump | wc -l)
17723         (( $nbcl > 0 )) || error "no changelogs found"
17724
17725         # reduce the max_idle_indexes value to make sure we exceed it
17726         for param in "changelog_max_idle_indexes=2" \
17727                      "changelog_gc=1" \
17728                      "changelog_min_gc_interval=2"; do
17729                 local MDT0=$(facet_svc $SINGLEMDS)
17730                 local var="${param%=*}"
17731                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17732
17733                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17734                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17735                         error "unable to set mdd.*.$param"
17736         done
17737
17738         local start=$SECONDS
17739         for i in $(seq $MDSCOUNT); do
17740                 cl_users=(${CL_USERS[mds$i]})
17741                 cl_user1[mds$i]="${cl_users[0]}"
17742                 cl_user2[mds$i]="${cl_users[1]}"
17743
17744                 [ -n "${cl_user1[mds$i]}" ] ||
17745                         error "mds$i: user1 is not registered"
17746                 [ -n "${cl_user2[mds$i]}" ] ||
17747                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17748
17749                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17750                 [ -n "$user_rec1" ] ||
17751                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17752                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17753                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17754                 [ -n "$user_rec2" ] ||
17755                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17756                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17757                      "$user_rec1 + 2 == $user_rec2"
17758                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17759                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17760                               "expected $user_rec1 + 2, but is $user_rec2"
17761                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17762                 [ -n "$user_rec2" ] ||
17763                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17764                 [ $user_rec1 == $user_rec2 ] ||
17765                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17766                               "expected $user_rec1, but is $user_rec2"
17767         done
17768
17769         # ensure we are past the previous changelog_min_gc_interval set above
17770         local sleep2=$((start + 2 - SECONDS))
17771         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17772         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17773         # cl_user1 should be OK because it recently processed records.
17774         for ((i = 0; i < MDSCOUNT; i++)); do
17775                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17776                         error "create $DIR/$tdir/d$i.3 failed"
17777         done
17778
17779         # ensure gc thread is done
17780         for i in $(mdts_nodes); do
17781                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17782                         error "$i: GC-thread not done"
17783         done
17784
17785         local first_rec
17786         for (( i = 1; i <= MDSCOUNT; i++ )); do
17787                 # check cl_user1 still registered
17788                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17789                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17790                 # check cl_user2 unregistered
17791                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17792                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17793
17794                 # check changelogs are present and starting at $user_rec1 + 1
17795                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17796                 [ -n "$user_rec1" ] ||
17797                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17798                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17799                             awk '{ print $1; exit; }')
17800
17801                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17802                 [ $((user_rec1 + 1)) == $first_rec ] ||
17803                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17804         done
17805 }
17806 run_test 160g "changelog garbage collect on idle records"
17807
17808 test_160h() {
17809         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17810         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17811                 skip "Need MDS version at least 2.10.56"
17812
17813         local mdts=$(comma_list $(mdts_nodes))
17814
17815         # Create a user
17816         changelog_register || error "first changelog_register failed"
17817         changelog_register || error "second changelog_register failed"
17818         local cl_users
17819         declare -A cl_user1
17820         declare -A cl_user2
17821         local user_rec1
17822         local user_rec2
17823         local i
17824
17825         # generate some changelog records to accumulate on each MDT
17826         # use all_char because created files should be evenly distributed
17827         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17828                 error "test_mkdir $tdir failed"
17829         for ((i = 0; i < MDSCOUNT; i++)); do
17830                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17831                         error "create $DIR/$tdir/d$i.1 failed"
17832         done
17833
17834         # check changelogs have been generated
17835         local nbcl=$(changelog_dump | wc -l)
17836         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17837
17838         for param in "changelog_max_idle_time=10" \
17839                      "changelog_gc=1" \
17840                      "changelog_min_gc_interval=2"; do
17841                 local MDT0=$(facet_svc $SINGLEMDS)
17842                 local var="${param%=*}"
17843                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17844
17845                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17846                 do_nodes $mdts $LCTL set_param mdd.*.$param
17847         done
17848
17849         # force cl_user2 to be idle (1st part)
17850         sleep 9
17851
17852         for i in $(seq $MDSCOUNT); do
17853                 cl_users=(${CL_USERS[mds$i]})
17854                 cl_user1[mds$i]="${cl_users[0]}"
17855                 cl_user2[mds$i]="${cl_users[1]}"
17856
17857                 [ -n "${cl_user1[mds$i]}" ] ||
17858                         error "mds$i: no user registered"
17859                 [ -n "${cl_user2[mds$i]}" ] ||
17860                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17861
17862                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17863                 [ -n "$user_rec1" ] ||
17864                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17865                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17866                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17867                 [ -n "$user_rec2" ] ||
17868                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17869                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17870                      "$user_rec1 + 2 == $user_rec2"
17871                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17872                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17873                               "$user_rec1 + 2, but is $user_rec2"
17874                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17875                 [ -n "$user_rec2" ] ||
17876                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17877                 [ $user_rec1 == $user_rec2 ] ||
17878                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17879                               "$user_rec1, but is $user_rec2"
17880         done
17881
17882         # force cl_user2 to be idle (2nd part) and to reach
17883         # changelog_max_idle_time
17884         sleep 2
17885
17886         # force each GC-thread start and block then
17887         # one per MDT/MDD, set fail_val accordingly
17888         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17889         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17890
17891         # generate more changelogs to trigger fail_loc
17892         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17893                 error "create $DIR/$tdir/${tfile}bis failed"
17894
17895         # stop MDT to stop GC-thread, should be done in back-ground as it will
17896         # block waiting for the thread to be released and exit
17897         declare -A stop_pids
17898         for i in $(seq $MDSCOUNT); do
17899                 stop mds$i &
17900                 stop_pids[mds$i]=$!
17901         done
17902
17903         for i in $(mdts_nodes); do
17904                 local facet
17905                 local nb=0
17906                 local facets=$(facets_up_on_host $i)
17907
17908                 for facet in ${facets//,/ }; do
17909                         if [[ $facet == mds* ]]; then
17910                                 nb=$((nb + 1))
17911                         fi
17912                 done
17913                 # ensure each MDS's gc threads are still present and all in "R"
17914                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17915                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17916                         error "$i: expected $nb GC-thread"
17917                 wait_update $i \
17918                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17919                         "R" 20 ||
17920                         error "$i: GC-thread not found in R-state"
17921                 # check umounts of each MDT on MDS have reached kthread_stop()
17922                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17923                         error "$i: expected $nb umount"
17924                 wait_update $i \
17925                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17926                         error "$i: umount not found in D-state"
17927         done
17928
17929         # release all GC-threads
17930         do_nodes $mdts $LCTL set_param fail_loc=0
17931
17932         # wait for MDT stop to complete
17933         for i in $(seq $MDSCOUNT); do
17934                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17935         done
17936
17937         # XXX
17938         # may try to check if any orphan changelog records are present
17939         # via ldiskfs/zfs and llog_reader...
17940
17941         # re-start/mount MDTs
17942         for i in $(seq $MDSCOUNT); do
17943                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17944                         error "Fail to start mds$i"
17945         done
17946
17947         local first_rec
17948         for i in $(seq $MDSCOUNT); do
17949                 # check cl_user1 still registered
17950                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17951                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17952                 # check cl_user2 unregistered
17953                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17954                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17955
17956                 # check changelogs are present and starting at $user_rec1 + 1
17957                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17958                 [ -n "$user_rec1" ] ||
17959                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17960                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17961                             awk '{ print $1; exit; }')
17962
17963                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17964                 [ $((user_rec1 + 1)) == $first_rec ] ||
17965                         error "mds$i: first index should be $user_rec1 + 1, " \
17966                               "but is $first_rec"
17967         done
17968 }
17969 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17970               "during mount"
17971
17972 test_160i() {
17973
17974         local mdts=$(comma_list $(mdts_nodes))
17975
17976         changelog_register || error "first changelog_register failed"
17977
17978         # generate some changelog records to accumulate on each MDT
17979         # use all_char because created files should be evenly distributed
17980         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17981                 error "test_mkdir $tdir failed"
17982         for ((i = 0; i < MDSCOUNT; i++)); do
17983                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17984                         error "create $DIR/$tdir/d$i.1 failed"
17985         done
17986
17987         # check changelogs have been generated
17988         local nbcl=$(changelog_dump | wc -l)
17989         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17990
17991         # simulate race between register and unregister
17992         # XXX as fail_loc is set per-MDS, with DNE configs the race
17993         # simulation will only occur for one MDT per MDS and for the
17994         # others the normal race scenario will take place
17995         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17996         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17997         do_nodes $mdts $LCTL set_param fail_val=1
17998
17999         # unregister 1st user
18000         changelog_deregister &
18001         local pid1=$!
18002         # wait some time for deregister work to reach race rdv
18003         sleep 2
18004         # register 2nd user
18005         changelog_register || error "2nd user register failed"
18006
18007         wait $pid1 || error "1st user deregister failed"
18008
18009         local i
18010         local last_rec
18011         declare -A LAST_REC
18012         for i in $(seq $MDSCOUNT); do
18013                 if changelog_users mds$i | grep "^cl"; then
18014                         # make sure new records are added with one user present
18015                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18016                                           awk '/^current.index:/ { print $NF }')
18017                 else
18018                         error "mds$i has no user registered"
18019                 fi
18020         done
18021
18022         # generate more changelog records to accumulate on each MDT
18023         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18024                 error "create $DIR/$tdir/${tfile}bis failed"
18025
18026         for i in $(seq $MDSCOUNT); do
18027                 last_rec=$(changelog_users $SINGLEMDS |
18028                            awk '/^current.index:/ { print $NF }')
18029                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18030                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18031                         error "changelogs are off on mds$i"
18032         done
18033 }
18034 run_test 160i "changelog user register/unregister race"
18035
18036 test_160j() {
18037         remote_mds_nodsh && skip "remote MDS with nodsh"
18038         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18039                 skip "Need MDS version at least 2.12.56"
18040
18041         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18042         stack_trap "umount $MOUNT2" EXIT
18043
18044         changelog_register || error "first changelog_register failed"
18045         stack_trap "changelog_deregister" EXIT
18046
18047         # generate some changelog
18048         # use all_char because created files should be evenly distributed
18049         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18050                 error "mkdir $tdir failed"
18051         for ((i = 0; i < MDSCOUNT; i++)); do
18052                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18053                         error "create $DIR/$tdir/d$i.1 failed"
18054         done
18055
18056         # open the changelog device
18057         exec 3>/dev/changelog-$FSNAME-MDT0000
18058         stack_trap "exec 3>&-" EXIT
18059         exec 4</dev/changelog-$FSNAME-MDT0000
18060         stack_trap "exec 4<&-" EXIT
18061
18062         # umount the first lustre mount
18063         umount $MOUNT
18064         stack_trap "mount_client $MOUNT" EXIT
18065
18066         # read changelog, which may or may not fail, but should not crash
18067         cat <&4 >/dev/null
18068
18069         # clear changelog
18070         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18071         changelog_users $SINGLEMDS | grep -q $cl_user ||
18072                 error "User $cl_user not found in changelog_users"
18073
18074         printf 'clear:'$cl_user':0' >&3
18075 }
18076 run_test 160j "client can be umounted while its chanangelog is being used"
18077
18078 test_160k() {
18079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18080         remote_mds_nodsh && skip "remote MDS with nodsh"
18081
18082         mkdir -p $DIR/$tdir/1/1
18083
18084         changelog_register || error "changelog_register failed"
18085         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18086
18087         changelog_users $SINGLEMDS | grep -q $cl_user ||
18088                 error "User '$cl_user' not found in changelog_users"
18089 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18090         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18091         rmdir $DIR/$tdir/1/1 & sleep 1
18092         mkdir $DIR/$tdir/2
18093         touch $DIR/$tdir/2/2
18094         rm -rf $DIR/$tdir/2
18095
18096         wait
18097         sleep 4
18098
18099         changelog_dump | grep rmdir || error "rmdir not recorded"
18100 }
18101 run_test 160k "Verify that changelog records are not lost"
18102
18103 # Verifies that a file passed as a parameter has recently had an operation
18104 # performed on it that has generated an MTIME changelog which contains the
18105 # correct parent FID. As files might reside on a different MDT from the
18106 # parent directory in DNE configurations, the FIDs are translated to paths
18107 # before being compared, which should be identical
18108 compare_mtime_changelog() {
18109         local file="${1}"
18110         local mdtidx
18111         local mtime
18112         local cl_fid
18113         local pdir
18114         local dir
18115
18116         mdtidx=$($LFS getstripe --mdt-index $file)
18117         mdtidx=$(printf "%04x" $mdtidx)
18118
18119         # Obtain the parent FID from the MTIME changelog
18120         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18121         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18122
18123         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18124         [ -z "$cl_fid" ] && error "parent FID not present"
18125
18126         # Verify that the path for the parent FID is the same as the path for
18127         # the test directory
18128         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18129
18130         dir=$(dirname $1)
18131
18132         [[ "${pdir%/}" == "$dir" ]] ||
18133                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18134 }
18135
18136 test_160l() {
18137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18138
18139         remote_mds_nodsh && skip "remote MDS with nodsh"
18140         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18141                 skip "Need MDS version at least 2.13.55"
18142
18143         local cl_user
18144
18145         changelog_register || error "changelog_register failed"
18146         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18147
18148         changelog_users $SINGLEMDS | grep -q $cl_user ||
18149                 error "User '$cl_user' not found in changelog_users"
18150
18151         # Clear some types so that MTIME changelogs are generated
18152         changelog_chmask "-CREAT"
18153         changelog_chmask "-CLOSE"
18154
18155         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18156
18157         # Test CL_MTIME during setattr
18158         touch $DIR/$tdir/$tfile
18159         compare_mtime_changelog $DIR/$tdir/$tfile
18160
18161         # Test CL_MTIME during close
18162         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18163         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18164 }
18165 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18166
18167 test_160m() {
18168         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18169         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18170                 skip "Need MDS version at least 2.14.51"
18171         local cl_users
18172         local cl_user1
18173         local cl_user2
18174         local pid1
18175
18176         # Create a user
18177         changelog_register || error "first changelog_register failed"
18178         changelog_register || error "second changelog_register failed"
18179
18180         cl_users=(${CL_USERS[mds1]})
18181         cl_user1="${cl_users[0]}"
18182         cl_user2="${cl_users[1]}"
18183         # generate some changelog records to accumulate on MDT0
18184         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18185         createmany -m $DIR/$tdir/$tfile 50 ||
18186                 error "create $DIR/$tdir/$tfile failed"
18187         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18188         rm -f $DIR/$tdir
18189
18190         # check changelogs have been generated
18191         local nbcl=$(changelog_dump | wc -l)
18192         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18193
18194 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18195         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18196
18197         __changelog_clear mds1 $cl_user1 +10
18198         __changelog_clear mds1 $cl_user2 0 &
18199         pid1=$!
18200         sleep 2
18201         __changelog_clear mds1 $cl_user1 0 ||
18202                 error "fail to cancel record for $cl_user1"
18203         wait $pid1
18204         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18205 }
18206 run_test 160m "Changelog clear race"
18207
18208 test_160n() {
18209         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18210         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18211                 skip "Need MDS version at least 2.14.51"
18212         local cl_users
18213         local cl_user1
18214         local cl_user2
18215         local pid1
18216         local first_rec
18217         local last_rec=0
18218
18219         # Create a user
18220         changelog_register || error "first changelog_register failed"
18221
18222         cl_users=(${CL_USERS[mds1]})
18223         cl_user1="${cl_users[0]}"
18224
18225         # generate some changelog records to accumulate on MDT0
18226         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18227         first_rec=$(changelog_users $SINGLEMDS |
18228                         awk '/^current.index:/ { print $NF }')
18229         while (( last_rec < (( first_rec + 65000)) )); do
18230                 createmany -m $DIR/$tdir/$tfile 10000 ||
18231                         error "create $DIR/$tdir/$tfile failed"
18232
18233                 for i in $(seq 0 10000); do
18234                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18235                                 > /dev/null
18236                 done
18237
18238                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18239                         error "unlinkmany failed unlink"
18240                 last_rec=$(changelog_users $SINGLEMDS |
18241                         awk '/^current.index:/ { print $NF }')
18242                 echo last record $last_rec
18243                 (( last_rec == 0 )) && error "no changelog found"
18244         done
18245
18246 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18247         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18248
18249         __changelog_clear mds1 $cl_user1 0 &
18250         pid1=$!
18251         sleep 2
18252         __changelog_clear mds1 $cl_user1 0 ||
18253                 error "fail to cancel record for $cl_user1"
18254         wait $pid1
18255         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18256 }
18257 run_test 160n "Changelog destroy race"
18258
18259 test_160o() {
18260         local mdt="$(facet_svc $SINGLEMDS)"
18261
18262         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18263         remote_mds_nodsh && skip "remote MDS with nodsh"
18264         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18265                 skip "Need MDS version at least 2.14.52"
18266
18267         changelog_register --user test_160o -m unlnk+close+open ||
18268                 error "changelog_register failed"
18269
18270         do_facet $SINGLEMDS $LCTL --device $mdt \
18271                                 changelog_register -u "Tt3_-#" &&
18272                 error "bad symbols in name should fail"
18273
18274         do_facet $SINGLEMDS $LCTL --device $mdt \
18275                                 changelog_register -u test_160o &&
18276                 error "the same name registration should fail"
18277
18278         do_facet $SINGLEMDS $LCTL --device $mdt \
18279                         changelog_register -u test_160toolongname &&
18280                 error "too long name registration should fail"
18281
18282         changelog_chmask "MARK+HSM"
18283         lctl get_param mdd.*.changelog*mask
18284         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18285         changelog_users $SINGLEMDS | grep -q $cl_user ||
18286                 error "User $cl_user not found in changelog_users"
18287         #verify username
18288         echo $cl_user | grep -q test_160o ||
18289                 error "User $cl_user has no specific name 'test160o'"
18290
18291         # change something
18292         changelog_clear 0 || error "changelog_clear failed"
18293         # generate some changelog records to accumulate on MDT0
18294         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18295         touch $DIR/$tdir/$tfile                 # open 1
18296
18297         OPENS=$(changelog_dump | grep -c "OPEN")
18298         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18299
18300         # must be no MKDIR it wasn't set as user mask
18301         MKDIR=$(changelog_dump | grep -c "MKDIR")
18302         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18303
18304         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18305                                 mdd.$mdt.changelog_current_mask -n)
18306         # register maskless user
18307         changelog_register || error "changelog_register failed"
18308         # effective mask should be not changed because it is not minimal
18309         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18310                                 mdd.$mdt.changelog_current_mask -n)
18311         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18312         # set server mask to minimal value
18313         changelog_chmask "MARK"
18314         # check effective mask again, should be treated as DEFMASK now
18315         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18316                                 mdd.$mdt.changelog_current_mask -n)
18317         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18318
18319         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18320                 # set server mask back to some value
18321                 changelog_chmask "CLOSE,UNLNK"
18322                 # check effective mask again, should not remain as DEFMASK
18323                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18324                                 mdd.$mdt.changelog_current_mask -n)
18325                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18326         fi
18327
18328         do_facet $SINGLEMDS $LCTL --device $mdt \
18329                                 changelog_deregister -u test_160o ||
18330                 error "cannot deregister by name"
18331 }
18332 run_test 160o "changelog user name and mask"
18333
18334 test_160p() {
18335         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18336         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18337                 skip "Need MDS version at least 2.14.51"
18338         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18339         local cl_users
18340         local cl_user1
18341         local entry_count
18342
18343         # Create a user
18344         changelog_register || error "first changelog_register failed"
18345
18346         cl_users=(${CL_USERS[mds1]})
18347         cl_user1="${cl_users[0]}"
18348
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 -rf $DIR/$tdir
18354
18355         # check changelogs have been generated
18356         entry_count=$(changelog_dump | wc -l)
18357         ((entry_count != 0)) || error "no changelog entries found"
18358
18359         # remove changelog_users and check that orphan entries are removed
18360         stop mds1
18361         local dev=$(mdsdevname 1)
18362         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18363         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18364         entry_count=$(changelog_dump | wc -l)
18365         ((entry_count == 0)) ||
18366                 error "found $entry_count changelog entries, expected none"
18367 }
18368 run_test 160p "Changelog orphan cleanup with no users"
18369
18370 test_160q() {
18371         local mdt="$(facet_svc $SINGLEMDS)"
18372         local clu
18373
18374         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18375         remote_mds_nodsh && skip "remote MDS with nodsh"
18376         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18377                 skip "Need MDS version at least 2.14.54"
18378
18379         # set server mask to minimal value like server init does
18380         changelog_chmask "MARK"
18381         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18382                 error "changelog_register failed"
18383         # check effective mask again, should be treated as DEFMASK now
18384         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18385                                 mdd.$mdt.changelog_current_mask -n)
18386         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18387                 error "changelog_deregister failed"
18388         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18389 }
18390 run_test 160q "changelog effective mask is DEFMASK if not set"
18391
18392 test_160s() {
18393         remote_mds_nodsh && skip "remote MDS with nodsh"
18394         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18395                 skip "Need MDS version at least 2.14.55"
18396
18397         local mdts=$(comma_list $(mdts_nodes))
18398
18399         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18400         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18401                                        fail_val=$((24 * 3600 * 10))
18402
18403         # Create a user which is 10 days old
18404         changelog_register || error "first changelog_register failed"
18405         local cl_users
18406         declare -A cl_user1
18407         local i
18408
18409         # generate some changelog records to accumulate on each MDT
18410         # use all_char because created files should be evenly distributed
18411         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18412                 error "test_mkdir $tdir failed"
18413         for ((i = 0; i < MDSCOUNT; i++)); do
18414                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18415                         error "create $DIR/$tdir/d$i.1 failed"
18416         done
18417
18418         # check changelogs have been generated
18419         local nbcl=$(changelog_dump | wc -l)
18420         (( nbcl > 0 )) || error "no changelogs found"
18421
18422         # reduce the max_idle_indexes value to make sure we exceed it
18423         for param in "changelog_max_idle_indexes=2097446912" \
18424                      "changelog_max_idle_time=2592000" \
18425                      "changelog_gc=1" \
18426                      "changelog_min_gc_interval=2"; do
18427                 local MDT0=$(facet_svc $SINGLEMDS)
18428                 local var="${param%=*}"
18429                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18430
18431                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18432                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18433                         error "unable to set mdd.*.$param"
18434         done
18435
18436         local start=$SECONDS
18437         for i in $(seq $MDSCOUNT); do
18438                 cl_users=(${CL_USERS[mds$i]})
18439                 cl_user1[mds$i]="${cl_users[0]}"
18440
18441                 [[ -n "${cl_user1[mds$i]}" ]] ||
18442                         error "mds$i: no user registered"
18443         done
18444
18445         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18446         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18447
18448         # ensure we are past the previous changelog_min_gc_interval set above
18449         local sleep2=$((start + 2 - SECONDS))
18450         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18451
18452         # Generate one more changelog to trigger GC
18453         for ((i = 0; i < MDSCOUNT; i++)); do
18454                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18455                         error "create $DIR/$tdir/d$i.3 failed"
18456         done
18457
18458         # ensure gc thread is done
18459         for node in $(mdts_nodes); do
18460                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18461                         error "$node: GC-thread not done"
18462         done
18463
18464         do_nodes $mdts $LCTL set_param fail_loc=0
18465
18466         for (( i = 1; i <= MDSCOUNT; i++ )); do
18467                 # check cl_user1 is purged
18468                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18469                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18470         done
18471         return 0
18472 }
18473 run_test 160s "changelog garbage collect on idle records * time"
18474
18475 test_160t() {
18476         remote_mds_nodsh && skip "remote MDS with nodsh"
18477         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18478                 skip "Need MDS version at least 2.15.50"
18479
18480         local MDT0=$(facet_svc $SINGLEMDS)
18481         local cl_users
18482         local cl_user1
18483         local cl_user2
18484         local start
18485
18486         changelog_register --user user1 -m all ||
18487                 error "user1 failed to register"
18488
18489         mkdir_on_mdt0 $DIR/$tdir
18490         # create default overstripe to maximize changelog size
18491         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18492         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18493         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18494
18495         # user2 consumes less records so less space
18496         changelog_register --user user2 || error "user2 failed to register"
18497         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18498         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18499
18500         # check changelogs have been generated
18501         local nbcl=$(changelog_dump | wc -l)
18502         (( nbcl > 0 )) || error "no changelogs found"
18503
18504         # reduce the changelog_min_gc_interval to force check
18505         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18506                 local var="${param%=*}"
18507                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18508
18509                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18510                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18511                         error "unable to set mdd.*.$param"
18512         done
18513
18514         start=$SECONDS
18515         cl_users=(${CL_USERS[mds1]})
18516         cl_user1="${cl_users[0]}"
18517         cl_user2="${cl_users[1]}"
18518
18519         [[ -n $cl_user1 ]] ||
18520                 error "mds1: user #1 isn't registered"
18521         [[ -n $cl_user2 ]] ||
18522                 error "mds1: user #2 isn't registered"
18523
18524         # ensure we are past the previous changelog_min_gc_interval set above
18525         local sleep2=$((start + 2 - SECONDS))
18526         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18527
18528         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18529         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18530                         fail_val=$(((llog_size1 + llog_size2) / 2))
18531
18532         # Generate more changelog to trigger GC
18533         createmany -o $DIR/$tdir/u3_ 4 ||
18534                 error "create failed for more files"
18535
18536         # ensure gc thread is done
18537         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18538                 error "mds1: GC-thread not done"
18539
18540         do_facet mds1 $LCTL set_param fail_loc=0
18541
18542         # check cl_user1 is purged
18543         changelog_users mds1 | grep -q "$cl_user1" &&
18544                 error "User $cl_user1 is registered"
18545         # check cl_user2 is not purged
18546         changelog_users mds1 | grep -q "$cl_user2" ||
18547                 error "User $cl_user2 is not registered"
18548 }
18549 run_test 160t "changelog garbage collect on lack of space"
18550
18551 test_161a() {
18552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18553
18554         test_mkdir -c1 $DIR/$tdir
18555         cp /etc/hosts $DIR/$tdir/$tfile
18556         test_mkdir -c1 $DIR/$tdir/foo1
18557         test_mkdir -c1 $DIR/$tdir/foo2
18558         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18559         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18560         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18561         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18562         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18563         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18564                 $LFS fid2path $DIR $FID
18565                 error "bad link ea"
18566         fi
18567         # middle
18568         rm $DIR/$tdir/foo2/zachary
18569         # last
18570         rm $DIR/$tdir/foo2/thor
18571         # first
18572         rm $DIR/$tdir/$tfile
18573         # rename
18574         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18575         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18576                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18577         rm $DIR/$tdir/foo2/maggie
18578
18579         # overflow the EA
18580         local longname=$tfile.avg_len_is_thirty_two_
18581         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18582                 error_noexit 'failed to unlink many hardlinks'" EXIT
18583         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18584                 error "failed to hardlink many files"
18585         links=$($LFS fid2path $DIR $FID | wc -l)
18586         echo -n "${links}/1000 links in link EA"
18587         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18588 }
18589 run_test 161a "link ea sanity"
18590
18591 test_161b() {
18592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18593         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18594
18595         local MDTIDX=1
18596         local remote_dir=$DIR/$tdir/remote_dir
18597
18598         mkdir -p $DIR/$tdir
18599         $LFS mkdir -i $MDTIDX $remote_dir ||
18600                 error "create remote directory failed"
18601
18602         cp /etc/hosts $remote_dir/$tfile
18603         mkdir -p $remote_dir/foo1
18604         mkdir -p $remote_dir/foo2
18605         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18606         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18607         ln $remote_dir/$tfile $remote_dir/foo1/luna
18608         ln $remote_dir/$tfile $remote_dir/foo2/thor
18609
18610         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18611                      tr -d ']')
18612         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18613                 $LFS fid2path $DIR $FID
18614                 error "bad link ea"
18615         fi
18616         # middle
18617         rm $remote_dir/foo2/zachary
18618         # last
18619         rm $remote_dir/foo2/thor
18620         # first
18621         rm $remote_dir/$tfile
18622         # rename
18623         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18624         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18625         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18626                 $LFS fid2path $DIR $FID
18627                 error "bad link rename"
18628         fi
18629         rm $remote_dir/foo2/maggie
18630
18631         # overflow the EA
18632         local longname=filename_avg_len_is_thirty_two_
18633         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18634                 error "failed to hardlink many files"
18635         links=$($LFS fid2path $DIR $FID | wc -l)
18636         echo -n "${links}/1000 links in link EA"
18637         [[ ${links} -gt 60 ]] ||
18638                 error "expected at least 60 links in link EA"
18639         unlinkmany $remote_dir/foo2/$longname 1000 ||
18640         error "failed to unlink many hardlinks"
18641 }
18642 run_test 161b "link ea sanity under remote directory"
18643
18644 test_161c() {
18645         remote_mds_nodsh && skip "remote MDS with nodsh"
18646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18647         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18648                 skip "Need MDS version at least 2.1.5"
18649
18650         # define CLF_RENAME_LAST 0x0001
18651         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18652         changelog_register || error "changelog_register failed"
18653
18654         rm -rf $DIR/$tdir
18655         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18656         touch $DIR/$tdir/foo_161c
18657         touch $DIR/$tdir/bar_161c
18658         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18659         changelog_dump | grep RENME | tail -n 5
18660         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18661         changelog_clear 0 || error "changelog_clear failed"
18662         if [ x$flags != "x0x1" ]; then
18663                 error "flag $flags is not 0x1"
18664         fi
18665
18666         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18667         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18668         touch $DIR/$tdir/foo_161c
18669         touch $DIR/$tdir/bar_161c
18670         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18671         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18672         changelog_dump | grep RENME | tail -n 5
18673         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18674         changelog_clear 0 || error "changelog_clear failed"
18675         if [ x$flags != "x0x0" ]; then
18676                 error "flag $flags is not 0x0"
18677         fi
18678         echo "rename overwrite a target having nlink > 1," \
18679                 "changelog record has flags of $flags"
18680
18681         # rename doesn't overwrite a target (changelog flag 0x0)
18682         touch $DIR/$tdir/foo_161c
18683         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18684         changelog_dump | grep RENME | tail -n 5
18685         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18686         changelog_clear 0 || error "changelog_clear failed"
18687         if [ x$flags != "x0x0" ]; then
18688                 error "flag $flags is not 0x0"
18689         fi
18690         echo "rename doesn't overwrite a target," \
18691                 "changelog record has flags of $flags"
18692
18693         # define CLF_UNLINK_LAST 0x0001
18694         # unlink a file having nlink = 1 (changelog flag 0x1)
18695         rm -f $DIR/$tdir/foo2_161c
18696         changelog_dump | grep UNLNK | tail -n 5
18697         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18698         changelog_clear 0 || error "changelog_clear failed"
18699         if [ x$flags != "x0x1" ]; then
18700                 error "flag $flags is not 0x1"
18701         fi
18702         echo "unlink a file having nlink = 1," \
18703                 "changelog record has flags of $flags"
18704
18705         # unlink a file having nlink > 1 (changelog flag 0x0)
18706         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18707         rm -f $DIR/$tdir/foobar_161c
18708         changelog_dump | grep UNLNK | tail -n 5
18709         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18710         changelog_clear 0 || error "changelog_clear failed"
18711         if [ x$flags != "x0x0" ]; then
18712                 error "flag $flags is not 0x0"
18713         fi
18714         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18715 }
18716 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18717
18718 test_161d() {
18719         remote_mds_nodsh && skip "remote MDS with nodsh"
18720         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18721
18722         local pid
18723         local fid
18724
18725         changelog_register || error "changelog_register failed"
18726
18727         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18728         # interfer with $MOUNT/.lustre/fid/ access
18729         mkdir $DIR/$tdir
18730         [[ $? -eq 0 ]] || error "mkdir failed"
18731
18732         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18733         $LCTL set_param fail_loc=0x8000140c
18734         # 5s pause
18735         $LCTL set_param fail_val=5
18736
18737         # create file
18738         echo foofoo > $DIR/$tdir/$tfile &
18739         pid=$!
18740
18741         # wait for create to be delayed
18742         sleep 2
18743
18744         ps -p $pid
18745         [[ $? -eq 0 ]] || error "create should be blocked"
18746
18747         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18748         stack_trap "rm -f $tempfile"
18749         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18750         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18751         # some delay may occur during ChangeLog publishing and file read just
18752         # above, that could allow file write to happen finally
18753         [[ -s $tempfile ]] && echo "file should be empty"
18754
18755         $LCTL set_param fail_loc=0
18756
18757         wait $pid
18758         [[ $? -eq 0 ]] || error "create failed"
18759 }
18760 run_test 161d "create with concurrent .lustre/fid access"
18761
18762 check_path() {
18763         local expected="$1"
18764         shift
18765         local fid="$2"
18766
18767         local path
18768         path=$($LFS fid2path "$@")
18769         local rc=$?
18770
18771         if [ $rc -ne 0 ]; then
18772                 error "path looked up of '$expected' failed: rc=$rc"
18773         elif [ "$path" != "$expected" ]; then
18774                 error "path looked up '$path' instead of '$expected'"
18775         else
18776                 echo "FID '$fid' resolves to path '$path' as expected"
18777         fi
18778 }
18779
18780 test_162a() { # was test_162
18781         test_mkdir -p -c1 $DIR/$tdir/d2
18782         touch $DIR/$tdir/d2/$tfile
18783         touch $DIR/$tdir/d2/x1
18784         touch $DIR/$tdir/d2/x2
18785         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18786         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18787         # regular file
18788         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18789         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18790
18791         # softlink
18792         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18793         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18794         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18795
18796         # softlink to wrong file
18797         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18798         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18799         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18800
18801         # hardlink
18802         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18803         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18804         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18805         # fid2path dir/fsname should both work
18806         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18807         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18808
18809         # hardlink count: check that there are 2 links
18810         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18811         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18812
18813         # hardlink indexing: remove the first link
18814         rm $DIR/$tdir/d2/p/q/r/hlink
18815         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18816 }
18817 run_test 162a "path lookup sanity"
18818
18819 test_162b() {
18820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18822
18823         mkdir $DIR/$tdir
18824         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18825                                 error "create striped dir failed"
18826
18827         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18828                                         tail -n 1 | awk '{print $2}')
18829         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18830
18831         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18832         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18833
18834         # regular file
18835         for ((i=0;i<5;i++)); do
18836                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18837                         error "get fid for f$i failed"
18838                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18839
18840                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18841                         error "get fid for d$i failed"
18842                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18843         done
18844
18845         return 0
18846 }
18847 run_test 162b "striped directory path lookup sanity"
18848
18849 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18850 test_162c() {
18851         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18852                 skip "Need MDS version at least 2.7.51"
18853
18854         local lpath=$tdir.local
18855         local rpath=$tdir.remote
18856
18857         test_mkdir $DIR/$lpath
18858         test_mkdir $DIR/$rpath
18859
18860         for ((i = 0; i <= 101; i++)); do
18861                 lpath="$lpath/$i"
18862                 mkdir $DIR/$lpath
18863                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18864                         error "get fid for local directory $DIR/$lpath failed"
18865                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18866
18867                 rpath="$rpath/$i"
18868                 test_mkdir $DIR/$rpath
18869                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18870                         error "get fid for remote directory $DIR/$rpath failed"
18871                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18872         done
18873
18874         return 0
18875 }
18876 run_test 162c "fid2path works with paths 100 or more directories deep"
18877
18878 oalr_event_count() {
18879         local event="${1}"
18880         local trace="${2}"
18881
18882         awk -v name="${FSNAME}-OST0000" \
18883             -v event="${event}" \
18884             '$1 == "TRACE" && $2 == event && $3 == name' \
18885             "${trace}" |
18886         wc -l
18887 }
18888
18889 oalr_expect_event_count() {
18890         local event="${1}"
18891         local trace="${2}"
18892         local expect="${3}"
18893         local count
18894
18895         count=$(oalr_event_count "${event}" "${trace}")
18896         if ((count == expect)); then
18897                 return 0
18898         fi
18899
18900         error_noexit "${event} event count was '${count}', expected ${expect}"
18901         cat "${trace}" >&2
18902         exit 1
18903 }
18904
18905 cleanup_165() {
18906         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18907         stop ost1
18908         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18909 }
18910
18911 setup_165() {
18912         sync # Flush previous IOs so we can count log entries.
18913         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18914         stack_trap cleanup_165 EXIT
18915 }
18916
18917 test_165a() {
18918         local trace="/tmp/${tfile}.trace"
18919         local rc
18920         local count
18921
18922         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18923                 skip "OFD access log unsupported"
18924
18925         setup_165
18926         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18927         sleep 5
18928
18929         do_facet ost1 ofd_access_log_reader --list
18930         stop ost1
18931
18932         do_facet ost1 killall -TERM ofd_access_log_reader
18933         wait
18934         rc=$?
18935
18936         if ((rc != 0)); then
18937                 error "ofd_access_log_reader exited with rc = '${rc}'"
18938         fi
18939
18940         # Parse trace file for discovery events:
18941         oalr_expect_event_count alr_log_add "${trace}" 1
18942         oalr_expect_event_count alr_log_eof "${trace}" 1
18943         oalr_expect_event_count alr_log_free "${trace}" 1
18944 }
18945 run_test 165a "ofd access log discovery"
18946
18947 test_165b() {
18948         local trace="/tmp/${tfile}.trace"
18949         local file="${DIR}/${tfile}"
18950         local pfid1
18951         local pfid2
18952         local -a entry
18953         local rc
18954         local count
18955         local size
18956         local flags
18957
18958         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18959                 skip "OFD access log unsupported"
18960
18961         setup_165
18962         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18963         sleep 5
18964
18965         do_facet ost1 ofd_access_log_reader --list
18966
18967         lfs setstripe -c 1 -i 0 "${file}"
18968         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18969                 error "cannot create '${file}'"
18970
18971         sleep 5
18972         do_facet ost1 killall -TERM ofd_access_log_reader
18973         wait
18974         rc=$?
18975
18976         if ((rc != 0)); then
18977                 error "ofd_access_log_reader exited with rc = '${rc}'"
18978         fi
18979
18980         oalr_expect_event_count alr_log_entry "${trace}" 1
18981
18982         pfid1=$($LFS path2fid "${file}")
18983
18984         # 1     2             3   4    5     6   7    8    9     10
18985         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18986         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18987
18988         echo "entry = '${entry[*]}'" >&2
18989
18990         pfid2=${entry[4]}
18991         if [[ "${pfid1}" != "${pfid2}" ]]; then
18992                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18993         fi
18994
18995         size=${entry[8]}
18996         if ((size != 1048576)); then
18997                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18998         fi
18999
19000         flags=${entry[10]}
19001         if [[ "${flags}" != "w" ]]; then
19002                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19003         fi
19004
19005         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19006         sleep 5
19007
19008         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19009                 error "cannot read '${file}'"
19010         sleep 5
19011
19012         do_facet ost1 killall -TERM ofd_access_log_reader
19013         wait
19014         rc=$?
19015
19016         if ((rc != 0)); then
19017                 error "ofd_access_log_reader exited with rc = '${rc}'"
19018         fi
19019
19020         oalr_expect_event_count alr_log_entry "${trace}" 1
19021
19022         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19023         echo "entry = '${entry[*]}'" >&2
19024
19025         pfid2=${entry[4]}
19026         if [[ "${pfid1}" != "${pfid2}" ]]; then
19027                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19028         fi
19029
19030         size=${entry[8]}
19031         if ((size != 524288)); then
19032                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19033         fi
19034
19035         flags=${entry[10]}
19036         if [[ "${flags}" != "r" ]]; then
19037                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19038         fi
19039 }
19040 run_test 165b "ofd access log entries are produced and consumed"
19041
19042 test_165c() {
19043         local trace="/tmp/${tfile}.trace"
19044         local file="${DIR}/${tdir}/${tfile}"
19045
19046         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19047                 skip "OFD access log unsupported"
19048
19049         test_mkdir "${DIR}/${tdir}"
19050
19051         setup_165
19052         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19053         sleep 5
19054
19055         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19056
19057         # 4096 / 64 = 64. Create twice as many entries.
19058         for ((i = 0; i < 128; i++)); do
19059                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19060                         error "cannot create file"
19061         done
19062
19063         sync
19064
19065         do_facet ost1 killall -TERM ofd_access_log_reader
19066         wait
19067         rc=$?
19068         if ((rc != 0)); then
19069                 error "ofd_access_log_reader exited with rc = '${rc}'"
19070         fi
19071
19072         unlinkmany  "${file}-%d" 128
19073 }
19074 run_test 165c "full ofd access logs do not block IOs"
19075
19076 oal_get_read_count() {
19077         local stats="$1"
19078
19079         # STATS lustre-OST0001 alr_read_count 1
19080
19081         do_facet ost1 cat "${stats}" |
19082         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19083              END { print count; }'
19084 }
19085
19086 oal_expect_read_count() {
19087         local stats="$1"
19088         local count
19089         local expect="$2"
19090
19091         # Ask ofd_access_log_reader to write stats.
19092         do_facet ost1 killall -USR1 ofd_access_log_reader
19093
19094         # Allow some time for things to happen.
19095         sleep 1
19096
19097         count=$(oal_get_read_count "${stats}")
19098         if ((count == expect)); then
19099                 return 0
19100         fi
19101
19102         error_noexit "bad read count, got ${count}, expected ${expect}"
19103         do_facet ost1 cat "${stats}" >&2
19104         exit 1
19105 }
19106
19107 test_165d() {
19108         local stats="/tmp/${tfile}.stats"
19109         local file="${DIR}/${tdir}/${tfile}"
19110         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19111
19112         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19113                 skip "OFD access log unsupported"
19114
19115         test_mkdir "${DIR}/${tdir}"
19116
19117         setup_165
19118         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19119         sleep 5
19120
19121         lfs setstripe -c 1 -i 0 "${file}"
19122
19123         do_facet ost1 lctl set_param "${param}=rw"
19124         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19125                 error "cannot create '${file}'"
19126         oal_expect_read_count "${stats}" 1
19127
19128         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19129                 error "cannot read '${file}'"
19130         oal_expect_read_count "${stats}" 2
19131
19132         do_facet ost1 lctl set_param "${param}=r"
19133         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19134                 error "cannot create '${file}'"
19135         oal_expect_read_count "${stats}" 2
19136
19137         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19138                 error "cannot read '${file}'"
19139         oal_expect_read_count "${stats}" 3
19140
19141         do_facet ost1 lctl set_param "${param}=w"
19142         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19143                 error "cannot create '${file}'"
19144         oal_expect_read_count "${stats}" 4
19145
19146         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19147                 error "cannot read '${file}'"
19148         oal_expect_read_count "${stats}" 4
19149
19150         do_facet ost1 lctl set_param "${param}=0"
19151         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19152                 error "cannot create '${file}'"
19153         oal_expect_read_count "${stats}" 4
19154
19155         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19156                 error "cannot read '${file}'"
19157         oal_expect_read_count "${stats}" 4
19158
19159         do_facet ost1 killall -TERM ofd_access_log_reader
19160         wait
19161         rc=$?
19162         if ((rc != 0)); then
19163                 error "ofd_access_log_reader exited with rc = '${rc}'"
19164         fi
19165 }
19166 run_test 165d "ofd_access_log mask works"
19167
19168 test_165e() {
19169         local stats="/tmp/${tfile}.stats"
19170         local file0="${DIR}/${tdir}-0/${tfile}"
19171         local file1="${DIR}/${tdir}-1/${tfile}"
19172
19173         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19174                 skip "OFD access log unsupported"
19175
19176         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19177
19178         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19179         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19180
19181         lfs setstripe -c 1 -i 0 "${file0}"
19182         lfs setstripe -c 1 -i 0 "${file1}"
19183
19184         setup_165
19185         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19186         sleep 5
19187
19188         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19189                 error "cannot create '${file0}'"
19190         sync
19191         oal_expect_read_count "${stats}" 0
19192
19193         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19194                 error "cannot create '${file1}'"
19195         sync
19196         oal_expect_read_count "${stats}" 1
19197
19198         do_facet ost1 killall -TERM ofd_access_log_reader
19199         wait
19200         rc=$?
19201         if ((rc != 0)); then
19202                 error "ofd_access_log_reader exited with rc = '${rc}'"
19203         fi
19204 }
19205 run_test 165e "ofd_access_log MDT index filter works"
19206
19207 test_165f() {
19208         local trace="/tmp/${tfile}.trace"
19209         local rc
19210         local count
19211
19212         setup_165
19213         do_facet ost1 timeout 60 ofd_access_log_reader \
19214                 --exit-on-close --debug=- --trace=- > "${trace}" &
19215         sleep 5
19216         stop ost1
19217
19218         wait
19219         rc=$?
19220
19221         if ((rc != 0)); then
19222                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19223                 cat "${trace}"
19224                 exit 1
19225         fi
19226 }
19227 run_test 165f "ofd_access_log_reader --exit-on-close works"
19228
19229 test_169() {
19230         # do directio so as not to populate the page cache
19231         log "creating a 10 Mb file"
19232         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19233                 error "multiop failed while creating a file"
19234         log "starting reads"
19235         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19236         log "truncating the file"
19237         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19238                 error "multiop failed while truncating the file"
19239         log "killing dd"
19240         kill %+ || true # reads might have finished
19241         echo "wait until dd is finished"
19242         wait
19243         log "removing the temporary file"
19244         rm -rf $DIR/$tfile || error "tmp file removal failed"
19245 }
19246 run_test 169 "parallel read and truncate should not deadlock"
19247
19248 test_170() {
19249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19250
19251         $LCTL clear     # bug 18514
19252         $LCTL debug_daemon start $TMP/${tfile}_log_good
19253         touch $DIR/$tfile
19254         $LCTL debug_daemon stop
19255         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19256                 error "sed failed to read log_good"
19257
19258         $LCTL debug_daemon start $TMP/${tfile}_log_good
19259         rm -rf $DIR/$tfile
19260         $LCTL debug_daemon stop
19261
19262         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19263                error "lctl df log_bad failed"
19264
19265         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19266         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19267
19268         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19269         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19270
19271         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19272                 error "bad_line good_line1 good_line2 are empty"
19273
19274         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19275         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19276         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19277
19278         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19279         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19280         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19281
19282         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19283                 error "bad_line_new good_line_new are empty"
19284
19285         local expected_good=$((good_line1 + good_line2*2))
19286
19287         rm -f $TMP/${tfile}*
19288         # LU-231, short malformed line may not be counted into bad lines
19289         if [ $bad_line -ne $bad_line_new ] &&
19290                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19291                 error "expected $bad_line bad lines, but got $bad_line_new"
19292                 return 1
19293         fi
19294
19295         if [ $expected_good -ne $good_line_new ]; then
19296                 error "expected $expected_good good lines, but got $good_line_new"
19297                 return 2
19298         fi
19299         true
19300 }
19301 run_test 170 "test lctl df to handle corrupted log ====================="
19302
19303 test_171() { # bug20592
19304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19305
19306         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19307         $LCTL set_param fail_loc=0x50e
19308         $LCTL set_param fail_val=3000
19309         multiop_bg_pause $DIR/$tfile O_s || true
19310         local MULTIPID=$!
19311         kill -USR1 $MULTIPID
19312         # cause log dump
19313         sleep 3
19314         wait $MULTIPID
19315         if dmesg | grep "recursive fault"; then
19316                 error "caught a recursive fault"
19317         fi
19318         $LCTL set_param fail_loc=0
19319         true
19320 }
19321 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19322
19323 test_172() {
19324
19325         #define OBD_FAIL_OBD_CLEANUP  0x60e
19326         $LCTL set_param fail_loc=0x60e
19327         umount $MOUNT || error "umount $MOUNT failed"
19328         stack_trap "mount_client $MOUNT"
19329
19330         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19331                 error "no client OBDs are remained"
19332
19333         $LCTL dl | while read devno state type name foo; do
19334                 case $type in
19335                 lov|osc|lmv|mdc)
19336                         $LCTL --device $name cleanup
19337                         $LCTL --device $name detach
19338                         ;;
19339                 *)
19340                         # skip server devices
19341                         ;;
19342                 esac
19343         done
19344
19345         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19346                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19347                 error "some client OBDs are still remained"
19348         fi
19349
19350 }
19351 run_test 172 "manual device removal with lctl cleanup/detach ======"
19352
19353 # it would be good to share it with obdfilter-survey/iokit-libecho code
19354 setup_obdecho_osc () {
19355         local rc=0
19356         local ost_nid=$1
19357         local obdfilter_name=$2
19358         echo "Creating new osc for $obdfilter_name on $ost_nid"
19359         # make sure we can find loopback nid
19360         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19361
19362         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19363                            ${obdfilter_name}_osc_UUID || rc=2; }
19364         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19365                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19366         return $rc
19367 }
19368
19369 cleanup_obdecho_osc () {
19370         local obdfilter_name=$1
19371         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19372         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19373         return 0
19374 }
19375
19376 obdecho_test() {
19377         local OBD=$1
19378         local node=$2
19379         local pages=${3:-64}
19380         local rc=0
19381         local id
19382
19383         local count=10
19384         local obd_size=$(get_obd_size $node $OBD)
19385         local page_size=$(get_page_size $node)
19386         if [[ -n "$obd_size" ]]; then
19387                 local new_count=$((obd_size / (pages * page_size / 1024)))
19388                 [[ $new_count -ge $count ]] || count=$new_count
19389         fi
19390
19391         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19392         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19393                            rc=2; }
19394         if [ $rc -eq 0 ]; then
19395             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19396             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19397         fi
19398         echo "New object id is $id"
19399         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19400                            rc=4; }
19401         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19402                            "test_brw $count w v $pages $id" || rc=4; }
19403         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19404                            rc=4; }
19405         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19406                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19407         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19408                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19409         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19410         return $rc
19411 }
19412
19413 test_180a() {
19414         skip "obdecho on osc is no longer supported"
19415 }
19416 run_test 180a "test obdecho on osc"
19417
19418 test_180b() {
19419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19420         remote_ost_nodsh && skip "remote OST with nodsh"
19421
19422         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19423                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19424                 error "failed to load module obdecho"
19425
19426         local target=$(do_facet ost1 $LCTL dl |
19427                        awk '/obdfilter/ { print $4; exit; }')
19428
19429         if [ -n "$target" ]; then
19430                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19431         else
19432                 do_facet ost1 $LCTL dl
19433                 error "there is no obdfilter target on ost1"
19434         fi
19435 }
19436 run_test 180b "test obdecho directly on obdfilter"
19437
19438 test_180c() { # LU-2598
19439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19440         remote_ost_nodsh && skip "remote OST with nodsh"
19441         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19442                 skip "Need MDS version at least 2.4.0"
19443
19444         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19445                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19446                 error "failed to load module obdecho"
19447
19448         local target=$(do_facet ost1 $LCTL dl |
19449                        awk '/obdfilter/ { print $4; exit; }')
19450
19451         if [ -n "$target" ]; then
19452                 local pages=16384 # 64MB bulk I/O RPC size
19453
19454                 obdecho_test "$target" ost1 "$pages" ||
19455                         error "obdecho_test with pages=$pages failed with $?"
19456         else
19457                 do_facet ost1 $LCTL dl
19458                 error "there is no obdfilter target on ost1"
19459         fi
19460 }
19461 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19462
19463 test_181() { # bug 22177
19464         test_mkdir $DIR/$tdir
19465         # create enough files to index the directory
19466         createmany -o $DIR/$tdir/foobar 4000
19467         # print attributes for debug purpose
19468         lsattr -d .
19469         # open dir
19470         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19471         MULTIPID=$!
19472         # remove the files & current working dir
19473         unlinkmany $DIR/$tdir/foobar 4000
19474         rmdir $DIR/$tdir
19475         kill -USR1 $MULTIPID
19476         wait $MULTIPID
19477         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19478         return 0
19479 }
19480 run_test 181 "Test open-unlinked dir ========================"
19481
19482 test_182a() {
19483         local fcount=1000
19484         local tcount=10
19485
19486         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19487
19488         $LCTL set_param mdc.*.rpc_stats=clear
19489
19490         for (( i = 0; i < $tcount; i++ )) ; do
19491                 mkdir $DIR/$tdir/$i
19492         done
19493
19494         for (( i = 0; i < $tcount; i++ )) ; do
19495                 createmany -o $DIR/$tdir/$i/f- $fcount &
19496         done
19497         wait
19498
19499         for (( i = 0; i < $tcount; i++ )) ; do
19500                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19501         done
19502         wait
19503
19504         $LCTL get_param mdc.*.rpc_stats
19505
19506         rm -rf $DIR/$tdir
19507 }
19508 run_test 182a "Test parallel modify metadata operations from mdc"
19509
19510 test_182b() {
19511         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19512         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19513         local dcount=1000
19514         local tcount=10
19515         local stime
19516         local etime
19517         local delta
19518
19519         do_facet mds1 $LCTL list_param \
19520                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19521                 skip "MDS lacks parallel RPC handling"
19522
19523         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19524
19525         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19526                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19527
19528         stime=$(date +%s)
19529         createmany -i 0 -d $DIR/$tdir/t- $tcount
19530
19531         for (( i = 0; i < $tcount; i++ )) ; do
19532                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19533         done
19534         wait
19535         etime=$(date +%s)
19536         delta=$((etime - stime))
19537         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19538
19539         stime=$(date +%s)
19540         for (( i = 0; i < $tcount; i++ )) ; do
19541                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19542         done
19543         wait
19544         etime=$(date +%s)
19545         delta=$((etime - stime))
19546         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19547
19548         rm -rf $DIR/$tdir
19549
19550         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19551
19552         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19553
19554         stime=$(date +%s)
19555         createmany -i 0 -d $DIR/$tdir/t- $tcount
19556
19557         for (( i = 0; i < $tcount; i++ )) ; do
19558                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19559         done
19560         wait
19561         etime=$(date +%s)
19562         delta=$((etime - stime))
19563         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19564
19565         stime=$(date +%s)
19566         for (( i = 0; i < $tcount; i++ )) ; do
19567                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19568         done
19569         wait
19570         etime=$(date +%s)
19571         delta=$((etime - stime))
19572         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19573
19574         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19575 }
19576 run_test 182b "Test parallel modify metadata operations from osp"
19577
19578 test_183() { # LU-2275
19579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19580         remote_mds_nodsh && skip "remote MDS with nodsh"
19581         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19582                 skip "Need MDS version at least 2.3.56"
19583
19584         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19585         echo aaa > $DIR/$tdir/$tfile
19586
19587 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19588         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19589
19590         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19591         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19592
19593         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19594
19595         # Flush negative dentry cache
19596         touch $DIR/$tdir/$tfile
19597
19598         # We are not checking for any leaked references here, they'll
19599         # become evident next time we do cleanup with module unload.
19600         rm -rf $DIR/$tdir
19601 }
19602 run_test 183 "No crash or request leak in case of strange dispositions ========"
19603
19604 # test suite 184 is for LU-2016, LU-2017
19605 test_184a() {
19606         check_swap_layouts_support
19607
19608         dir0=$DIR/$tdir/$testnum
19609         test_mkdir -p -c1 $dir0
19610         ref1=/etc/passwd
19611         ref2=/etc/group
19612         file1=$dir0/f1
19613         file2=$dir0/f2
19614         $LFS setstripe -c1 $file1
19615         cp $ref1 $file1
19616         $LFS setstripe -c2 $file2
19617         cp $ref2 $file2
19618         gen1=$($LFS getstripe -g $file1)
19619         gen2=$($LFS getstripe -g $file2)
19620
19621         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19622         gen=$($LFS getstripe -g $file1)
19623         [[ $gen1 != $gen ]] ||
19624                 error "Layout generation on $file1 does not change"
19625         gen=$($LFS getstripe -g $file2)
19626         [[ $gen2 != $gen ]] ||
19627                 error "Layout generation on $file2 does not change"
19628
19629         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19630         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19631
19632         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19633 }
19634 run_test 184a "Basic layout swap"
19635
19636 test_184b() {
19637         check_swap_layouts_support
19638
19639         dir0=$DIR/$tdir/$testnum
19640         mkdir -p $dir0 || error "creating dir $dir0"
19641         file1=$dir0/f1
19642         file2=$dir0/f2
19643         file3=$dir0/f3
19644         dir1=$dir0/d1
19645         dir2=$dir0/d2
19646         mkdir $dir1 $dir2
19647         $LFS setstripe -c1 $file1
19648         $LFS setstripe -c2 $file2
19649         $LFS setstripe -c1 $file3
19650         chown $RUNAS_ID $file3
19651         gen1=$($LFS getstripe -g $file1)
19652         gen2=$($LFS getstripe -g $file2)
19653
19654         $LFS swap_layouts $dir1 $dir2 &&
19655                 error "swap of directories layouts should fail"
19656         $LFS swap_layouts $dir1 $file1 &&
19657                 error "swap of directory and file layouts should fail"
19658         $RUNAS $LFS swap_layouts $file1 $file2 &&
19659                 error "swap of file we cannot write should fail"
19660         $LFS swap_layouts $file1 $file3 &&
19661                 error "swap of file with different owner should fail"
19662         /bin/true # to clear error code
19663 }
19664 run_test 184b "Forbidden layout swap (will generate errors)"
19665
19666 test_184c() {
19667         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19668         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19669         check_swap_layouts_support
19670         check_swap_layout_no_dom $DIR
19671
19672         local dir0=$DIR/$tdir/$testnum
19673         mkdir -p $dir0 || error "creating dir $dir0"
19674
19675         local ref1=$dir0/ref1
19676         local ref2=$dir0/ref2
19677         local file1=$dir0/file1
19678         local file2=$dir0/file2
19679         # create a file large enough for the concurrent test
19680         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19681         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19682         echo "ref file size: ref1($(stat -c %s $ref1))," \
19683              "ref2($(stat -c %s $ref2))"
19684
19685         cp $ref2 $file2
19686         dd if=$ref1 of=$file1 bs=16k &
19687         local DD_PID=$!
19688
19689         # Make sure dd starts to copy file, but wait at most 5 seconds
19690         local loops=0
19691         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19692
19693         $LFS swap_layouts $file1 $file2
19694         local rc=$?
19695         wait $DD_PID
19696         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19697         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19698
19699         # how many bytes copied before swapping layout
19700         local copied=$(stat -c %s $file2)
19701         local remaining=$(stat -c %s $ref1)
19702         remaining=$((remaining - copied))
19703         echo "Copied $copied bytes before swapping layout..."
19704
19705         cmp -n $copied $file1 $ref2 | grep differ &&
19706                 error "Content mismatch [0, $copied) of ref2 and file1"
19707         cmp -n $copied $file2 $ref1 ||
19708                 error "Content mismatch [0, $copied) of ref1 and file2"
19709         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19710                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19711
19712         # clean up
19713         rm -f $ref1 $ref2 $file1 $file2
19714 }
19715 run_test 184c "Concurrent write and layout swap"
19716
19717 test_184d() {
19718         check_swap_layouts_support
19719         check_swap_layout_no_dom $DIR
19720         [ -z "$(which getfattr 2>/dev/null)" ] &&
19721                 skip_env "no getfattr command"
19722
19723         local file1=$DIR/$tdir/$tfile-1
19724         local file2=$DIR/$tdir/$tfile-2
19725         local file3=$DIR/$tdir/$tfile-3
19726         local lovea1
19727         local lovea2
19728
19729         mkdir -p $DIR/$tdir
19730         touch $file1 || error "create $file1 failed"
19731         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19732                 error "create $file2 failed"
19733         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19734                 error "create $file3 failed"
19735         lovea1=$(get_layout_param $file1)
19736
19737         $LFS swap_layouts $file2 $file3 ||
19738                 error "swap $file2 $file3 layouts failed"
19739         $LFS swap_layouts $file1 $file2 ||
19740                 error "swap $file1 $file2 layouts failed"
19741
19742         lovea2=$(get_layout_param $file2)
19743         echo "$lovea1"
19744         echo "$lovea2"
19745         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19746
19747         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19748         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19749 }
19750 run_test 184d "allow stripeless layouts swap"
19751
19752 test_184e() {
19753         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19754                 skip "Need MDS version at least 2.6.94"
19755         check_swap_layouts_support
19756         check_swap_layout_no_dom $DIR
19757         [ -z "$(which getfattr 2>/dev/null)" ] &&
19758                 skip_env "no getfattr command"
19759
19760         local file1=$DIR/$tdir/$tfile-1
19761         local file2=$DIR/$tdir/$tfile-2
19762         local file3=$DIR/$tdir/$tfile-3
19763         local lovea
19764
19765         mkdir -p $DIR/$tdir
19766         touch $file1 || error "create $file1 failed"
19767         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19768                 error "create $file2 failed"
19769         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19770                 error "create $file3 failed"
19771
19772         $LFS swap_layouts $file1 $file2 ||
19773                 error "swap $file1 $file2 layouts failed"
19774
19775         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19776         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19777
19778         echo 123 > $file1 || error "Should be able to write into $file1"
19779
19780         $LFS swap_layouts $file1 $file3 ||
19781                 error "swap $file1 $file3 layouts failed"
19782
19783         echo 123 > $file1 || error "Should be able to write into $file1"
19784
19785         rm -rf $file1 $file2 $file3
19786 }
19787 run_test 184e "Recreate layout after stripeless layout swaps"
19788
19789 test_184f() {
19790         # Create a file with name longer than sizeof(struct stat) ==
19791         # 144 to see if we can get chars from the file name to appear
19792         # in the returned striping. Note that 'f' == 0x66.
19793         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19794
19795         mkdir -p $DIR/$tdir
19796         mcreate $DIR/$tdir/$file
19797         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19798                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19799         fi
19800 }
19801 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19802
19803 test_185() { # LU-2441
19804         # LU-3553 - no volatile file support in old servers
19805         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19806                 skip "Need MDS version at least 2.3.60"
19807
19808         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19809         touch $DIR/$tdir/spoo
19810         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19811         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19812                 error "cannot create/write a volatile file"
19813         [ "$FILESET" == "" ] &&
19814         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19815                 error "FID is still valid after close"
19816
19817         multiop_bg_pause $DIR/$tdir Vw4096_c
19818         local multi_pid=$!
19819
19820         local OLD_IFS=$IFS
19821         IFS=":"
19822         local fidv=($fid)
19823         IFS=$OLD_IFS
19824         # assume that the next FID for this client is sequential, since stdout
19825         # is unfortunately eaten by multiop_bg_pause
19826         local n=$((${fidv[1]} + 1))
19827         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19828         if [ "$FILESET" == "" ]; then
19829                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19830                         error "FID is missing before close"
19831         fi
19832         kill -USR1 $multi_pid
19833         # 1 second delay, so if mtime change we will see it
19834         sleep 1
19835         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19836         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19837 }
19838 run_test 185 "Volatile file support"
19839
19840 function create_check_volatile() {
19841         local idx=$1
19842         local tgt
19843
19844         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19845         local PID=$!
19846         sleep 1
19847         local FID=$(cat /tmp/${tfile}.fid)
19848         [ "$FID" == "" ] && error "can't get FID for volatile"
19849         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19850         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19851         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19852         kill -USR1 $PID
19853         wait
19854         sleep 1
19855         cancel_lru_locks mdc # flush opencache
19856         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19857         return 0
19858 }
19859
19860 test_185a(){
19861         # LU-12516 - volatile creation via .lustre
19862         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19863                 skip "Need MDS version at least 2.3.55"
19864
19865         create_check_volatile 0
19866         [ $MDSCOUNT -lt 2 ] && return 0
19867
19868         # DNE case
19869         create_check_volatile 1
19870
19871         return 0
19872 }
19873 run_test 185a "Volatile file creation in .lustre/fid/"
19874
19875 test_187a() {
19876         remote_mds_nodsh && skip "remote MDS with nodsh"
19877         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19878                 skip "Need MDS version at least 2.3.0"
19879
19880         local dir0=$DIR/$tdir/$testnum
19881         mkdir -p $dir0 || error "creating dir $dir0"
19882
19883         local file=$dir0/file1
19884         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19885         stack_trap "rm -f $file"
19886         local dv1=$($LFS data_version $file)
19887         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19888         local dv2=$($LFS data_version $file)
19889         [[ $dv1 != $dv2 ]] ||
19890                 error "data version did not change on write $dv1 == $dv2"
19891 }
19892 run_test 187a "Test data version change"
19893
19894 test_187b() {
19895         remote_mds_nodsh && skip "remote MDS with nodsh"
19896         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19897                 skip "Need MDS version at least 2.3.0"
19898
19899         local dir0=$DIR/$tdir/$testnum
19900         mkdir -p $dir0 || error "creating dir $dir0"
19901
19902         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19903         [[ ${DV[0]} != ${DV[1]} ]] ||
19904                 error "data version did not change on write"\
19905                       " ${DV[0]} == ${DV[1]}"
19906
19907         # clean up
19908         rm -f $file1
19909 }
19910 run_test 187b "Test data version change on volatile file"
19911
19912 test_200() {
19913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19914         remote_mgs_nodsh && skip "remote MGS with nodsh"
19915         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19916
19917         local POOL=${POOL:-cea1}
19918         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19919         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19920         # Pool OST targets
19921         local first_ost=0
19922         local last_ost=$(($OSTCOUNT - 1))
19923         local ost_step=2
19924         local ost_list=$(seq $first_ost $ost_step $last_ost)
19925         local ost_range="$first_ost $last_ost $ost_step"
19926         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19927         local file_dir=$POOL_ROOT/file_tst
19928         local subdir=$test_path/subdir
19929         local rc=0
19930
19931         while : ; do
19932                 # former test_200a test_200b
19933                 pool_add $POOL                          || { rc=$? ; break; }
19934                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19935                 # former test_200c test_200d
19936                 mkdir -p $test_path
19937                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19938                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19939                 mkdir -p $subdir
19940                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19941                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19942                                                         || { rc=$? ; break; }
19943                 # former test_200e test_200f
19944                 local files=$((OSTCOUNT*3))
19945                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19946                                                         || { rc=$? ; break; }
19947                 pool_create_files $POOL $file_dir $files "$ost_list" \
19948                                                         || { rc=$? ; break; }
19949                 # former test_200g test_200h
19950                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19951                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19952
19953                 # former test_201a test_201b test_201c
19954                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19955
19956                 local f=$test_path/$tfile
19957                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19958                 pool_remove $POOL $f                    || { rc=$? ; break; }
19959                 break
19960         done
19961
19962         destroy_test_pools
19963
19964         return $rc
19965 }
19966 run_test 200 "OST pools"
19967
19968 # usage: default_attr <count | size | offset>
19969 default_attr() {
19970         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19971 }
19972
19973 # usage: check_default_stripe_attr
19974 check_default_stripe_attr() {
19975         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19976         case $1 in
19977         --stripe-count|-c)
19978                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19979         --stripe-size|-S)
19980                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19981         --stripe-index|-i)
19982                 EXPECTED=-1;;
19983         *)
19984                 error "unknown getstripe attr '$1'"
19985         esac
19986
19987         [ $ACTUAL == $EXPECTED ] ||
19988                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19989 }
19990
19991 test_204a() {
19992         test_mkdir $DIR/$tdir
19993         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19994
19995         check_default_stripe_attr --stripe-count
19996         check_default_stripe_attr --stripe-size
19997         check_default_stripe_attr --stripe-index
19998 }
19999 run_test 204a "Print default stripe attributes"
20000
20001 test_204b() {
20002         test_mkdir $DIR/$tdir
20003         $LFS setstripe --stripe-count 1 $DIR/$tdir
20004
20005         check_default_stripe_attr --stripe-size
20006         check_default_stripe_attr --stripe-index
20007 }
20008 run_test 204b "Print default stripe size and offset"
20009
20010 test_204c() {
20011         test_mkdir $DIR/$tdir
20012         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20013
20014         check_default_stripe_attr --stripe-count
20015         check_default_stripe_attr --stripe-index
20016 }
20017 run_test 204c "Print default stripe count and offset"
20018
20019 test_204d() {
20020         test_mkdir $DIR/$tdir
20021         $LFS setstripe --stripe-index 0 $DIR/$tdir
20022
20023         check_default_stripe_attr --stripe-count
20024         check_default_stripe_attr --stripe-size
20025 }
20026 run_test 204d "Print default stripe count and size"
20027
20028 test_204e() {
20029         test_mkdir $DIR/$tdir
20030         $LFS setstripe -d $DIR/$tdir
20031
20032         # LU-16904 check if root is set as PFL layout
20033         local numcomp=$($LFS getstripe --component-count $MOUNT)
20034
20035         if [[ $numcomp -gt 0 ]]; then
20036                 check_default_stripe_attr --stripe-count
20037         else
20038                 check_default_stripe_attr --stripe-count --raw
20039         fi
20040         check_default_stripe_attr --stripe-size --raw
20041         check_default_stripe_attr --stripe-index --raw
20042 }
20043 run_test 204e "Print raw stripe attributes"
20044
20045 test_204f() {
20046         test_mkdir $DIR/$tdir
20047         $LFS setstripe --stripe-count 1 $DIR/$tdir
20048
20049         check_default_stripe_attr --stripe-size --raw
20050         check_default_stripe_attr --stripe-index --raw
20051 }
20052 run_test 204f "Print raw stripe size and offset"
20053
20054 test_204g() {
20055         test_mkdir $DIR/$tdir
20056         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20057
20058         check_default_stripe_attr --stripe-count --raw
20059         check_default_stripe_attr --stripe-index --raw
20060 }
20061 run_test 204g "Print raw stripe count and offset"
20062
20063 test_204h() {
20064         test_mkdir $DIR/$tdir
20065         $LFS setstripe --stripe-index 0 $DIR/$tdir
20066
20067         check_default_stripe_attr --stripe-count --raw
20068         check_default_stripe_attr --stripe-size --raw
20069 }
20070 run_test 204h "Print raw stripe count and size"
20071
20072 # Figure out which job scheduler is being used, if any,
20073 # or use a fake one
20074 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20075         JOBENV=SLURM_JOB_ID
20076 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20077         JOBENV=LSB_JOBID
20078 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20079         JOBENV=PBS_JOBID
20080 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20081         JOBENV=LOADL_STEP_ID
20082 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20083         JOBENV=JOB_ID
20084 else
20085         $LCTL list_param jobid_name > /dev/null 2>&1
20086         if [ $? -eq 0 ]; then
20087                 JOBENV=nodelocal
20088         else
20089                 JOBENV=FAKE_JOBID
20090         fi
20091 fi
20092 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20093
20094 verify_jobstats() {
20095         local cmd=($1)
20096         shift
20097         local facets="$@"
20098
20099 # we don't really need to clear the stats for this test to work, since each
20100 # command has a unique jobid, but it makes debugging easier if needed.
20101 #       for facet in $facets; do
20102 #               local dev=$(convert_facet2label $facet)
20103 #               # clear old jobstats
20104 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20105 #       done
20106
20107         # use a new JobID for each test, or we might see an old one
20108         [ "$JOBENV" = "FAKE_JOBID" ] &&
20109                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20110
20111         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20112
20113         [ "$JOBENV" = "nodelocal" ] && {
20114                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20115                 $LCTL set_param jobid_name=$FAKE_JOBID
20116                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20117         }
20118
20119         log "Test: ${cmd[*]}"
20120         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20121
20122         if [ $JOBENV = "FAKE_JOBID" ]; then
20123                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20124         else
20125                 ${cmd[*]}
20126         fi
20127
20128         # all files are created on OST0000
20129         for facet in $facets; do
20130                 local stats="*.$(convert_facet2label $facet).job_stats"
20131
20132                 # strip out libtool wrappers for in-tree executables
20133                 if (( $(do_facet $facet lctl get_param $stats |
20134                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20135                         do_facet $facet lctl get_param $stats
20136                         error "No jobstats for $JOBVAL found on $facet::$stats"
20137                 fi
20138         done
20139 }
20140
20141 jobstats_set() {
20142         local new_jobenv=$1
20143
20144         set_persistent_param_and_check client "jobid_var" \
20145                 "$FSNAME.sys.jobid_var" $new_jobenv
20146 }
20147
20148 test_205a() { # Job stats
20149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20150         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20151                 skip "Need MDS version with at least 2.7.1"
20152         remote_mgs_nodsh && skip "remote MGS with nodsh"
20153         remote_mds_nodsh && skip "remote MDS with nodsh"
20154         remote_ost_nodsh && skip "remote OST with nodsh"
20155         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20156                 skip "Server doesn't support jobstats"
20157         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20158
20159         local old_jobenv=$($LCTL get_param -n jobid_var)
20160         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20161         stack_trap "jobstats_set $old_jobenv" EXIT
20162
20163         changelog_register
20164
20165         local old_jobid_name=$($LCTL get_param jobid_name)
20166         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20167
20168         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20169                                 mdt.*.job_cleanup_interval | head -n 1)
20170         local new_interval=5
20171         do_facet $SINGLEMDS \
20172                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20173         stack_trap "do_facet $SINGLEMDS \
20174                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20175         local start=$SECONDS
20176
20177         local cmd
20178         # mkdir
20179         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20180         verify_jobstats "$cmd" "$SINGLEMDS"
20181         # rmdir
20182         cmd="rmdir $DIR/$tdir"
20183         verify_jobstats "$cmd" "$SINGLEMDS"
20184         # mkdir on secondary MDT
20185         if [ $MDSCOUNT -gt 1 ]; then
20186                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20187                 verify_jobstats "$cmd" "mds2"
20188         fi
20189         # mknod
20190         cmd="mknod $DIR/$tfile c 1 3"
20191         verify_jobstats "$cmd" "$SINGLEMDS"
20192         # unlink
20193         cmd="rm -f $DIR/$tfile"
20194         verify_jobstats "$cmd" "$SINGLEMDS"
20195         # create all files on OST0000 so verify_jobstats can find OST stats
20196         # open & close
20197         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20198         verify_jobstats "$cmd" "$SINGLEMDS"
20199         # setattr
20200         cmd="touch $DIR/$tfile"
20201         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20202         # write
20203         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20204         verify_jobstats "$cmd" "ost1"
20205         # read
20206         cancel_lru_locks osc
20207         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20208         verify_jobstats "$cmd" "ost1"
20209         # truncate
20210         cmd="$TRUNCATE $DIR/$tfile 0"
20211         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20212         # rename
20213         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20214         verify_jobstats "$cmd" "$SINGLEMDS"
20215         # jobstats expiry - sleep until old stats should be expired
20216         local left=$((new_interval + 5 - (SECONDS - start)))
20217         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20218                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20219                         "0" $left
20220         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20221         verify_jobstats "$cmd" "$SINGLEMDS"
20222         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20223             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20224
20225         # Ensure that jobid are present in changelog (if supported by MDS)
20226         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20227                 changelog_dump | tail -10
20228                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20229                 [ $jobids -eq 9 ] ||
20230                         error "Wrong changelog jobid count $jobids != 9"
20231
20232                 # LU-5862
20233                 JOBENV="disable"
20234                 jobstats_set $JOBENV
20235                 touch $DIR/$tfile
20236                 changelog_dump | grep $tfile
20237                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20238                 [ $jobids -eq 0 ] ||
20239                         error "Unexpected jobids when jobid_var=$JOBENV"
20240         fi
20241
20242         # test '%j' access to environment variable - if supported
20243         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20244                 JOBENV="JOBCOMPLEX"
20245                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20246
20247                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20248         fi
20249
20250         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20251                 JOBENV="JOBCOMPLEX"
20252                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20253
20254                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20255         fi
20256
20257         # test '%j' access to per-session jobid - if supported
20258         if lctl list_param jobid_this_session > /dev/null 2>&1
20259         then
20260                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20261                 lctl set_param jobid_this_session=$USER
20262
20263                 JOBENV="JOBCOMPLEX"
20264                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20265
20266                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20267         fi
20268 }
20269 run_test 205a "Verify job stats"
20270
20271 # LU-13117, LU-13597, LU-16599
20272 test_205b() {
20273         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20274                 skip "Need MDS version at least 2.13.54.91"
20275
20276         local job_stats="mdt.*.job_stats"
20277         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20278
20279         do_facet mds1 $LCTL set_param $job_stats=clear
20280
20281         # Setting jobid_var to USER might not be supported
20282         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20283         $LCTL set_param jobid_var=USER || true
20284         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20285         $LCTL set_param jobid_name="%j.%e.%u"
20286
20287         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20288         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20289                 { do_facet mds1 $LCTL get_param $job_stats;
20290                   error "Unexpected jobid found"; }
20291         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20292                 { do_facet mds1 $LCTL get_param $job_stats;
20293                   error "wrong job_stats format found"; }
20294
20295         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20296                 echo "MDS does not yet escape jobid" && return 0
20297
20298         mkdir_on_mdt0 $DIR/$tdir
20299         $LCTL set_param jobid_var=TEST205b
20300         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20301         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20302                       awk '/has\\x20sp/ {print $3}')
20303         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20304                   error "jobid not escaped"; }
20305
20306         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20307                 # need to run such a command on mds1:
20308                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20309                 #
20310                 # there might be multiple MDTs on single mds server, so need to
20311                 # specifiy MDT0000. Or the command will fail due to other MDTs
20312                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20313                         error "cannot clear escaped jobid in job_stats";
20314         else
20315                 echo "MDS does not support clearing escaped jobid"
20316         fi
20317 }
20318 run_test 205b "Verify job stats jobid and output format"
20319
20320 # LU-13733
20321 test_205c() {
20322         $LCTL set_param llite.*.stats=0
20323         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20324         $LCTL get_param llite.*.stats
20325         $LCTL get_param llite.*.stats | grep \
20326                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20327                         error "wrong client stats format found"
20328 }
20329 run_test 205c "Verify client stats format"
20330
20331 test_205d() {
20332         local file=$DIR/$tdir/$tfile
20333
20334         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20335                 skip "need lustre >= 2.15.53 for lljobstat"
20336         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20337                 skip "need lustre >= 2.15.53 for lljobstat"
20338         verify_yaml_available || skip_env "YAML verification not installed"
20339
20340         test_mkdir -i 0 $DIR/$tdir
20341         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20342         stack_trap "rm -rf $DIR/$tdir"
20343
20344         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20345                 error "failed to write data to $file"
20346         mv $file $file.2
20347
20348         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20349         echo -n 'verify rename_stats...'
20350         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20351                 verify_yaml || error "rename_stats is not valid YAML"
20352         echo " OK"
20353
20354         echo -n 'verify mdt job_stats...'
20355         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20356                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20357         echo " OK"
20358
20359         echo -n 'verify ost job_stats...'
20360         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20361                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20362         echo " OK"
20363 }
20364 run_test 205d "verify the format of some stats files"
20365
20366 test_205e() {
20367         local ops_comma
20368         local file=$DIR/$tdir/$tfile
20369         local -a cli_params
20370
20371         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20372                 skip "need lustre >= 2.15.53 for lljobstat"
20373         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20374                 skip "need lustre >= 2.15.53 for lljobstat"
20375         verify_yaml_available || skip_env "YAML verification not installed"
20376
20377         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20378         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20379         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20380
20381         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20382         stack_trap "rm -rf $DIR/$tdir"
20383
20384         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20385                 error "failed to create $file on ost1"
20386         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20387                 error "failed to write data to $file"
20388
20389         do_facet mds1 "$LCTL get_param *.*.job_stats"
20390         do_facet ost1 "$LCTL get_param *.*.job_stats"
20391
20392         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20393         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20394                 error "The output of lljobstat is not an valid YAML"
20395
20396         # verify that job dd.0 does exist and has some ops on ost1
20397         # typically this line is like:
20398         # - 205e.dd.0:            {ops: 20, ...}
20399         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20400                     awk '$2=="205e.dd.0:" {print $4}')
20401
20402         (( ${ops_comma%,} >= 10 )) ||
20403                 error "cannot find job 205e.dd.0 with ops >= 10"
20404 }
20405 run_test 205e "verify the output of lljobstat"
20406
20407 test_205f() {
20408         verify_yaml_available || skip_env "YAML verification not installed"
20409
20410         # check both qos_ost_weights and qos_mdt_weights
20411         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20412         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20413                 error "qos_ost_weights is not valid YAML"
20414 }
20415 run_test 205f "verify qos_ost_weights YAML format "
20416
20417 __test_205_jobstats_dump() {
20418         local -a pids
20419         local nbr_instance=$1
20420
20421         while true; do
20422                 if (( ${#pids[@]} >= nbr_instance )); then
20423                         wait ${pids[@]}
20424                         pids=()
20425                 fi
20426
20427                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20428                 pids+=( $! )
20429         done
20430 }
20431
20432 __test_205_cleanup() {
20433         kill $@
20434         # Clear all job entries
20435         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20436 }
20437
20438 test_205g() {
20439         local -a mds1_params
20440         local -a cli_params
20441         local pids
20442         local interval=5
20443
20444         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20445         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20446         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20447
20448         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20449         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20450         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20451
20452         # start jobs loop
20453         export TEST205G_ID=205g
20454         stack_trap "unset TEST205G_ID" EXIT
20455         while true; do
20456                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20457         done & pids="$! "
20458
20459         __test_205_jobstats_dump 4 & pids+="$! "
20460         stack_trap "__test_205_cleanup $pids" EXIT INT
20461
20462         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20463 }
20464 run_test 205g "stress test for job_stats procfile"
20465
20466 test_205h() {
20467         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20468                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20469         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20470
20471         local dir=$DIR/$tdir
20472         local f=$dir/$tfile
20473         local f2=$dir/$tfile-2
20474         local f3=$dir/$tfile-3
20475         local subdir=$DIR/dir
20476         local val
20477
20478         local mdts=$(comma_list $(mdts_nodes))
20479         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20480         local client_saved=$($LCTL get_param -n jobid_var)
20481
20482         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20483         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20484
20485         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20486                 error "failed to set job_xattr parameter to user.job"
20487         $LCTL set_param jobid_var=procname.uid ||
20488                 error "failed to set jobid_var parameter"
20489
20490         test_mkdir $dir
20491
20492         touch $f
20493         val=$(getfattr -n user.job $f | grep user.job)
20494         [[ $val = user.job=\"touch.0\" ]] ||
20495                 error "expected user.job=\"touch.0\", got '$val'"
20496
20497         mkdir $subdir
20498         val=$(getfattr -n user.job $subdir | grep user.job)
20499         [[ $val = user.job=\"mkdir.0\" ]] ||
20500                 error "expected user.job=\"mkdir.0\", got '$val'"
20501
20502         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20503                 error "failed to set job_xattr parameter to NONE"
20504
20505         touch $f2
20506         val=$(getfattr -d $f2)
20507         [[ -z $val ]] ||
20508                 error "expected no user xattr, got '$val'"
20509
20510         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20511                 error "failed to set job_xattr parameter to trusted.job"
20512
20513         touch $f3
20514         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20515         [[ $val = trusted.job=\"touch.0\" ]] ||
20516                 error "expected trusted.job=\"touch.0\", got '$val'"
20517 }
20518 run_test 205h "check jobid xattr is stored correctly"
20519
20520 test_205i() {
20521         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20522                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20523
20524         local mdts=$(comma_list $(mdts_nodes))
20525         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20526
20527         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20528
20529         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20530                 error "failed to set mdt.*.job_xattr to user.1234567"
20531
20532         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20533                 error "failed to reject too long job_xattr name"
20534
20535         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20536                 error "failed to reject job_xattr name in bad format"
20537
20538         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20539                 error "failed to reject job_xattr name with invalid character"
20540
20541         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20542                         xargs $LCTL set_param" &&
20543                 error "failed to reject job_xattr name with non-ascii character"
20544
20545         return 0
20546 }
20547 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20548
20549 # LU-1480, LU-1773 and LU-1657
20550 test_206() {
20551         mkdir -p $DIR/$tdir
20552         $LFS setstripe -c -1 $DIR/$tdir
20553 #define OBD_FAIL_LOV_INIT 0x1403
20554         $LCTL set_param fail_loc=0xa0001403
20555         $LCTL set_param fail_val=1
20556         touch $DIR/$tdir/$tfile || true
20557 }
20558 run_test 206 "fail lov_init_raid0() doesn't lbug"
20559
20560 test_207a() {
20561         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20562         local fsz=`stat -c %s $DIR/$tfile`
20563         cancel_lru_locks mdc
20564
20565         # do not return layout in getattr intent
20566 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20567         $LCTL set_param fail_loc=0x170
20568         local sz=`stat -c %s $DIR/$tfile`
20569
20570         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20571
20572         rm -rf $DIR/$tfile
20573 }
20574 run_test 207a "can refresh layout at glimpse"
20575
20576 test_207b() {
20577         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20578         local cksum=`md5sum $DIR/$tfile`
20579         local fsz=`stat -c %s $DIR/$tfile`
20580         cancel_lru_locks mdc
20581         cancel_lru_locks osc
20582
20583         # do not return layout in getattr intent
20584 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20585         $LCTL set_param fail_loc=0x171
20586
20587         # it will refresh layout after the file is opened but before read issues
20588         echo checksum is "$cksum"
20589         echo "$cksum" |md5sum -c --quiet || error "file differs"
20590
20591         rm -rf $DIR/$tfile
20592 }
20593 run_test 207b "can refresh layout at open"
20594
20595 test_208() {
20596         # FIXME: in this test suite, only RD lease is used. This is okay
20597         # for now as only exclusive open is supported. After generic lease
20598         # is done, this test suite should be revised. - Jinshan
20599
20600         remote_mds_nodsh && skip "remote MDS with nodsh"
20601         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20602                 skip "Need MDS version at least 2.4.52"
20603
20604         echo "==== test 1: verify get lease work"
20605         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20606
20607         echo "==== test 2: verify lease can be broken by upcoming open"
20608         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20609         local PID=$!
20610         sleep 2
20611
20612         $MULTIOP $DIR/$tfile oO_RDWR:c
20613         kill -USR1 $PID && wait $PID || error "break lease error"
20614
20615         echo "==== test 3: verify lease can't be granted if an open already exists"
20616         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20617         local PID=$!
20618         sleep 2
20619
20620         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20621         kill -USR1 $PID && wait $PID || error "open file error"
20622
20623         echo "==== test 4: lease can sustain over recovery"
20624         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20625         PID=$!
20626         sleep 2
20627
20628         fail mds1
20629
20630         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20631
20632         echo "==== test 5: lease broken can't be regained by replay"
20633         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20634         PID=$!
20635         sleep 2
20636
20637         # open file to break lease and then recovery
20638         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20639         fail mds1
20640
20641         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20642
20643         rm -f $DIR/$tfile
20644 }
20645 run_test 208 "Exclusive open"
20646
20647 test_209() {
20648         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20649                 skip_env "must have disp_stripe"
20650
20651         touch $DIR/$tfile
20652         sync; sleep 5; sync;
20653
20654         echo 3 > /proc/sys/vm/drop_caches
20655         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20656                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20657         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20658
20659         # open/close 500 times
20660         for i in $(seq 500); do
20661                 cat $DIR/$tfile
20662         done
20663
20664         echo 3 > /proc/sys/vm/drop_caches
20665         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20666                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20667         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20668
20669         echo "before: $req_before, after: $req_after"
20670         [ $((req_after - req_before)) -ge 300 ] &&
20671                 error "open/close requests are not freed"
20672         return 0
20673 }
20674 run_test 209 "read-only open/close requests should be freed promptly"
20675
20676 test_210() {
20677         local pid
20678
20679         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20680         pid=$!
20681         sleep 1
20682
20683         $LFS getstripe $DIR/$tfile
20684         kill -USR1 $pid
20685         wait $pid || error "multiop failed"
20686
20687         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20688         pid=$!
20689         sleep 1
20690
20691         $LFS getstripe $DIR/$tfile
20692         kill -USR1 $pid
20693         wait $pid || error "multiop failed"
20694 }
20695 run_test 210 "lfs getstripe does not break leases"
20696
20697 function test_211() {
20698         local PID
20699         local id
20700         local rc
20701
20702         stack_trap "rm -f $DIR/$tfile" EXIT
20703         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20704                 error "can't create file"
20705         $LFS mirror extend -N $DIR/$tfile ||
20706                 error "can't create a replica"
20707         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20708         $LFS getstripe $DIR/$tfile
20709         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20710         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20711
20712         $MULTIOP $DIR/$tfile OeW_E+eUc &
20713         PID=$!
20714         sleep 0.3
20715
20716         id=$($LFS getstripe $DIR/$tfile |
20717                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20718         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20719                 error "removed last in-sync replica?"
20720
20721         kill -USR1 $PID
20722         wait $PID
20723         (( $? == 0 )) || error "failed split broke the lease"
20724 }
20725 run_test 211 "failed mirror split doesn't break write lease"
20726
20727 test_212() {
20728         size=`date +%s`
20729         size=$((size % 8192 + 1))
20730         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20731         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20732         rm -f $DIR/f212 $DIR/f212.xyz
20733 }
20734 run_test 212 "Sendfile test ============================================"
20735
20736 test_213() {
20737         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20738         cancel_lru_locks osc
20739         lctl set_param fail_loc=0x8000040f
20740         # generate a read lock
20741         cat $DIR/$tfile > /dev/null
20742         # write to the file, it will try to cancel the above read lock.
20743         cat /etc/hosts >> $DIR/$tfile
20744 }
20745 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20746
20747 test_214() { # for bug 20133
20748         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20749         for (( i=0; i < 340; i++ )) ; do
20750                 touch $DIR/$tdir/d214c/a$i
20751         done
20752
20753         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20754         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20755         ls $DIR/d214c || error "ls $DIR/d214c failed"
20756         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20757         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20758 }
20759 run_test 214 "hash-indexed directory test - bug 20133"
20760
20761 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20762 create_lnet_proc_files() {
20763         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20764 }
20765
20766 # counterpart of create_lnet_proc_files
20767 remove_lnet_proc_files() {
20768         rm -f $TMP/lnet_$1.sys
20769 }
20770
20771 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20772 # 3rd arg as regexp for body
20773 check_lnet_proc_stats() {
20774         local l=$(cat "$TMP/lnet_$1" |wc -l)
20775         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20776
20777         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20778 }
20779
20780 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20781 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20782 # optional and can be regexp for 2nd line (lnet.routes case)
20783 check_lnet_proc_entry() {
20784         local blp=2          # blp stands for 'position of 1st line of body'
20785         [ -z "$5" ] || blp=3 # lnet.routes case
20786
20787         local l=$(cat "$TMP/lnet_$1" |wc -l)
20788         # subtracting one from $blp because the body can be empty
20789         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20790
20791         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20792                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20793
20794         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20795                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20796
20797         # bail out if any unexpected line happened
20798         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20799         [ "$?" != 0 ] || error "$2 misformatted"
20800 }
20801
20802 test_215() { # for bugs 18102, 21079, 21517
20803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20804
20805         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20806         local P='[1-9][0-9]*'           # positive numeric
20807         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20808         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20809         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20810         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20811
20812         local L1 # regexp for 1st line
20813         local L2 # regexp for 2nd line (optional)
20814         local BR # regexp for the rest (body)
20815
20816         # lnet.stats should look as 11 space-separated non-negative numerics
20817         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20818         create_lnet_proc_files "stats"
20819         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20820         remove_lnet_proc_files "stats"
20821
20822         # lnet.routes should look like this:
20823         # Routing disabled/enabled
20824         # net hops priority state router
20825         # where net is a string like tcp0, hops > 0, priority >= 0,
20826         # state is up/down,
20827         # router is a string like 192.168.1.1@tcp2
20828         L1="^Routing (disabled|enabled)$"
20829         L2="^net +hops +priority +state +router$"
20830         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20831         create_lnet_proc_files "routes"
20832         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20833         remove_lnet_proc_files "routes"
20834
20835         # lnet.routers should look like this:
20836         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20837         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20838         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20839         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20840         L1="^ref +rtr_ref +alive +router$"
20841         BR="^$P +$P +(up|down) +$NID$"
20842         create_lnet_proc_files "routers"
20843         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20844         remove_lnet_proc_files "routers"
20845
20846         # lnet.peers should look like this:
20847         # nid refs state last max rtr min tx min queue
20848         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20849         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20850         # numeric (0 or >0 or <0), queue >= 0.
20851         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20852         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20853         create_lnet_proc_files "peers"
20854         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20855         remove_lnet_proc_files "peers"
20856
20857         # lnet.buffers  should look like this:
20858         # pages count credits min
20859         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20860         L1="^pages +count +credits +min$"
20861         BR="^ +$N +$N +$I +$I$"
20862         create_lnet_proc_files "buffers"
20863         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20864         remove_lnet_proc_files "buffers"
20865
20866         # lnet.nis should look like this:
20867         # nid status alive refs peer rtr max tx min
20868         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20869         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20870         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20871         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20872         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20873         create_lnet_proc_files "nis"
20874         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20875         remove_lnet_proc_files "nis"
20876
20877         # can we successfully write to lnet.stats?
20878         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20879 }
20880 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20881
20882 test_216() { # bug 20317
20883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20884         remote_ost_nodsh && skip "remote OST with nodsh"
20885
20886         local node
20887         local facets=$(get_facets OST)
20888         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20889
20890         save_lustre_params client "osc.*.contention_seconds" > $p
20891         save_lustre_params $facets \
20892                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20893         save_lustre_params $facets \
20894                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20895         save_lustre_params $facets \
20896                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20897         clear_stats osc.*.osc_stats
20898
20899         # agressive lockless i/o settings
20900         do_nodes $(comma_list $(osts_nodes)) \
20901                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20902                         ldlm.namespaces.filter-*.contended_locks=0 \
20903                         ldlm.namespaces.filter-*.contention_seconds=60"
20904         lctl set_param -n osc.*.contention_seconds=60
20905
20906         $DIRECTIO write $DIR/$tfile 0 10 4096
20907         $CHECKSTAT -s 40960 $DIR/$tfile
20908
20909         # disable lockless i/o
20910         do_nodes $(comma_list $(osts_nodes)) \
20911                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20912                         ldlm.namespaces.filter-*.contended_locks=32 \
20913                         ldlm.namespaces.filter-*.contention_seconds=0"
20914         lctl set_param -n osc.*.contention_seconds=0
20915         clear_stats osc.*.osc_stats
20916
20917         dd if=/dev/zero of=$DIR/$tfile count=0
20918         $CHECKSTAT -s 0 $DIR/$tfile
20919
20920         restore_lustre_params <$p
20921         rm -f $p
20922         rm $DIR/$tfile
20923 }
20924 run_test 216 "check lockless direct write updates file size and kms correctly"
20925
20926 test_217() { # bug 22430
20927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20928
20929         local node
20930
20931         for node in $(nodes_list); do
20932                 local nid=$(host_nids_address $node $NETTYPE)
20933                 local node_ip=$(do_node $node getent ahostsv4 $node |
20934                                 awk '{ print $1; exit; }')
20935
20936                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20937                 # if hostname matches any NID, use hostname for better testing
20938                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20939                         echo "lctl ping node $node@$NETTYPE"
20940                         lctl ping $node@$NETTYPE
20941                 else # otherwise, at least test 'lctl ping' is working
20942                         echo "lctl ping nid $(h2nettype $nid)"
20943                         lctl ping $(h2nettype $nid)
20944                         echo "skipping $node (no hyphen detected)"
20945                 fi
20946         done
20947 }
20948 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20949
20950 test_218() {
20951         # do directio so as not to populate the page cache
20952         log "creating a 10 Mb file"
20953         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20954                 error "multiop failed while creating a file"
20955         log "starting reads"
20956         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20957         log "truncating the file"
20958         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20959                 error "multiop failed while truncating the file"
20960         log "killing dd"
20961         kill %+ || true # reads might have finished
20962         echo "wait until dd is finished"
20963         wait
20964         log "removing the temporary file"
20965         rm -rf $DIR/$tfile || error "tmp file removal failed"
20966 }
20967 run_test 218 "parallel read and truncate should not deadlock"
20968
20969 test_219() {
20970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20971
20972         # write one partial page
20973         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20974         # set no grant so vvp_io_commit_write will do sync write
20975         $LCTL set_param fail_loc=0x411
20976         # write a full page at the end of file
20977         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20978
20979         $LCTL set_param fail_loc=0
20980         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20981         $LCTL set_param fail_loc=0x411
20982         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20983
20984         # LU-4201
20985         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20986         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20987 }
20988 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20989
20990 test_220() { #LU-325
20991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20992         remote_ost_nodsh && skip "remote OST with nodsh"
20993         remote_mds_nodsh && skip "remote MDS with nodsh"
20994         remote_mgs_nodsh && skip "remote MGS with nodsh"
20995
20996         local OSTIDX=0
20997
20998         # create on MDT0000 so the last_id and next_id are correct
20999         mkdir_on_mdt0 $DIR/$tdir
21000         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21001         OST=${OST%_UUID}
21002
21003         # on the mdt's osc
21004         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21005         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21006                         osp.$mdtosc_proc1.prealloc_last_id)
21007         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21008                         osp.$mdtosc_proc1.prealloc_next_id)
21009
21010         $LFS df -i
21011
21012         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21013         #define OBD_FAIL_OST_ENOINO              0x229
21014         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21015         create_pool $FSNAME.$TESTNAME || return 1
21016         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21017
21018         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21019
21020         MDSOBJS=$((last_id - next_id))
21021         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21022
21023         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21024         echo "OST still has $count kbytes free"
21025
21026         echo "create $MDSOBJS files @next_id..."
21027         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21028
21029         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21030                         osp.$mdtosc_proc1.prealloc_last_id)
21031         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21032                         osp.$mdtosc_proc1.prealloc_next_id)
21033
21034         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21035         $LFS df -i
21036
21037         echo "cleanup..."
21038
21039         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21040         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21041
21042         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21043                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21044         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21045                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21046         echo "unlink $MDSOBJS files @$next_id..."
21047         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21048 }
21049 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21050
21051 test_221() {
21052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21053
21054         dd if=`which date` of=$MOUNT/date oflag=sync
21055         chmod +x $MOUNT/date
21056
21057         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21058         $LCTL set_param fail_loc=0x80001401
21059
21060         $MOUNT/date > /dev/null
21061         rm -f $MOUNT/date
21062 }
21063 run_test 221 "make sure fault and truncate race to not cause OOM"
21064
21065 test_222a () {
21066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21067
21068         rm -rf $DIR/$tdir
21069         test_mkdir $DIR/$tdir
21070         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21071         createmany -o $DIR/$tdir/$tfile 10
21072         cancel_lru_locks mdc
21073         cancel_lru_locks osc
21074         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21075         $LCTL set_param fail_loc=0x31a
21076         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21077         $LCTL set_param fail_loc=0
21078         rm -r $DIR/$tdir
21079 }
21080 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21081
21082 test_222b () {
21083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21084
21085         rm -rf $DIR/$tdir
21086         test_mkdir $DIR/$tdir
21087         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21088         createmany -o $DIR/$tdir/$tfile 10
21089         cancel_lru_locks mdc
21090         cancel_lru_locks osc
21091         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21092         $LCTL set_param fail_loc=0x31a
21093         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21094         $LCTL set_param fail_loc=0
21095 }
21096 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21097
21098 test_223 () {
21099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21100
21101         rm -rf $DIR/$tdir
21102         test_mkdir $DIR/$tdir
21103         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21104         createmany -o $DIR/$tdir/$tfile 10
21105         cancel_lru_locks mdc
21106         cancel_lru_locks osc
21107         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21108         $LCTL set_param fail_loc=0x31b
21109         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21110         $LCTL set_param fail_loc=0
21111         rm -r $DIR/$tdir
21112 }
21113 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21114
21115 test_224a() { # LU-1039, MRP-303
21116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21117         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21118         $LCTL set_param fail_loc=0x508
21119         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21120         $LCTL set_param fail_loc=0
21121         df $DIR
21122 }
21123 run_test 224a "Don't panic on bulk IO failure"
21124
21125 test_224bd_sub() { # LU-1039, MRP-303
21126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21127         local timeout=$1
21128
21129         shift
21130         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21131
21132         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21133
21134         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21135         cancel_lru_locks osc
21136         set_checksums 0
21137         stack_trap "set_checksums $ORIG_CSUM" EXIT
21138         local at_max_saved=0
21139
21140         # adaptive timeouts may prevent seeing the issue
21141         if at_is_enabled; then
21142                 at_max_saved=$(at_max_get mds)
21143                 at_max_set 0 mds client
21144                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21145         fi
21146
21147         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21148         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21149         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21150
21151         do_facet ost1 $LCTL set_param fail_loc=0
21152         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21153         df $DIR
21154 }
21155
21156 test_224b() {
21157         test_224bd_sub 3 error "dd failed"
21158 }
21159 run_test 224b "Don't panic on bulk IO failure"
21160
21161 test_224c() { # LU-6441
21162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21163         remote_mds_nodsh && skip "remote MDS with nodsh"
21164
21165         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21166         save_writethrough $p
21167         set_cache writethrough on
21168
21169         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21170         local at_max=$($LCTL get_param -n at_max)
21171         local timeout=$($LCTL get_param -n timeout)
21172         local test_at="at_max"
21173         local param_at="$FSNAME.sys.at_max"
21174         local test_timeout="timeout"
21175         local param_timeout="$FSNAME.sys.timeout"
21176
21177         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21178
21179         set_persistent_param_and_check client "$test_at" "$param_at" 0
21180         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21181
21182         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21183         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21184         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21185         stack_trap "rm -f $DIR/$tfile"
21186         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21187         sync
21188         do_facet ost1 "$LCTL set_param fail_loc=0"
21189
21190         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21191         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21192                 $timeout
21193
21194         $LCTL set_param -n $pages_per_rpc
21195         restore_lustre_params < $p
21196         rm -f $p
21197 }
21198 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21199
21200 test_224d() { # LU-11169
21201         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21202 }
21203 run_test 224d "Don't corrupt data on bulk IO timeout"
21204
21205 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21206 test_225a () {
21207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21208         if [ -z ${MDSSURVEY} ]; then
21209                 skip_env "mds-survey not found"
21210         fi
21211         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21212                 skip "Need MDS version at least 2.2.51"
21213
21214         local mds=$(facet_host $SINGLEMDS)
21215         local target=$(do_nodes $mds 'lctl dl' |
21216                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21217
21218         local cmd1="file_count=1000 thrhi=4"
21219         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21220         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21221         local cmd="$cmd1 $cmd2 $cmd3"
21222
21223         rm -f ${TMP}/mds_survey*
21224         echo + $cmd
21225         eval $cmd || error "mds-survey with zero-stripe failed"
21226         cat ${TMP}/mds_survey*
21227         rm -f ${TMP}/mds_survey*
21228 }
21229 run_test 225a "Metadata survey sanity with zero-stripe"
21230
21231 test_225b () {
21232         if [ -z ${MDSSURVEY} ]; then
21233                 skip_env "mds-survey not found"
21234         fi
21235         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21236                 skip "Need MDS version at least 2.2.51"
21237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21238         remote_mds_nodsh && skip "remote MDS with nodsh"
21239         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21240                 skip_env "Need to mount OST to test"
21241         fi
21242
21243         local mds=$(facet_host $SINGLEMDS)
21244         local target=$(do_nodes $mds 'lctl dl' |
21245                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21246
21247         local cmd1="file_count=1000 thrhi=4"
21248         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21249         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21250         local cmd="$cmd1 $cmd2 $cmd3"
21251
21252         rm -f ${TMP}/mds_survey*
21253         echo + $cmd
21254         eval $cmd || error "mds-survey with stripe_count failed"
21255         cat ${TMP}/mds_survey*
21256         rm -f ${TMP}/mds_survey*
21257 }
21258 run_test 225b "Metadata survey sanity with stripe_count = 1"
21259
21260 mcreate_path2fid () {
21261         local mode=$1
21262         local major=$2
21263         local minor=$3
21264         local name=$4
21265         local desc=$5
21266         local path=$DIR/$tdir/$name
21267         local fid
21268         local rc
21269         local fid_path
21270
21271         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21272                 error "cannot create $desc"
21273
21274         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21275         rc=$?
21276         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21277
21278         fid_path=$($LFS fid2path $MOUNT $fid)
21279         rc=$?
21280         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21281
21282         [ "$path" == "$fid_path" ] ||
21283                 error "fid2path returned $fid_path, expected $path"
21284
21285         echo "pass with $path and $fid"
21286 }
21287
21288 test_226a () {
21289         rm -rf $DIR/$tdir
21290         mkdir -p $DIR/$tdir
21291
21292         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21293         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21294         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21295         mcreate_path2fid 0040666 0 0 dir "directory"
21296         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21297         mcreate_path2fid 0100666 0 0 file "regular file"
21298         mcreate_path2fid 0120666 0 0 link "symbolic link"
21299         mcreate_path2fid 0140666 0 0 sock "socket"
21300 }
21301 run_test 226a "call path2fid and fid2path on files of all type"
21302
21303 test_226b () {
21304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21305
21306         local MDTIDX=1
21307
21308         rm -rf $DIR/$tdir
21309         mkdir -p $DIR/$tdir
21310         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21311                 error "create remote directory failed"
21312         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21313         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21314                                 "character special file (null)"
21315         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21316                                 "character special file (no device)"
21317         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21318         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21319                                 "block special file (loop)"
21320         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21321         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21322         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21323 }
21324 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21325
21326 test_226c () {
21327         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21328         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21329                 skip "Need MDS version at least 2.13.55"
21330
21331         local submnt=/mnt/submnt
21332         local srcfile=/etc/passwd
21333         local dstfile=$submnt/passwd
21334         local path
21335         local fid
21336
21337         rm -rf $DIR/$tdir
21338         rm -rf $submnt
21339         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21340                 error "create remote directory failed"
21341         mkdir -p $submnt || error "create $submnt failed"
21342         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21343                 error "mount $submnt failed"
21344         stack_trap "umount $submnt" EXIT
21345
21346         cp $srcfile $dstfile
21347         fid=$($LFS path2fid $dstfile)
21348         path=$($LFS fid2path $submnt "$fid")
21349         [ "$path" = "$dstfile" ] ||
21350                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21351 }
21352 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21353
21354 test_226d () {
21355         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21356                 skip "Need client at least version 2.15.57"
21357
21358         # Define First test dataset
21359         local testdirs_01=$DIR/$tdir
21360         local testdata_01=$testdirs_01/${tdir}_01
21361         local testresult_01=${tdir}_01
21362         # Define Second test dataset
21363         local testdirs_02=$DIR/$tdir/$tdir
21364         local testdata_02=$testdirs_02/${tdir}_02
21365         local testresult_02=${tdir}_02
21366         # Define third test dataset (top level)
21367         local testdata_03=$DIR/${tdir}_03
21368         local testresult_03=${tdir}_03
21369
21370         # Create first test dataset
21371         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21372         touch $testdata_01 || error "cannot create file $testdata_01"
21373
21374         # Create second test dataset
21375         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21376         touch $testdata_02 || error "cannot create file $testdata_02"
21377
21378         # Create third test dataset
21379         touch $testdata_03 || error "cannot create file $testdata_03"
21380
21381         local fid01=$($LFS getstripe -F "$testdata_01") ||
21382                 error "getstripe failed on $testdata_01"
21383         local fid02=$($LFS getstripe -F "$testdata_02") ||
21384                 error "getstripe failed on $testdata_01"
21385         local fid03=$($LFS getstripe -F "$testdata_03") ||
21386                 error "getstripe failed on $testdata_03"
21387
21388         # Verify only -n option
21389         local out1=$($LFS fid2path -n $DIR $fid01) ||
21390                 error "fid2path failed on $fid01"
21391         local out2=$($LFS fid2path -n $DIR $fid02) ||
21392                 error "fid2path failed on $fid02"
21393         local out3=$($LFS fid2path -n $DIR $fid03) ||
21394                 error "fid2path failed on $fid03"
21395
21396         [[ "$out1" == "$testresult_01" ]] ||
21397                 error "fid2path failed: Expected $testresult_01 got $out1"
21398         [[ "$out2" == "$testresult_02" ]] ||
21399                 error "fid2path failed: Expected $testresult_02 got $out2"
21400         [[ "$out3" == "$testresult_03" ]] ||
21401                 error "fid2path failed: Expected $testresult_03 got $out3"
21402
21403         # Verify with option -fn together
21404         out1=$($LFS fid2path -fn $DIR $fid01) ||
21405                 error "fid2path -fn failed on $fid01"
21406         out2=$($LFS fid2path -fn $DIR $fid02) ||
21407                 error "fid2path -fn failed on $fid02"
21408         out3=$($LFS fid2path -fn $DIR $fid03) ||
21409                 error "fid2path -fn failed on $fid03"
21410
21411         local tmpout=$(echo $out1 | cut -d" " -f2)
21412         [[ "$tmpout" == "$testresult_01" ]] ||
21413                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21414
21415         tmpout=$(echo $out2 | cut -d" " -f2)
21416         [[ "$tmpout" == "$testresult_02" ]] ||
21417                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21418
21419         tmpout=$(echo $out3 | cut -d" " -f2)
21420         [[ "$tmpout" == "$testresult_03" ]] ||
21421                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21422 }
21423 run_test 226d "verify fid2path with -n and -fn option"
21424
21425 test_226e () {
21426         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21427                 skip "Need client at least version 2.15.56"
21428
21429         # Define filename with 'newline' and a space
21430         local testfile="Test"$'\n'"file 01"
21431         # Define link name with multiple 'newline' and a space
21432         local linkfile="Link"$'\n'"file "$'\n'"01"
21433         # Remove prior hard link
21434         rm -f $DIR/"$linkfile"
21435
21436         # Create file
21437         touch $DIR/"$testfile"
21438         # Create link
21439         ln $DIR/"$testfile" $DIR/"$linkfile"
21440
21441         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21442                 error "getstripe failed on $DIR/$testfile"
21443
21444         # Call with -0 option
21445         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21446                 echo "FILE:" | grep -c "FILE:")
21447
21448         # With -0 option the output should be exactly 2 lines.
21449         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21450 }
21451 run_test 226e "Verify path2fid -0 option with newline and space"
21452
21453 # LU-1299 Executing or running ldd on a truncated executable does not
21454 # cause an out-of-memory condition.
21455 test_227() {
21456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21457         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21458
21459         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21460         chmod +x $MOUNT/date
21461
21462         $MOUNT/date > /dev/null
21463         ldd $MOUNT/date > /dev/null
21464         rm -f $MOUNT/date
21465 }
21466 run_test 227 "running truncated executable does not cause OOM"
21467
21468 # LU-1512 try to reuse idle OI blocks
21469 test_228a() {
21470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21471         remote_mds_nodsh && skip "remote MDS with nodsh"
21472         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21473
21474         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21475         local myDIR=$DIR/$tdir
21476
21477         mkdir -p $myDIR
21478         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21479         $LCTL set_param fail_loc=0x80001002
21480         createmany -o $myDIR/t- 10000
21481         $LCTL set_param fail_loc=0
21482         # The guard is current the largest FID holder
21483         touch $myDIR/guard
21484         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21485                     tr -d '[')
21486         local IDX=$(($SEQ % 64))
21487
21488         do_facet $SINGLEMDS sync
21489         # Make sure journal flushed.
21490         sleep 6
21491         local blk1=$(do_facet $SINGLEMDS \
21492                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21493                      grep Blockcount | awk '{print $4}')
21494
21495         # Remove old files, some OI blocks will become idle.
21496         unlinkmany $myDIR/t- 10000
21497         # Create new files, idle OI blocks should be reused.
21498         createmany -o $myDIR/t- 2000
21499         do_facet $SINGLEMDS sync
21500         # Make sure journal flushed.
21501         sleep 6
21502         local blk2=$(do_facet $SINGLEMDS \
21503                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21504                      grep Blockcount | awk '{print $4}')
21505
21506         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21507 }
21508 run_test 228a "try to reuse idle OI blocks"
21509
21510 test_228b() {
21511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21512         remote_mds_nodsh && skip "remote MDS with nodsh"
21513         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21514
21515         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21516         local myDIR=$DIR/$tdir
21517
21518         mkdir -p $myDIR
21519         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21520         $LCTL set_param fail_loc=0x80001002
21521         createmany -o $myDIR/t- 10000
21522         $LCTL set_param fail_loc=0
21523         # The guard is current the largest FID holder
21524         touch $myDIR/guard
21525         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21526                     tr -d '[')
21527         local IDX=$(($SEQ % 64))
21528
21529         do_facet $SINGLEMDS sync
21530         # Make sure journal flushed.
21531         sleep 6
21532         local blk1=$(do_facet $SINGLEMDS \
21533                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21534                      grep Blockcount | awk '{print $4}')
21535
21536         # Remove old files, some OI blocks will become idle.
21537         unlinkmany $myDIR/t- 10000
21538
21539         # stop the MDT
21540         stop $SINGLEMDS || error "Fail to stop MDT."
21541         # remount the MDT
21542         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21543                 error "Fail to start MDT."
21544
21545         client_up || error "Fail to df."
21546         # Create new files, idle OI blocks should be reused.
21547         createmany -o $myDIR/t- 2000
21548         do_facet $SINGLEMDS sync
21549         # Make sure journal flushed.
21550         sleep 6
21551         local blk2=$(do_facet $SINGLEMDS \
21552                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21553                      grep Blockcount | awk '{print $4}')
21554
21555         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21556 }
21557 run_test 228b "idle OI blocks can be reused after MDT restart"
21558
21559 #LU-1881
21560 test_228c() {
21561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21562         remote_mds_nodsh && skip "remote MDS with nodsh"
21563         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21564
21565         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21566         local myDIR=$DIR/$tdir
21567
21568         mkdir -p $myDIR
21569         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21570         $LCTL set_param fail_loc=0x80001002
21571         # 20000 files can guarantee there are index nodes in the OI file
21572         createmany -o $myDIR/t- 20000
21573         $LCTL set_param fail_loc=0
21574         # The guard is current the largest FID holder
21575         touch $myDIR/guard
21576         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21577                     tr -d '[')
21578         local IDX=$(($SEQ % 64))
21579
21580         do_facet $SINGLEMDS sync
21581         # Make sure journal flushed.
21582         sleep 6
21583         local blk1=$(do_facet $SINGLEMDS \
21584                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21585                      grep Blockcount | awk '{print $4}')
21586
21587         # Remove old files, some OI blocks will become idle.
21588         unlinkmany $myDIR/t- 20000
21589         rm -f $myDIR/guard
21590         # The OI file should become empty now
21591
21592         # Create new files, idle OI blocks should be reused.
21593         createmany -o $myDIR/t- 2000
21594         do_facet $SINGLEMDS sync
21595         # Make sure journal flushed.
21596         sleep 6
21597         local blk2=$(do_facet $SINGLEMDS \
21598                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21599                      grep Blockcount | awk '{print $4}')
21600
21601         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21602 }
21603 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21604
21605 test_229() { # LU-2482, LU-3448
21606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21607         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21608         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21609                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21610
21611         rm -f $DIR/$tfile
21612
21613         # Create a file with a released layout and stripe count 2.
21614         $MULTIOP $DIR/$tfile H2c ||
21615                 error "failed to create file with released layout"
21616
21617         $LFS getstripe -v $DIR/$tfile
21618
21619         local pattern=$($LFS getstripe -L $DIR/$tfile)
21620         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21621
21622         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21623                 error "getstripe"
21624         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21625         stat $DIR/$tfile || error "failed to stat released file"
21626
21627         chown $RUNAS_ID $DIR/$tfile ||
21628                 error "chown $RUNAS_ID $DIR/$tfile failed"
21629
21630         chgrp $RUNAS_ID $DIR/$tfile ||
21631                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21632
21633         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21634         rm $DIR/$tfile || error "failed to remove released file"
21635 }
21636 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21637
21638 test_230a() {
21639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21640         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21641         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21642                 skip "Need MDS version at least 2.11.52"
21643
21644         local MDTIDX=1
21645
21646         test_mkdir $DIR/$tdir
21647         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21648         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21649         [ $mdt_idx -ne 0 ] &&
21650                 error "create local directory on wrong MDT $mdt_idx"
21651
21652         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21653                         error "create remote directory failed"
21654         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21655         [ $mdt_idx -ne $MDTIDX ] &&
21656                 error "create remote directory on wrong MDT $mdt_idx"
21657
21658         createmany -o $DIR/$tdir/test_230/t- 10 ||
21659                 error "create files on remote directory failed"
21660         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21661         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21662         rm -r $DIR/$tdir || error "unlink remote directory failed"
21663 }
21664 run_test 230a "Create remote directory and files under the remote directory"
21665
21666 test_230b() {
21667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21668         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21669         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21670                 skip "Need MDS version at least 2.11.52"
21671
21672         local MDTIDX=1
21673         local mdt_index
21674         local i
21675         local file
21676         local pid
21677         local stripe_count
21678         local migrate_dir=$DIR/$tdir/migrate_dir
21679         local other_dir=$DIR/$tdir/other_dir
21680
21681         test_mkdir $DIR/$tdir
21682         test_mkdir -i0 -c1 $migrate_dir
21683         test_mkdir -i0 -c1 $other_dir
21684         for ((i=0; i<10; i++)); do
21685                 mkdir -p $migrate_dir/dir_${i}
21686                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21687                         error "create files under remote dir failed $i"
21688         done
21689
21690         cp /etc/passwd $migrate_dir/$tfile
21691         cp /etc/passwd $other_dir/$tfile
21692         chattr +SAD $migrate_dir
21693         chattr +SAD $migrate_dir/$tfile
21694
21695         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21696         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21697         local old_dir_mode=$(stat -c%f $migrate_dir)
21698         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21699
21700         mkdir -p $migrate_dir/dir_default_stripe2
21701         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21702         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21703
21704         mkdir -p $other_dir
21705         ln $migrate_dir/$tfile $other_dir/luna
21706         ln $migrate_dir/$tfile $migrate_dir/sofia
21707         ln $other_dir/$tfile $migrate_dir/david
21708         ln -s $migrate_dir/$tfile $other_dir/zachary
21709         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21710         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21711
21712         local len
21713         local lnktgt
21714
21715         # inline symlink
21716         for len in 58 59 60; do
21717                 lnktgt=$(str_repeat 'l' $len)
21718                 touch $migrate_dir/$lnktgt
21719                 ln -s $lnktgt $migrate_dir/${len}char_ln
21720         done
21721
21722         # PATH_MAX
21723         for len in 4094 4095; do
21724                 lnktgt=$(str_repeat 'l' $len)
21725                 ln -s $lnktgt $migrate_dir/${len}char_ln
21726         done
21727
21728         # NAME_MAX
21729         for len in 254 255; do
21730                 touch $migrate_dir/$(str_repeat 'l' $len)
21731         done
21732
21733         $LFS migrate -m $MDTIDX $migrate_dir ||
21734                 error "fails on migrating remote dir to MDT1"
21735
21736         echo "migratate to MDT1, then checking.."
21737         for ((i = 0; i < 10; i++)); do
21738                 for file in $(find $migrate_dir/dir_${i}); do
21739                         mdt_index=$($LFS getstripe -m $file)
21740                         # broken symlink getstripe will fail
21741                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21742                                 error "$file is not on MDT${MDTIDX}"
21743                 done
21744         done
21745
21746         # the multiple link file should still in MDT0
21747         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21748         [ $mdt_index == 0 ] ||
21749                 error "$file is not on MDT${MDTIDX}"
21750
21751         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21752         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21753                 error " expect $old_dir_flag get $new_dir_flag"
21754
21755         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21756         [ "$old_file_flag" = "$new_file_flag" ] ||
21757                 error " expect $old_file_flag get $new_file_flag"
21758
21759         local new_dir_mode=$(stat -c%f $migrate_dir)
21760         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21761                 error "expect mode $old_dir_mode get $new_dir_mode"
21762
21763         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21764         [ "$old_file_mode" = "$new_file_mode" ] ||
21765                 error "expect mode $old_file_mode get $new_file_mode"
21766
21767         diff /etc/passwd $migrate_dir/$tfile ||
21768                 error "$tfile different after migration"
21769
21770         diff /etc/passwd $other_dir/luna ||
21771                 error "luna different after migration"
21772
21773         diff /etc/passwd $migrate_dir/sofia ||
21774                 error "sofia different after migration"
21775
21776         diff /etc/passwd $migrate_dir/david ||
21777                 error "david different after migration"
21778
21779         diff /etc/passwd $other_dir/zachary ||
21780                 error "zachary different after migration"
21781
21782         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21783                 error "${tfile}_ln different after migration"
21784
21785         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21786                 error "${tfile}_ln_other different after migration"
21787
21788         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21789         [ $stripe_count = 2 ] ||
21790                 error "dir strpe_count $d != 2 after migration."
21791
21792         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21793         [ $stripe_count = 2 ] ||
21794                 error "file strpe_count $d != 2 after migration."
21795
21796         #migrate back to MDT0
21797         MDTIDX=0
21798
21799         $LFS migrate -m $MDTIDX $migrate_dir ||
21800                 error "fails on migrating remote dir to MDT0"
21801
21802         echo "migrate back to MDT0, checking.."
21803         for file in $(find $migrate_dir); do
21804                 mdt_index=$($LFS getstripe -m $file)
21805                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21806                         error "$file is not on MDT${MDTIDX}"
21807         done
21808
21809         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21810         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21811                 error " expect $old_dir_flag get $new_dir_flag"
21812
21813         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21814         [ "$old_file_flag" = "$new_file_flag" ] ||
21815                 error " expect $old_file_flag get $new_file_flag"
21816
21817         local new_dir_mode=$(stat -c%f $migrate_dir)
21818         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21819                 error "expect mode $old_dir_mode get $new_dir_mode"
21820
21821         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21822         [ "$old_file_mode" = "$new_file_mode" ] ||
21823                 error "expect mode $old_file_mode get $new_file_mode"
21824
21825         diff /etc/passwd ${migrate_dir}/$tfile ||
21826                 error "$tfile different after migration"
21827
21828         diff /etc/passwd ${other_dir}/luna ||
21829                 error "luna different after migration"
21830
21831         diff /etc/passwd ${migrate_dir}/sofia ||
21832                 error "sofia different after migration"
21833
21834         diff /etc/passwd ${other_dir}/zachary ||
21835                 error "zachary different after migration"
21836
21837         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21838                 error "${tfile}_ln different after migration"
21839
21840         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21841                 error "${tfile}_ln_other different after migration"
21842
21843         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21844         [ $stripe_count = 2 ] ||
21845                 error "dir strpe_count $d != 2 after migration."
21846
21847         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21848         [ $stripe_count = 2 ] ||
21849                 error "file strpe_count $d != 2 after migration."
21850
21851         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21852 }
21853 run_test 230b "migrate directory"
21854
21855 test_230c() {
21856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21858         remote_mds_nodsh && skip "remote MDS with nodsh"
21859         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21860                 skip "Need MDS version at least 2.11.52"
21861
21862         local MDTIDX=1
21863         local total=3
21864         local mdt_index
21865         local file
21866         local migrate_dir=$DIR/$tdir/migrate_dir
21867
21868         #If migrating directory fails in the middle, all entries of
21869         #the directory is still accessiable.
21870         test_mkdir $DIR/$tdir
21871         test_mkdir -i0 -c1 $migrate_dir
21872         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21873         stat $migrate_dir
21874         createmany -o $migrate_dir/f $total ||
21875                 error "create files under ${migrate_dir} failed"
21876
21877         # fail after migrating top dir, and this will fail only once, so the
21878         # first sub file migration will fail (currently f3), others succeed.
21879         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21880         do_facet mds1 lctl set_param fail_loc=0x1801
21881         local t=$(ls $migrate_dir | wc -l)
21882         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21883                 error "migrate should fail"
21884         local u=$(ls $migrate_dir | wc -l)
21885         [ "$u" == "$t" ] || error "$u != $t during migration"
21886
21887         # add new dir/file should succeed
21888         mkdir $migrate_dir/dir ||
21889                 error "mkdir failed under migrating directory"
21890         touch $migrate_dir/file ||
21891                 error "create file failed under migrating directory"
21892
21893         # add file with existing name should fail
21894         for file in $migrate_dir/f*; do
21895                 stat $file > /dev/null || error "stat $file failed"
21896                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21897                         error "open(O_CREAT|O_EXCL) $file should fail"
21898                 $MULTIOP $file m && error "create $file should fail"
21899                 touch $DIR/$tdir/remote_dir/$tfile ||
21900                         error "touch $tfile failed"
21901                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21902                         error "link $file should fail"
21903                 mdt_index=$($LFS getstripe -m $file)
21904                 if [ $mdt_index == 0 ]; then
21905                         # file failed to migrate is not allowed to rename to
21906                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21907                                 error "rename to $file should fail"
21908                 else
21909                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21910                                 error "rename to $file failed"
21911                 fi
21912                 echo hello >> $file || error "write $file failed"
21913         done
21914
21915         # resume migration with different options should fail
21916         $LFS migrate -m 0 $migrate_dir &&
21917                 error "migrate -m 0 $migrate_dir should fail"
21918
21919         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21920                 error "migrate -c 2 $migrate_dir should fail"
21921
21922         # resume migration should succeed
21923         $LFS migrate -m $MDTIDX $migrate_dir ||
21924                 error "migrate $migrate_dir failed"
21925
21926         echo "Finish migration, then checking.."
21927         for file in $(find $migrate_dir); do
21928                 mdt_index=$($LFS getstripe -m $file)
21929                 [ $mdt_index == $MDTIDX ] ||
21930                         error "$file is not on MDT${MDTIDX}"
21931         done
21932
21933         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21934 }
21935 run_test 230c "check directory accessiblity if migration failed"
21936
21937 test_230d() {
21938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21940         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21941                 skip "Need MDS version at least 2.11.52"
21942         # LU-11235
21943         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21944
21945         local migrate_dir=$DIR/$tdir/migrate_dir
21946         local old_index
21947         local new_index
21948         local old_count
21949         local new_count
21950         local new_hash
21951         local mdt_index
21952         local i
21953         local j
21954
21955         old_index=$((RANDOM % MDSCOUNT))
21956         old_count=$((MDSCOUNT - old_index))
21957         new_index=$((RANDOM % MDSCOUNT))
21958         new_count=$((MDSCOUNT - new_index))
21959         new_hash=1 # for all_char
21960
21961         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21962         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21963
21964         test_mkdir $DIR/$tdir
21965         test_mkdir -i $old_index -c $old_count $migrate_dir
21966
21967         for ((i=0; i<100; i++)); do
21968                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21969                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21970                         error "create files under remote dir failed $i"
21971         done
21972
21973         echo -n "Migrate from MDT$old_index "
21974         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21975         echo -n "to MDT$new_index"
21976         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21977         echo
21978
21979         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21980         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21981                 error "migrate remote dir error"
21982
21983         echo "Finish migration, then checking.."
21984         for file in $(find $migrate_dir -maxdepth 1); do
21985                 mdt_index=$($LFS getstripe -m $file)
21986                 if [ $mdt_index -lt $new_index ] ||
21987                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21988                         error "$file is on MDT$mdt_index"
21989                 fi
21990         done
21991
21992         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21993 }
21994 run_test 230d "check migrate big directory"
21995
21996 test_230e() {
21997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21998         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21999         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22000                 skip "Need MDS version at least 2.11.52"
22001
22002         local i
22003         local j
22004         local a_fid
22005         local b_fid
22006
22007         mkdir_on_mdt0 $DIR/$tdir
22008         mkdir $DIR/$tdir/migrate_dir
22009         mkdir $DIR/$tdir/other_dir
22010         touch $DIR/$tdir/migrate_dir/a
22011         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22012         ls $DIR/$tdir/other_dir
22013
22014         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22015                 error "migrate dir fails"
22016
22017         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22018         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22019
22020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22021         [ $mdt_index == 0 ] || error "a is not on MDT0"
22022
22023         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22024                 error "migrate dir fails"
22025
22026         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22027         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22028
22029         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22030         [ $mdt_index == 1 ] || error "a is not on MDT1"
22031
22032         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22033         [ $mdt_index == 1 ] || error "b is not on MDT1"
22034
22035         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22036         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22037
22038         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22039
22040         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22041 }
22042 run_test 230e "migrate mulitple local link files"
22043
22044 test_230f() {
22045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22046         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22047         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22048                 skip "Need MDS version at least 2.11.52"
22049
22050         local a_fid
22051         local ln_fid
22052
22053         mkdir -p $DIR/$tdir
22054         mkdir $DIR/$tdir/migrate_dir
22055         $LFS mkdir -i1 $DIR/$tdir/other_dir
22056         touch $DIR/$tdir/migrate_dir/a
22057         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22058         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22059         ls $DIR/$tdir/other_dir
22060
22061         # a should be migrated to MDT1, since no other links on MDT0
22062         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22063                 error "#1 migrate dir fails"
22064         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22065         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22066         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22067         [ $mdt_index == 1 ] || error "a is not on MDT1"
22068
22069         # a should stay on MDT1, because it is a mulitple link file
22070         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22071                 error "#2 migrate dir fails"
22072         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22073         [ $mdt_index == 1 ] || error "a is not on MDT1"
22074
22075         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22076                 error "#3 migrate dir fails"
22077
22078         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22079         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22080         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22081
22082         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22083         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22084
22085         # a should be migrated to MDT0, since no other links on MDT1
22086         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22087                 error "#4 migrate dir fails"
22088         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22089         [ $mdt_index == 0 ] || error "a is not on MDT0"
22090
22091         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22092 }
22093 run_test 230f "migrate mulitple remote link files"
22094
22095 test_230g() {
22096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22098         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22099                 skip "Need MDS version at least 2.11.52"
22100
22101         mkdir -p $DIR/$tdir/migrate_dir
22102
22103         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22104                 error "migrating dir to non-exist MDT succeeds"
22105         true
22106 }
22107 run_test 230g "migrate dir to non-exist MDT"
22108
22109 test_230h() {
22110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22112         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22113                 skip "Need MDS version at least 2.11.52"
22114
22115         local mdt_index
22116
22117         mkdir -p $DIR/$tdir/migrate_dir
22118
22119         $LFS migrate -m1 $DIR &&
22120                 error "migrating mountpoint1 should fail"
22121
22122         $LFS migrate -m1 $DIR/$tdir/.. &&
22123                 error "migrating mountpoint2 should fail"
22124
22125         # same as mv
22126         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22127                 error "migrating $tdir/migrate_dir/.. should fail"
22128
22129         true
22130 }
22131 run_test 230h "migrate .. and root"
22132
22133 test_230i() {
22134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22137                 skip "Need MDS version at least 2.11.52"
22138
22139         mkdir -p $DIR/$tdir/migrate_dir
22140
22141         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22142                 error "migration fails with a tailing slash"
22143
22144         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22145                 error "migration fails with two tailing slashes"
22146 }
22147 run_test 230i "lfs migrate -m tolerates trailing slashes"
22148
22149 test_230j() {
22150         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22151         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22152                 skip "Need MDS version at least 2.11.52"
22153
22154         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22155         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22156                 error "create $tfile failed"
22157         cat /etc/passwd > $DIR/$tdir/$tfile
22158
22159         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22160
22161         cmp /etc/passwd $DIR/$tdir/$tfile ||
22162                 error "DoM file mismatch after migration"
22163 }
22164 run_test 230j "DoM file data not changed after dir migration"
22165
22166 test_230k() {
22167         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22168         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22169                 skip "Need MDS version at least 2.11.56"
22170
22171         local total=20
22172         local files_on_starting_mdt=0
22173
22174         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22175         $LFS getdirstripe $DIR/$tdir
22176         for i in $(seq $total); do
22177                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22178                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22179                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22180         done
22181
22182         echo "$files_on_starting_mdt files on MDT0"
22183
22184         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22185         $LFS getdirstripe $DIR/$tdir
22186
22187         files_on_starting_mdt=0
22188         for i in $(seq $total); do
22189                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22190                         error "file $tfile.$i mismatch after migration"
22191                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22192                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22193         done
22194
22195         echo "$files_on_starting_mdt files on MDT1 after migration"
22196         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22197
22198         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22199         $LFS getdirstripe $DIR/$tdir
22200
22201         files_on_starting_mdt=0
22202         for i in $(seq $total); do
22203                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22204                         error "file $tfile.$i mismatch after 2nd migration"
22205                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22206                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22207         done
22208
22209         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22210         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22211
22212         true
22213 }
22214 run_test 230k "file data not changed after dir migration"
22215
22216 test_230l() {
22217         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22218         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22219                 skip "Need MDS version at least 2.11.56"
22220
22221         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22222         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22223                 error "create files under remote dir failed $i"
22224         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22225 }
22226 run_test 230l "readdir between MDTs won't crash"
22227
22228 test_230m() {
22229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22230         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22231                 skip "Need MDS version at least 2.11.56"
22232
22233         local MDTIDX=1
22234         local mig_dir=$DIR/$tdir/migrate_dir
22235         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22236         local shortstr="b"
22237         local val
22238
22239         echo "Creating files and dirs with xattrs"
22240         test_mkdir $DIR/$tdir
22241         test_mkdir -i0 -c1 $mig_dir
22242         mkdir $mig_dir/dir
22243         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22244                 error "cannot set xattr attr1 on dir"
22245         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22246                 error "cannot set xattr attr2 on dir"
22247         touch $mig_dir/dir/f0
22248         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22249                 error "cannot set xattr attr1 on file"
22250         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22251                 error "cannot set xattr attr2 on file"
22252         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22253         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22254         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22255         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22256         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22257         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22258         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22259         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22260         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22261
22262         echo "Migrating to MDT1"
22263         $LFS migrate -m $MDTIDX $mig_dir ||
22264                 error "fails on migrating dir to MDT1"
22265
22266         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22267         echo "Checking xattrs"
22268         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22269         [ "$val" = $longstr ] ||
22270                 error "expecting xattr1 $longstr on dir, found $val"
22271         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22272         [ "$val" = $shortstr ] ||
22273                 error "expecting xattr2 $shortstr on dir, found $val"
22274         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22275         [ "$val" = $longstr ] ||
22276                 error "expecting xattr1 $longstr on file, found $val"
22277         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22278         [ "$val" = $shortstr ] ||
22279                 error "expecting xattr2 $shortstr on file, found $val"
22280 }
22281 run_test 230m "xattrs not changed after dir migration"
22282
22283 test_230n() {
22284         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22285         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22286                 skip "Need MDS version at least 2.13.53"
22287
22288         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22289         cat /etc/hosts > $DIR/$tdir/$tfile
22290         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22291         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22292
22293         cmp /etc/hosts $DIR/$tdir/$tfile ||
22294                 error "File data mismatch after migration"
22295 }
22296 run_test 230n "Dir migration with mirrored file"
22297
22298 test_230o() {
22299         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22300         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22301                 skip "Need MDS version at least 2.13.52"
22302
22303         local mdts=$(comma_list $(mdts_nodes))
22304         local timeout=100
22305         local restripe_status
22306         local delta
22307         local i
22308
22309         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22310
22311         # in case "crush" hash type is not set
22312         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22313
22314         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22315                            mdt.*MDT0000.enable_dir_restripe)
22316         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22317         stack_trap "do_nodes $mdts $LCTL set_param \
22318                     mdt.*.enable_dir_restripe=$restripe_status"
22319
22320         mkdir $DIR/$tdir
22321         createmany -m $DIR/$tdir/f 100 ||
22322                 error "create files under remote dir failed $i"
22323         createmany -d $DIR/$tdir/d 100 ||
22324                 error "create dirs under remote dir failed $i"
22325
22326         for i in $(seq 2 $MDSCOUNT); do
22327                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22328                 $LFS setdirstripe -c $i $DIR/$tdir ||
22329                         error "split -c $i $tdir failed"
22330                 wait_update $HOSTNAME \
22331                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22332                         error "dir split not finished"
22333                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22334                         awk '/migrate/ {sum += $2} END { print sum }')
22335                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22336                 # delta is around total_files/stripe_count
22337                 (( $delta < 200 / (i - 1) + 4 )) ||
22338                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22339         done
22340 }
22341 run_test 230o "dir split"
22342
22343 test_230p() {
22344         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22345         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22346                 skip "Need MDS version at least 2.13.52"
22347
22348         local mdts=$(comma_list $(mdts_nodes))
22349         local timeout=100
22350         local restripe_status
22351         local delta
22352         local c
22353
22354         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22355
22356         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22357
22358         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22359                            mdt.*MDT0000.enable_dir_restripe)
22360         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22361         stack_trap "do_nodes $mdts $LCTL set_param \
22362                     mdt.*.enable_dir_restripe=$restripe_status"
22363
22364         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22365         createmany -m $DIR/$tdir/f 100 ||
22366                 error "create files under remote dir failed"
22367         createmany -d $DIR/$tdir/d 100 ||
22368                 error "create dirs under remote dir failed"
22369
22370         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22371                 local mdt_hash="crush"
22372
22373                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22374                 $LFS setdirstripe -c $c $DIR/$tdir ||
22375                         error "split -c $c $tdir failed"
22376                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22377                         mdt_hash="$mdt_hash,fixed"
22378                 elif [ $c -eq 1 ]; then
22379                         mdt_hash="none"
22380                 fi
22381                 wait_update $HOSTNAME \
22382                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22383                         error "dir merge not finished"
22384                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22385                         awk '/migrate/ {sum += $2} END { print sum }')
22386                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22387                 # delta is around total_files/stripe_count
22388                 (( delta < 200 / c + 4 )) ||
22389                         error "$delta files migrated >= $((200 / c + 4))"
22390         done
22391 }
22392 run_test 230p "dir merge"
22393
22394 test_230q() {
22395         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22396         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22397                 skip "Need MDS version at least 2.13.52"
22398
22399         local mdts=$(comma_list $(mdts_nodes))
22400         local saved_threshold=$(do_facet mds1 \
22401                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22402         local saved_delta=$(do_facet mds1 \
22403                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22404         local threshold=100
22405         local delta=2
22406         local total=0
22407         local stripe_count=0
22408         local stripe_index
22409         local nr_files
22410         local create
22411
22412         # test with fewer files on ZFS
22413         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22414
22415         stack_trap "do_nodes $mdts $LCTL set_param \
22416                     mdt.*.dir_split_count=$saved_threshold"
22417         stack_trap "do_nodes $mdts $LCTL set_param \
22418                     mdt.*.dir_split_delta=$saved_delta"
22419         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22420         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22421         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22422         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22423         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22424         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22425
22426         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22427         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22428
22429         create=$((threshold * 3 / 2))
22430         while [ $stripe_count -lt $MDSCOUNT ]; do
22431                 createmany -m $DIR/$tdir/f $total $create ||
22432                         error "create sub files failed"
22433                 stat $DIR/$tdir > /dev/null
22434                 total=$((total + create))
22435                 stripe_count=$((stripe_count + delta))
22436                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22437
22438                 wait_update $HOSTNAME \
22439                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22440                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22441
22442                 wait_update $HOSTNAME \
22443                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22444                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22445
22446                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22447                 echo "$nr_files/$total files on MDT$stripe_index after split"
22448                 # allow 10% margin of imbalance with crush hash
22449                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22450                         error "$nr_files files on MDT$stripe_index after split"
22451
22452                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22453                 [ $nr_files -eq $total ] ||
22454                         error "total sub files $nr_files != $total"
22455         done
22456
22457         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22458
22459         echo "fixed layout directory won't auto split"
22460         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22461         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22462                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22463         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22464                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22465 }
22466 run_test 230q "dir auto split"
22467
22468 test_230r() {
22469         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22470         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22471         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22472                 skip "Need MDS version at least 2.13.54"
22473
22474         # maximum amount of local locks:
22475         # parent striped dir - 2 locks
22476         # new stripe in parent to migrate to - 1 lock
22477         # source and target - 2 locks
22478         # Total 5 locks for regular file
22479         mkdir -p $DIR/$tdir
22480         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22481         touch $DIR/$tdir/dir1/eee
22482
22483         # create 4 hardlink for 4 more locks
22484         # Total: 9 locks > RS_MAX_LOCKS (8)
22485         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22486         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22487         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22488         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22489         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22490         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22491         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22492         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22493
22494         cancel_lru_locks mdc
22495
22496         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22497                 error "migrate dir fails"
22498
22499         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22500 }
22501 run_test 230r "migrate with too many local locks"
22502
22503 test_230s() {
22504         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22505                 skip "Need MDS version at least 2.14.52"
22506
22507         local mdts=$(comma_list $(mdts_nodes))
22508         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22509                                 mdt.*MDT0000.enable_dir_restripe)
22510
22511         stack_trap "do_nodes $mdts $LCTL set_param \
22512                     mdt.*.enable_dir_restripe=$restripe_status"
22513
22514         local st
22515         for st in 0 1; do
22516                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22517                 test_mkdir $DIR/$tdir
22518                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22519                         error "$LFS mkdir should return EEXIST if target exists"
22520                 rmdir $DIR/$tdir
22521         done
22522 }
22523 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22524
22525 test_230t()
22526 {
22527         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22528         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22529                 skip "Need MDS version at least 2.14.50"
22530
22531         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22532         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22533         $LFS project -p 1 -s $DIR/$tdir ||
22534                 error "set $tdir project id failed"
22535         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22536                 error "set subdir project id failed"
22537         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22538 }
22539 run_test 230t "migrate directory with project ID set"
22540
22541 test_230u()
22542 {
22543         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22544         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22545                 skip "Need MDS version at least 2.14.53"
22546
22547         local count
22548
22549         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22550         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22551         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22552         for i in $(seq 0 $((MDSCOUNT - 1))); do
22553                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22554                 echo "$count dirs migrated to MDT$i"
22555         done
22556         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22557         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22558 }
22559 run_test 230u "migrate directory by QOS"
22560
22561 test_230v()
22562 {
22563         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22564         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22565                 skip "Need MDS version at least 2.14.53"
22566
22567         local count
22568
22569         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22570         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22571         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22572         for i in $(seq 0 $((MDSCOUNT - 1))); do
22573                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22574                 echo "$count subdirs migrated to MDT$i"
22575                 (( i == 3 )) && (( count > 0 )) &&
22576                         error "subdir shouldn't be migrated to MDT3"
22577         done
22578         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22579         (( count == 3 )) || error "dirs migrated to $count MDTs"
22580 }
22581 run_test 230v "subdir migrated to the MDT where its parent is located"
22582
22583 test_230w() {
22584         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22585         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22586                 skip "Need MDS version at least 2.15.0"
22587
22588         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22589         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22590         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22591
22592         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22593                 error "migrate failed"
22594
22595         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22596                 error "$tdir stripe count mismatch"
22597
22598         for i in $(seq 0 9); do
22599                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22600                         error "d$i is striped"
22601         done
22602 }
22603 run_test 230w "non-recursive mode dir migration"
22604
22605 test_230x() {
22606         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22607         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22608                 skip "Need MDS version at least 2.15.0"
22609
22610         mkdir -p $DIR/$tdir || error "mkdir failed"
22611         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22612
22613         local mdt_name=$(mdtname_from_index 0)
22614         local low=$(do_facet mds2 $LCTL get_param -n \
22615                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22616         local high=$(do_facet mds2 $LCTL get_param -n \
22617                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22618         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22619         local maxage=$(do_facet mds2 $LCTL get_param -n \
22620                 osp.*$mdt_name-osp-MDT0001.maxage)
22621
22622         stack_trap "do_facet mds2 $LCTL set_param -n \
22623                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22624                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22625         stack_trap "do_facet mds2 $LCTL set_param -n \
22626                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22627
22628         do_facet mds2 $LCTL set_param -n \
22629                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22630         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22631         sleep 4
22632         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22633                 error "migrate $tdir should fail"
22634
22635         do_facet mds2 $LCTL set_param -n \
22636                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22637         do_facet mds2 $LCTL set_param -n \
22638                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22639         sleep 4
22640         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22641                 error "migrate failed"
22642         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22643                 error "$tdir stripe count mismatch"
22644 }
22645 run_test 230x "dir migration check space"
22646
22647 test_230y() {
22648         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22649         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22650                 skip "Need MDS version at least 2.15.55.45"
22651
22652         local pid
22653
22654         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22655         $LFS getdirstripe $DIR/$tdir
22656         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22657         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22658         pid=$!
22659         sleep 1
22660
22661         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22662         do_facet mds2 lctl set_param fail_loc=0x1802
22663
22664         wait $pid
22665         do_facet mds2 lctl set_param fail_loc=0
22666         $LFS getdirstripe $DIR/$tdir
22667         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22668         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22669 }
22670 run_test 230y "unlink dir with bad hash type"
22671
22672 test_230z() {
22673         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22674         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22675                 skip "Need MDS version at least 2.15.55.45"
22676
22677         local pid
22678
22679         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22680         $LFS getdirstripe $DIR/$tdir
22681         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22682         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22683         pid=$!
22684         sleep 1
22685
22686         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22687         do_facet mds2 lctl set_param fail_loc=0x1802
22688
22689         wait $pid
22690         do_facet mds2 lctl set_param fail_loc=0
22691         $LFS getdirstripe $DIR/$tdir
22692
22693         # resume migration
22694         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22695                 error "resume migration failed"
22696         $LFS getdirstripe $DIR/$tdir
22697         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22698                 error "migration is not finished"
22699 }
22700 run_test 230z "resume dir migration with bad hash type"
22701
22702 test_231a()
22703 {
22704         # For simplicity this test assumes that max_pages_per_rpc
22705         # is the same across all OSCs
22706         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22707         local bulk_size=$((max_pages * PAGE_SIZE))
22708         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22709                                        head -n 1)
22710
22711         mkdir -p $DIR/$tdir
22712         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22713                 error "failed to set stripe with -S ${brw_size}M option"
22714         stack_trap "rm -rf $DIR/$tdir"
22715
22716         # clear the OSC stats
22717         $LCTL set_param osc.*.stats=0 &>/dev/null
22718         stop_writeback
22719
22720         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22721         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22722                 oflag=direct &>/dev/null || error "dd failed"
22723
22724         sync; sleep 1; sync # just to be safe
22725         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22726         if [ x$nrpcs != "x1" ]; then
22727                 $LCTL get_param osc.*.stats
22728                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22729         fi
22730
22731         start_writeback
22732         # Drop the OSC cache, otherwise we will read from it
22733         cancel_lru_locks osc
22734
22735         # clear the OSC stats
22736         $LCTL set_param osc.*.stats=0 &>/dev/null
22737
22738         # Client reads $bulk_size.
22739         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22740                 iflag=direct &>/dev/null || error "dd failed"
22741
22742         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22743         if [ x$nrpcs != "x1" ]; then
22744                 $LCTL get_param osc.*.stats
22745                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22746         fi
22747 }
22748 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22749
22750 test_231b() {
22751         mkdir -p $DIR/$tdir
22752         stack_trap "rm -rf $DIR/$tdir"
22753         local i
22754         for i in {0..1023}; do
22755                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22756                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22757                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22758         done
22759         sync
22760 }
22761 run_test 231b "must not assert on fully utilized OST request buffer"
22762
22763 test_232a() {
22764         mkdir -p $DIR/$tdir
22765         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22766
22767         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22768         do_facet ost1 $LCTL set_param fail_loc=0x31c
22769
22770         # ignore dd failure
22771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22772         stack_trap "rm -f $DIR/$tdir/$tfile"
22773
22774         do_facet ost1 $LCTL set_param fail_loc=0
22775         umount_client $MOUNT || error "umount failed"
22776         mount_client $MOUNT || error "mount failed"
22777         stop ost1 || error "cannot stop ost1"
22778         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22779 }
22780 run_test 232a "failed lock should not block umount"
22781
22782 test_232b() {
22783         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22784                 skip "Need MDS version at least 2.10.58"
22785
22786         mkdir -p $DIR/$tdir
22787         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22788         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22789         stack_trap "rm -f $DIR/$tdir/$tfile"
22790         sync
22791         cancel_lru_locks osc
22792
22793         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22794         do_facet ost1 $LCTL set_param fail_loc=0x31c
22795
22796         # ignore failure
22797         $LFS data_version $DIR/$tdir/$tfile || true
22798
22799         do_facet ost1 $LCTL set_param fail_loc=0
22800         umount_client $MOUNT || error "umount failed"
22801         mount_client $MOUNT || error "mount failed"
22802         stop ost1 || error "cannot stop ost1"
22803         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22804 }
22805 run_test 232b "failed data version lock should not block umount"
22806
22807 test_233a() {
22808         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22809                 skip "Need MDS version at least 2.3.64"
22810         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22811
22812         local fid=$($LFS path2fid $MOUNT)
22813
22814         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22815                 error "cannot access $MOUNT using its FID '$fid'"
22816 }
22817 run_test 233a "checking that OBF of the FS root succeeds"
22818
22819 test_233b() {
22820         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22821                 skip "Need MDS version at least 2.5.90"
22822         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22823
22824         local fid=$($LFS path2fid $MOUNT/.lustre)
22825
22826         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22827                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22828
22829         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22830         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22831                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22832 }
22833 run_test 233b "checking that OBF of the FS .lustre succeeds"
22834
22835 test_234() {
22836         local p="$TMP/sanityN-$TESTNAME.parameters"
22837         save_lustre_params client "llite.*.xattr_cache" > $p
22838         lctl set_param llite.*.xattr_cache 1 ||
22839                 skip_env "xattr cache is not supported"
22840
22841         mkdir -p $DIR/$tdir || error "mkdir failed"
22842         touch $DIR/$tdir/$tfile || error "touch failed"
22843         # OBD_FAIL_LLITE_XATTR_ENOMEM
22844         $LCTL set_param fail_loc=0x1405
22845         getfattr -n user.attr $DIR/$tdir/$tfile &&
22846                 error "getfattr should have failed with ENOMEM"
22847         $LCTL set_param fail_loc=0x0
22848         rm -rf $DIR/$tdir
22849
22850         restore_lustre_params < $p
22851         rm -f $p
22852 }
22853 run_test 234 "xattr cache should not crash on ENOMEM"
22854
22855 test_235() {
22856         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22857                 skip "Need MDS version at least 2.4.52"
22858
22859         flock_deadlock $DIR/$tfile
22860         local RC=$?
22861         case $RC in
22862                 0)
22863                 ;;
22864                 124) error "process hangs on a deadlock"
22865                 ;;
22866                 *) error "error executing flock_deadlock $DIR/$tfile"
22867                 ;;
22868         esac
22869 }
22870 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22871
22872 #LU-2935
22873 test_236() {
22874         check_swap_layouts_support
22875
22876         local ref1=/etc/passwd
22877         local ref2=/etc/group
22878         local file1=$DIR/$tdir/f1
22879         local file2=$DIR/$tdir/f2
22880
22881         test_mkdir -c1 $DIR/$tdir
22882         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22883         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22884         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22885         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22886         local fd=$(free_fd)
22887         local cmd="exec $fd<>$file2"
22888         eval $cmd
22889         rm $file2
22890         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22891                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22892         cmd="exec $fd>&-"
22893         eval $cmd
22894         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22895
22896         #cleanup
22897         rm -rf $DIR/$tdir
22898 }
22899 run_test 236 "Layout swap on open unlinked file"
22900
22901 # LU-4659 linkea consistency
22902 test_238() {
22903         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22904                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22905                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22906                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22907
22908         touch $DIR/$tfile
22909         ln $DIR/$tfile $DIR/$tfile.lnk
22910         touch $DIR/$tfile.new
22911         mv $DIR/$tfile.new $DIR/$tfile
22912         local fid1=$($LFS path2fid $DIR/$tfile)
22913         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22914         local path1=$($LFS fid2path $FSNAME "$fid1")
22915         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22916         local path2=$($LFS fid2path $FSNAME "$fid2")
22917         [ $tfile.lnk == $path2 ] ||
22918                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22919         rm -f $DIR/$tfile*
22920 }
22921 run_test 238 "Verify linkea consistency"
22922
22923 test_239A() { # was test_239
22924         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22925                 skip "Need MDS version at least 2.5.60"
22926
22927         local list=$(comma_list $(mdts_nodes))
22928
22929         mkdir -p $DIR/$tdir
22930         createmany -o $DIR/$tdir/f- 5000
22931         unlinkmany $DIR/$tdir/f- 5000
22932         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22933                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22934         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22935                         osp.*MDT*.sync_in_flight" | calc_sum)
22936         [ "$changes" -eq 0 ] || error "$changes not synced"
22937 }
22938 run_test 239A "osp_sync test"
22939
22940 test_239a() { #LU-5297
22941         remote_mds_nodsh && skip "remote MDS with nodsh"
22942
22943         touch $DIR/$tfile
22944         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22945         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22946         chgrp $RUNAS_GID $DIR/$tfile
22947         wait_delete_completed
22948 }
22949 run_test 239a "process invalid osp sync record correctly"
22950
22951 test_239b() { #LU-5297
22952         remote_mds_nodsh && skip "remote MDS with nodsh"
22953
22954         touch $DIR/$tfile1
22955         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22956         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22957         chgrp $RUNAS_GID $DIR/$tfile1
22958         wait_delete_completed
22959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22960         touch $DIR/$tfile2
22961         chgrp $RUNAS_GID $DIR/$tfile2
22962         wait_delete_completed
22963 }
22964 run_test 239b "process osp sync record with ENOMEM error correctly"
22965
22966 test_240() {
22967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22968         remote_mds_nodsh && skip "remote MDS with nodsh"
22969
22970         mkdir -p $DIR/$tdir
22971
22972         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22973                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22974         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22975                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22976
22977         umount_client $MOUNT || error "umount failed"
22978         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22979         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22980         mount_client $MOUNT || error "failed to mount client"
22981
22982         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22983         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22984 }
22985 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22986
22987 test_241_bio() {
22988         local count=$1
22989         local bsize=$2
22990
22991         for LOOP in $(seq $count); do
22992                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22993                 cancel_lru_locks $OSC || true
22994         done
22995 }
22996
22997 test_241_dio() {
22998         local count=$1
22999         local bsize=$2
23000
23001         for LOOP in $(seq $1); do
23002                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23003                         2>/dev/null
23004         done
23005 }
23006
23007 test_241a() { # was test_241
23008         local bsize=$PAGE_SIZE
23009
23010         (( bsize < 40960 )) && bsize=40960
23011         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23012         ls -la $DIR/$tfile
23013         cancel_lru_locks $OSC
23014         test_241_bio 1000 $bsize &
23015         PID=$!
23016         test_241_dio 1000 $bsize
23017         wait $PID
23018 }
23019 run_test 241a "bio vs dio"
23020
23021 test_241b() {
23022         local bsize=$PAGE_SIZE
23023
23024         (( bsize < 40960 )) && bsize=40960
23025         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23026         ls -la $DIR/$tfile
23027         test_241_dio 1000 $bsize &
23028         PID=$!
23029         test_241_dio 1000 $bsize
23030         wait $PID
23031 }
23032 run_test 241b "dio vs dio"
23033
23034 test_242() {
23035         remote_mds_nodsh && skip "remote MDS with nodsh"
23036
23037         mkdir_on_mdt0 $DIR/$tdir
23038         touch $DIR/$tdir/$tfile
23039
23040         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23041         do_facet mds1 lctl set_param fail_loc=0x105
23042         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23043
23044         do_facet mds1 lctl set_param fail_loc=0
23045         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23046 }
23047 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23048
23049 test_243()
23050 {
23051         test_mkdir $DIR/$tdir
23052         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23053 }
23054 run_test 243 "various group lock tests"
23055
23056 test_244a()
23057 {
23058         test_mkdir $DIR/$tdir
23059         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23060         sendfile_grouplock $DIR/$tdir/$tfile || \
23061                 error "sendfile+grouplock failed"
23062         rm -rf $DIR/$tdir
23063 }
23064 run_test 244a "sendfile with group lock tests"
23065
23066 test_244b()
23067 {
23068         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23069
23070         local threads=50
23071         local size=$((1024*1024))
23072
23073         test_mkdir $DIR/$tdir
23074         for i in $(seq 1 $threads); do
23075                 local file=$DIR/$tdir/file_$((i / 10))
23076                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23077                 local pids[$i]=$!
23078         done
23079         for i in $(seq 1 $threads); do
23080                 wait ${pids[$i]}
23081         done
23082 }
23083 run_test 244b "multi-threaded write with group lock"
23084
23085 test_245a() {
23086         local flagname="multi_mod_rpcs"
23087         local connect_data_name="max_mod_rpcs"
23088         local out
23089
23090         # check if multiple modify RPCs flag is set
23091         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23092                 grep "connect_flags:")
23093         echo "$out"
23094
23095         echo "$out" | grep -qw $flagname
23096         if [ $? -ne 0 ]; then
23097                 echo "connect flag $flagname is not set"
23098                 return
23099         fi
23100
23101         # check if multiple modify RPCs data is set
23102         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23103         echo "$out"
23104
23105         echo "$out" | grep -qw $connect_data_name ||
23106                 error "import should have connect data $connect_data_name"
23107 }
23108 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23109
23110 test_245b() {
23111         local flagname="multi_mod_rpcs"
23112         local connect_data_name="max_mod_rpcs"
23113         local out
23114
23115         remote_mds_nodsh && skip "remote MDS with nodsh"
23116         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23117
23118         # check if multiple modify RPCs flag is set
23119         out=$(do_facet mds1 \
23120               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23121               grep "connect_flags:")
23122         echo "$out"
23123
23124         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23125
23126         # check if multiple modify RPCs data is set
23127         out=$(do_facet mds1 \
23128               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23129
23130         [[ "$out" =~ $connect_data_name ]] ||
23131                 {
23132                         echo "$out"
23133                         error "missing connect data $connect_data_name"
23134                 }
23135 }
23136 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23137
23138 cleanup_247() {
23139         local submount=$1
23140
23141         trap 0
23142         umount_client $submount
23143         rmdir $submount
23144 }
23145
23146 test_247a() {
23147         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23148                 grep -q subtree ||
23149                 skip_env "Fileset feature is not supported"
23150
23151         local submount=${MOUNT}_$tdir
23152
23153         mkdir $MOUNT/$tdir
23154         mkdir -p $submount || error "mkdir $submount failed"
23155         FILESET="$FILESET/$tdir" mount_client $submount ||
23156                 error "mount $submount failed"
23157         trap "cleanup_247 $submount" EXIT
23158         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23159         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23160                 error "read $MOUNT/$tdir/$tfile failed"
23161         cleanup_247 $submount
23162 }
23163 run_test 247a "mount subdir as fileset"
23164
23165 test_247b() {
23166         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23167                 skip_env "Fileset feature is not supported"
23168
23169         local submount=${MOUNT}_$tdir
23170
23171         rm -rf $MOUNT/$tdir
23172         mkdir -p $submount || error "mkdir $submount failed"
23173         SKIP_FILESET=1
23174         FILESET="$FILESET/$tdir" mount_client $submount &&
23175                 error "mount $submount should fail"
23176         rmdir $submount
23177 }
23178 run_test 247b "mount subdir that dose not exist"
23179
23180 test_247c() {
23181         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23182                 skip_env "Fileset feature is not supported"
23183
23184         local submount=${MOUNT}_$tdir
23185
23186         mkdir -p $MOUNT/$tdir/dir1
23187         mkdir -p $submount || error "mkdir $submount failed"
23188         trap "cleanup_247 $submount" EXIT
23189         FILESET="$FILESET/$tdir" mount_client $submount ||
23190                 error "mount $submount failed"
23191         local fid=$($LFS path2fid $MOUNT/)
23192         $LFS fid2path $submount $fid && error "fid2path should fail"
23193         cleanup_247 $submount
23194 }
23195 run_test 247c "running fid2path outside subdirectory root"
23196
23197 test_247d() {
23198         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23199                 skip "Fileset feature is not supported"
23200
23201         local submount=${MOUNT}_$tdir
23202
23203         mkdir -p $MOUNT/$tdir/dir1
23204         mkdir -p $submount || error "mkdir $submount failed"
23205         FILESET="$FILESET/$tdir" mount_client $submount ||
23206                 error "mount $submount failed"
23207         trap "cleanup_247 $submount" EXIT
23208
23209         local td=$submount/dir1
23210         local fid=$($LFS path2fid $td)
23211         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23212
23213         # check that we get the same pathname back
23214         local rootpath
23215         local found
23216         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23217                 echo "$rootpath $fid"
23218                 found=$($LFS fid2path $rootpath "$fid")
23219                 [ -n "$found" ] || error "fid2path should succeed"
23220                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23221         done
23222         # check wrong root path format
23223         rootpath=$submount"_wrong"
23224         found=$($LFS fid2path $rootpath "$fid")
23225         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23226
23227         cleanup_247 $submount
23228 }
23229 run_test 247d "running fid2path inside subdirectory root"
23230
23231 # LU-8037
23232 test_247e() {
23233         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23234                 grep -q subtree ||
23235                 skip "Fileset feature is not supported"
23236
23237         local submount=${MOUNT}_$tdir
23238
23239         mkdir $MOUNT/$tdir
23240         mkdir -p $submount || error "mkdir $submount failed"
23241         FILESET="$FILESET/.." mount_client $submount &&
23242                 error "mount $submount should fail"
23243         rmdir $submount
23244 }
23245 run_test 247e "mount .. as fileset"
23246
23247 test_247f() {
23248         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23249         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23250                 skip "Need at least version 2.14.50.162"
23251         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23252                 skip "Fileset feature is not supported"
23253
23254         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23255         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23256                 error "mkdir remote failed"
23257         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23258                 error "mkdir remote/subdir failed"
23259         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23260                 error "mkdir striped failed"
23261         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23262
23263         local submount=${MOUNT}_$tdir
23264
23265         mkdir -p $submount || error "mkdir $submount failed"
23266         stack_trap "rmdir $submount"
23267
23268         local dir
23269         local fileset=$FILESET
23270         local mdts=$(comma_list $(mdts_nodes))
23271
23272         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23273         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23274                 $tdir/striped/subdir $tdir/striped/.; do
23275                 FILESET="$fileset/$dir" mount_client $submount ||
23276                         error "mount $dir failed"
23277                 umount_client $submount
23278         done
23279 }
23280 run_test 247f "mount striped or remote directory as fileset"
23281
23282 test_subdir_mount_lock()
23283 {
23284         local testdir=$1
23285         local submount=${MOUNT}_$(basename $testdir)
23286
23287         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23288
23289         mkdir -p $submount || error "mkdir $submount failed"
23290         stack_trap "rmdir $submount"
23291
23292         FILESET="$fileset/$testdir" mount_client $submount ||
23293                 error "mount $FILESET failed"
23294         stack_trap "umount $submount"
23295
23296         local mdts=$(comma_list $(mdts_nodes))
23297
23298         local nrpcs
23299
23300         stat $submount > /dev/null || error "stat $submount failed"
23301         cancel_lru_locks $MDC
23302         stat $submount > /dev/null || error "stat $submount failed"
23303         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23304         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23305         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23306         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23307                 awk '/getattr/ {sum += $2} END {print sum}')
23308
23309         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23310 }
23311
23312 test_247g() {
23313         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23314
23315         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23316                 error "mkdir $tdir failed"
23317         test_subdir_mount_lock $tdir
23318 }
23319 run_test 247g "striped directory submount revalidate ROOT from cache"
23320
23321 test_247h() {
23322         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23323         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23324                 skip "Need MDS version at least 2.15.51"
23325
23326         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23327         test_subdir_mount_lock $tdir
23328         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23329         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23330                 error "mkdir $tdir.1 failed"
23331         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23332 }
23333 run_test 247h "remote directory submount revalidate ROOT from cache"
23334
23335 test_248a() {
23336         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23337         [ -z "$fast_read_sav" ] && skip "no fast read support"
23338
23339         # create a large file for fast read verification
23340         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23341
23342         # make sure the file is created correctly
23343         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23344                 { rm -f $DIR/$tfile; skip "file creation error"; }
23345
23346         echo "Test 1: verify that fast read is 4 times faster on cache read"
23347
23348         # small read with fast read enabled
23349         $LCTL set_param -n llite.*.fast_read=1
23350         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23351                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23352                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23353         # small read with fast read disabled
23354         $LCTL set_param -n llite.*.fast_read=0
23355         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23356                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23357                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23358
23359         # verify that fast read is 4 times faster for cache read
23360         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23361                 error_not_in_vm "fast read was not 4 times faster: " \
23362                            "$t_fast vs $t_slow"
23363
23364         echo "Test 2: verify the performance between big and small read"
23365         $LCTL set_param -n llite.*.fast_read=1
23366
23367         # 1k non-cache read
23368         cancel_lru_locks osc
23369         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23370                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23371                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23372
23373         # 1M non-cache read
23374         cancel_lru_locks osc
23375         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23376                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23377                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23378
23379         # verify that big IO is not 4 times faster than small IO
23380         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23381                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23382
23383         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23384         rm -f $DIR/$tfile
23385 }
23386 run_test 248a "fast read verification"
23387
23388 test_248b() {
23389         # Default short_io_bytes=16384, try both smaller and larger sizes.
23390         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23391         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23392         echo "bs=53248 count=113 normal buffered write"
23393         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23394                 error "dd of initial data file failed"
23395         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23396
23397         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23398         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23399                 error "dd with sync normal writes failed"
23400         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23401
23402         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23403         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23404                 error "dd with sync small writes failed"
23405         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23406
23407         cancel_lru_locks osc
23408
23409         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23410         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23411         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23412         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23413                 iflag=direct || error "dd with O_DIRECT small read failed"
23414         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23415         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23416                 error "compare $TMP/$tfile.1 failed"
23417
23418         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23419         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23420
23421         # just to see what the maximum tunable value is, and test parsing
23422         echo "test invalid parameter 2MB"
23423         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23424                 error "too-large short_io_bytes allowed"
23425         echo "test maximum parameter 512KB"
23426         # if we can set a larger short_io_bytes, run test regardless of version
23427         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23428                 # older clients may not allow setting it this large, that's OK
23429                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23430                         skip "Need at least client version 2.13.50"
23431                 error "medium short_io_bytes failed"
23432         fi
23433         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23434         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23435
23436         echo "test large parameter 64KB"
23437         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23438         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23439
23440         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23441         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23442                 error "dd with sync large writes failed"
23443         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23444
23445         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23446         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23447         num=$((113 * 4096 / PAGE_SIZE))
23448         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23449         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23450                 error "dd with O_DIRECT large writes failed"
23451         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23452                 error "compare $DIR/$tfile.3 failed"
23453
23454         cancel_lru_locks osc
23455
23456         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23457         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23458                 error "dd with O_DIRECT large read failed"
23459         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23460                 error "compare $TMP/$tfile.2 failed"
23461
23462         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23463         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23464                 error "dd with O_DIRECT large read failed"
23465         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23466                 error "compare $TMP/$tfile.3 failed"
23467 }
23468 run_test 248b "test short_io read and write for both small and large sizes"
23469
23470 test_249() { # LU-7890
23471         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23472                 skip "Need at least version 2.8.54"
23473
23474         rm -f $DIR/$tfile
23475         $LFS setstripe -c 1 $DIR/$tfile
23476         # Offset 2T == 4k * 512M
23477         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23478                 error "dd to 2T offset failed"
23479 }
23480 run_test 249 "Write above 2T file size"
23481
23482 test_250() {
23483         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23484          && skip "no 16TB file size limit on ZFS"
23485
23486         $LFS setstripe -c 1 $DIR/$tfile
23487         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23488         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23489         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23490         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23491                 conv=notrunc,fsync && error "append succeeded"
23492         return 0
23493 }
23494 run_test 250 "Write above 16T limit"
23495
23496 test_251() {
23497         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23498
23499         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23500         #Skip once - writing the first stripe will succeed
23501         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23502         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23503                 error "short write happened"
23504
23505         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23506         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23507                 error "short read happened"
23508
23509         rm -f $DIR/$tfile
23510 }
23511 run_test 251 "Handling short read and write correctly"
23512
23513 test_252() {
23514         remote_mds_nodsh && skip "remote MDS with nodsh"
23515         remote_ost_nodsh && skip "remote OST with nodsh"
23516         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23517                 skip_env "ldiskfs only test"
23518         fi
23519
23520         local tgt
23521         local dev
23522         local out
23523         local uuid
23524         local num
23525         local gen
23526
23527         # check lr_reader on OST0000
23528         tgt=ost1
23529         dev=$(facet_device $tgt)
23530         out=$(do_facet $tgt $LR_READER $dev)
23531         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23532         echo "$out"
23533         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23534         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23535                 error "Invalid uuid returned by $LR_READER on target $tgt"
23536         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23537
23538         # check lr_reader -c on MDT0000
23539         tgt=mds1
23540         dev=$(facet_device $tgt)
23541         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23542                 skip "$LR_READER does not support additional options"
23543         fi
23544         out=$(do_facet $tgt $LR_READER -c $dev)
23545         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23546         echo "$out"
23547         num=$(echo "$out" | grep -c "mdtlov")
23548         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23549                 error "Invalid number of mdtlov clients returned by $LR_READER"
23550         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23551
23552         # check lr_reader -cr on MDT0000
23553         out=$(do_facet $tgt $LR_READER -cr $dev)
23554         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23555         echo "$out"
23556         echo "$out" | grep -q "^reply_data:$" ||
23557                 error "$LR_READER should have returned 'reply_data' section"
23558         num=$(echo "$out" | grep -c "client_generation")
23559         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23560 }
23561 run_test 252 "check lr_reader tool"
23562
23563 test_253() {
23564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23565         remote_mds_nodsh && skip "remote MDS with nodsh"
23566         remote_mgs_nodsh && skip "remote MGS with nodsh"
23567
23568         local ostidx=0
23569         local rc=0
23570         local ost_name=$(ostname_from_index $ostidx)
23571
23572         # on the mdt's osc
23573         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23574         do_facet $SINGLEMDS $LCTL get_param -n \
23575                 osp.$mdtosc_proc1.reserved_mb_high ||
23576                 skip  "remote MDS does not support reserved_mb_high"
23577
23578         rm -rf $DIR/$tdir
23579         wait_mds_ost_sync
23580         wait_delete_completed
23581         mkdir $DIR/$tdir
23582         stack_trap "rm -rf $DIR/$tdir"
23583
23584         pool_add $TESTNAME || error "Pool creation failed"
23585         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23586
23587         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23588                 error "Setstripe failed"
23589
23590         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23591
23592         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23593                     grep "watermarks")
23594         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23595
23596         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23597                         osp.$mdtosc_proc1.prealloc_status)
23598         echo "prealloc_status $oa_status"
23599
23600         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23601                 error "File creation should fail"
23602
23603         #object allocation was stopped, but we still able to append files
23604         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23605                 oflag=append || error "Append failed"
23606
23607         rm -f $DIR/$tdir/$tfile.0
23608
23609         # For this test, we want to delete the files we created to go out of
23610         # space but leave the watermark, so we remain nearly out of space
23611         ost_watermarks_enospc_delete_files $tfile $ostidx
23612
23613         wait_delete_completed
23614
23615         sleep_maxage
23616
23617         for i in $(seq 10 12); do
23618                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23619                         2>/dev/null || error "File creation failed after rm"
23620         done
23621
23622         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23623                         osp.$mdtosc_proc1.prealloc_status)
23624         echo "prealloc_status $oa_status"
23625
23626         if (( oa_status != 0 )); then
23627                 error "Object allocation still disable after rm"
23628         fi
23629 }
23630 run_test 253 "Check object allocation limit"
23631
23632 test_254() {
23633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23634         remote_mds_nodsh && skip "remote MDS with nodsh"
23635
23636         local mdt=$(facet_svc $SINGLEMDS)
23637
23638         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23639                 skip "MDS does not support changelog_size"
23640
23641         local cl_user
23642
23643         changelog_register || error "changelog_register failed"
23644
23645         changelog_clear 0 || error "changelog_clear failed"
23646
23647         local size1=$(do_facet $SINGLEMDS \
23648                       $LCTL get_param -n mdd.$mdt.changelog_size)
23649         echo "Changelog size $size1"
23650
23651         rm -rf $DIR/$tdir
23652         $LFS mkdir -i 0 $DIR/$tdir
23653         # change something
23654         mkdir -p $DIR/$tdir/pics/2008/zachy
23655         touch $DIR/$tdir/pics/2008/zachy/timestamp
23656         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23657         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23658         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23659         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23660         rm $DIR/$tdir/pics/desktop.jpg
23661
23662         local size2=$(do_facet $SINGLEMDS \
23663                       $LCTL get_param -n mdd.$mdt.changelog_size)
23664         echo "Changelog size after work $size2"
23665
23666         (( $size2 > $size1 )) ||
23667                 error "new Changelog size=$size2 less than old size=$size1"
23668 }
23669 run_test 254 "Check changelog size"
23670
23671 ladvise_no_type()
23672 {
23673         local type=$1
23674         local file=$2
23675
23676         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23677                 awk -F: '{print $2}' | grep $type > /dev/null
23678         if [ $? -ne 0 ]; then
23679                 return 0
23680         fi
23681         return 1
23682 }
23683
23684 ladvise_no_ioctl()
23685 {
23686         local file=$1
23687
23688         lfs ladvise -a willread $file > /dev/null 2>&1
23689         if [ $? -eq 0 ]; then
23690                 return 1
23691         fi
23692
23693         lfs ladvise -a willread $file 2>&1 |
23694                 grep "Inappropriate ioctl for device" > /dev/null
23695         if [ $? -eq 0 ]; then
23696                 return 0
23697         fi
23698         return 1
23699 }
23700
23701 percent() {
23702         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23703 }
23704
23705 # run a random read IO workload
23706 # usage: random_read_iops <filename> <filesize> <iosize>
23707 random_read_iops() {
23708         local file=$1
23709         local fsize=$2
23710         local iosize=${3:-4096}
23711
23712         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23713                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23714 }
23715
23716 drop_file_oss_cache() {
23717         local file="$1"
23718         local nodes="$2"
23719
23720         $LFS ladvise -a dontneed $file 2>/dev/null ||
23721                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23722 }
23723
23724 ladvise_willread_performance()
23725 {
23726         local repeat=10
23727         local average_origin=0
23728         local average_cache=0
23729         local average_ladvise=0
23730
23731         for ((i = 1; i <= $repeat; i++)); do
23732                 echo "Iter $i/$repeat: reading without willread hint"
23733                 cancel_lru_locks osc
23734                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23735                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23736                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23737                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23738
23739                 cancel_lru_locks osc
23740                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23741                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23742                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23743
23744                 cancel_lru_locks osc
23745                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23746                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23747                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23748                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23749                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23750         done
23751         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23752         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23753         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23754
23755         speedup_cache=$(percent $average_cache $average_origin)
23756         speedup_ladvise=$(percent $average_ladvise $average_origin)
23757
23758         echo "Average uncached read: $average_origin"
23759         echo "Average speedup with OSS cached read: " \
23760                 "$average_cache = +$speedup_cache%"
23761         echo "Average speedup with ladvise willread: " \
23762                 "$average_ladvise = +$speedup_ladvise%"
23763
23764         local lowest_speedup=20
23765         if (( ${average_cache%.*} < $lowest_speedup )); then
23766                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23767                      " got $average_cache%. Skipping ladvise willread check."
23768                 return 0
23769         fi
23770
23771         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23772         # it is still good to run until then to exercise 'ladvise willread'
23773         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23774                 [ "$ost1_FSTYPE" = "zfs" ] &&
23775                 echo "osd-zfs does not support dontneed or drop_caches" &&
23776                 return 0
23777
23778         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23779         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23780                 error_not_in_vm "Speedup with willread is less than " \
23781                         "$lowest_speedup%, got $average_ladvise%"
23782 }
23783
23784 test_255a() {
23785         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23786                 skip "lustre < 2.8.54 does not support ladvise "
23787         remote_ost_nodsh && skip "remote OST with nodsh"
23788
23789         stack_trap "rm -f $DIR/$tfile"
23790         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23791
23792         ladvise_no_type willread $DIR/$tfile &&
23793                 skip "willread ladvise is not supported"
23794
23795         ladvise_no_ioctl $DIR/$tfile &&
23796                 skip "ladvise ioctl is not supported"
23797
23798         local size_mb=100
23799         local size=$((size_mb * 1048576))
23800         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23801                 error "dd to $DIR/$tfile failed"
23802
23803         lfs ladvise -a willread $DIR/$tfile ||
23804                 error "Ladvise failed with no range argument"
23805
23806         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23807                 error "Ladvise failed with no -l or -e argument"
23808
23809         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23810                 error "Ladvise failed with only -e argument"
23811
23812         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23813                 error "Ladvise failed with only -l argument"
23814
23815         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23816                 error "End offset should not be smaller than start offset"
23817
23818         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23819                 error "End offset should not be equal to start offset"
23820
23821         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23822                 error "Ladvise failed with overflowing -s argument"
23823
23824         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23825                 error "Ladvise failed with overflowing -e argument"
23826
23827         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23828                 error "Ladvise failed with overflowing -l argument"
23829
23830         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23831                 error "Ladvise succeeded with conflicting -l and -e arguments"
23832
23833         echo "Synchronous ladvise should wait"
23834         local delay=8
23835 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23836         do_nodes $(comma_list $(osts_nodes)) \
23837                 $LCTL set_param fail_val=$delay fail_loc=0x237
23838         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23839                 $LCTL set_param fail_loc=0"
23840
23841         local start_ts=$SECONDS
23842         lfs ladvise -a willread $DIR/$tfile ||
23843                 error "Ladvise failed with no range argument"
23844         local end_ts=$SECONDS
23845         local inteval_ts=$((end_ts - start_ts))
23846
23847         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23848                 error "Synchronous advice didn't wait reply"
23849         fi
23850
23851         echo "Asynchronous ladvise shouldn't wait"
23852         local start_ts=$SECONDS
23853         lfs ladvise -a willread -b $DIR/$tfile ||
23854                 error "Ladvise failed with no range argument"
23855         local end_ts=$SECONDS
23856         local inteval_ts=$((end_ts - start_ts))
23857
23858         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23859                 error "Asynchronous advice blocked"
23860         fi
23861
23862         ladvise_willread_performance
23863 }
23864 run_test 255a "check 'lfs ladvise -a willread'"
23865
23866 facet_meminfo() {
23867         local facet=$1
23868         local info=$2
23869
23870         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23871 }
23872
23873 test_255b() {
23874         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23875                 skip "lustre < 2.8.54 does not support ladvise "
23876         remote_ost_nodsh && skip "remote OST with nodsh"
23877
23878         stack_trap "rm -f $DIR/$tfile"
23879         lfs setstripe -c 1 -i 0 $DIR/$tfile
23880
23881         ladvise_no_type dontneed $DIR/$tfile &&
23882                 skip "dontneed ladvise is not supported"
23883
23884         ladvise_no_ioctl $DIR/$tfile &&
23885                 skip "ladvise ioctl is not supported"
23886
23887         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23888                 [ "$ost1_FSTYPE" = "zfs" ] &&
23889                 skip "zfs-osd does not support 'ladvise dontneed'"
23890
23891         local size_mb=100
23892         local size=$((size_mb * 1048576))
23893         # In order to prevent disturbance of other processes, only check 3/4
23894         # of the memory usage
23895         local kibibytes=$((size_mb * 1024 * 3 / 4))
23896
23897         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23898                 error "dd to $DIR/$tfile failed"
23899
23900         #force write to complete before dropping OST cache & checking memory
23901         sync
23902
23903         local total=$(facet_meminfo ost1 MemTotal)
23904         echo "Total memory: $total KiB"
23905
23906         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23907         local before_read=$(facet_meminfo ost1 Cached)
23908         echo "Cache used before read: $before_read KiB"
23909
23910         lfs ladvise -a willread $DIR/$tfile ||
23911                 error "Ladvise willread failed"
23912         local after_read=$(facet_meminfo ost1 Cached)
23913         echo "Cache used after read: $after_read KiB"
23914
23915         lfs ladvise -a dontneed $DIR/$tfile ||
23916                 error "Ladvise dontneed again failed"
23917         local no_read=$(facet_meminfo ost1 Cached)
23918         echo "Cache used after dontneed ladvise: $no_read KiB"
23919
23920         if [ $total -lt $((before_read + kibibytes)) ]; then
23921                 echo "Memory is too small, abort checking"
23922                 return 0
23923         fi
23924
23925         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23926                 error "Ladvise willread should use more memory" \
23927                         "than $kibibytes KiB"
23928         fi
23929
23930         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23931                 error "Ladvise dontneed should release more memory" \
23932                         "than $kibibytes KiB"
23933         fi
23934 }
23935 run_test 255b "check 'lfs ladvise -a dontneed'"
23936
23937 test_255c() {
23938         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23939                 skip "lustre < 2.10.50 does not support lockahead"
23940
23941         local ost1_imp=$(get_osc_import_name client ost1)
23942         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23943                          cut -d'.' -f2)
23944         local count
23945         local new_count
23946         local difference
23947         local i
23948         local rc
23949
23950         test_mkdir -p $DIR/$tdir
23951         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23952
23953         #test 10 returns only success/failure
23954         i=10
23955         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23956         rc=$?
23957         if [ $rc -eq 255 ]; then
23958                 error "Ladvise test${i} failed, ${rc}"
23959         fi
23960
23961         #test 11 counts lock enqueue requests, all others count new locks
23962         i=11
23963         count=$(do_facet ost1 \
23964                 $LCTL get_param -n ost.OSS.ost.stats)
23965         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23966
23967         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23968         rc=$?
23969         if [ $rc -eq 255 ]; then
23970                 error "Ladvise test${i} failed, ${rc}"
23971         fi
23972
23973         new_count=$(do_facet ost1 \
23974                 $LCTL get_param -n ost.OSS.ost.stats)
23975         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23976                    awk '{ print $2 }')
23977
23978         difference="$((new_count - count))"
23979         if [ $difference -ne $rc ]; then
23980                 error "Ladvise test${i}, bad enqueue count, returned " \
23981                       "${rc}, actual ${difference}"
23982         fi
23983
23984         for i in $(seq 12 21); do
23985                 # If we do not do this, we run the risk of having too many
23986                 # locks and starting lock cancellation while we are checking
23987                 # lock counts.
23988                 cancel_lru_locks osc
23989
23990                 count=$($LCTL get_param -n \
23991                        ldlm.namespaces.$imp_name.lock_unused_count)
23992
23993                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23994                 rc=$?
23995                 if [ $rc -eq 255 ]; then
23996                         error "Ladvise test ${i} failed, ${rc}"
23997                 fi
23998
23999                 new_count=$($LCTL get_param -n \
24000                        ldlm.namespaces.$imp_name.lock_unused_count)
24001                 difference="$((new_count - count))"
24002
24003                 # Test 15 output is divided by 100 to map down to valid return
24004                 if [ $i -eq 15 ]; then
24005                         rc="$((rc * 100))"
24006                 fi
24007
24008                 if [ $difference -ne $rc ]; then
24009                         error "Ladvise test ${i}, bad lock count, returned " \
24010                               "${rc}, actual ${difference}"
24011                 fi
24012         done
24013
24014         #test 22 returns only success/failure
24015         i=22
24016         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24017         rc=$?
24018         if [ $rc -eq 255 ]; then
24019                 error "Ladvise test${i} failed, ${rc}"
24020         fi
24021 }
24022 run_test 255c "suite of ladvise lockahead tests"
24023
24024 test_256() {
24025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24026         remote_mds_nodsh && skip "remote MDS with nodsh"
24027         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24028         changelog_users $SINGLEMDS | grep "^cl" &&
24029                 skip "active changelog user"
24030
24031         local cl_user
24032         local cat_sl
24033         local mdt_dev
24034
24035         mdt_dev=$(facet_device $SINGLEMDS)
24036         echo $mdt_dev
24037
24038         changelog_register || error "changelog_register failed"
24039
24040         rm -rf $DIR/$tdir
24041         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24042
24043         changelog_clear 0 || error "changelog_clear failed"
24044
24045         # change something
24046         touch $DIR/$tdir/{1..10}
24047
24048         # stop the MDT
24049         stop $SINGLEMDS || error "Fail to stop MDT"
24050
24051         # remount the MDT
24052         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24053                 error "Fail to start MDT"
24054
24055         #after mount new plainllog is used
24056         touch $DIR/$tdir/{11..19}
24057         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24058         stack_trap "rm -f $tmpfile"
24059         cat_sl=$(do_facet $SINGLEMDS "sync; \
24060                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24061                  llog_reader $tmpfile | grep -c type=1064553b")
24062         do_facet $SINGLEMDS llog_reader $tmpfile
24063
24064         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24065
24066         changelog_clear 0 || error "changelog_clear failed"
24067
24068         cat_sl=$(do_facet $SINGLEMDS "sync; \
24069                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24070                  llog_reader $tmpfile | grep -c type=1064553b")
24071
24072         if (( cat_sl == 2 )); then
24073                 error "Empty plain llog was not deleted from changelog catalog"
24074         elif (( cat_sl != 1 )); then
24075                 error "Active plain llog shouldn't be deleted from catalog"
24076         fi
24077 }
24078 run_test 256 "Check llog delete for empty and not full state"
24079
24080 test_257() {
24081         remote_mds_nodsh && skip "remote MDS with nodsh"
24082         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24083                 skip "Need MDS version at least 2.8.55"
24084
24085         test_mkdir $DIR/$tdir
24086
24087         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24088                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24089         stat $DIR/$tdir
24090
24091 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24092         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24093         local facet=mds$((mdtidx + 1))
24094         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24095         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24096
24097         stop $facet || error "stop MDS failed"
24098         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24099                 error "start MDS fail"
24100         wait_recovery_complete $facet
24101 }
24102 run_test 257 "xattr locks are not lost"
24103
24104 # Verify we take the i_mutex when security requires it
24105 test_258a() {
24106 #define OBD_FAIL_IMUTEX_SEC 0x141c
24107         $LCTL set_param fail_loc=0x141c
24108         touch $DIR/$tfile
24109         chmod u+s $DIR/$tfile
24110         chmod a+rwx $DIR/$tfile
24111         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24112         RC=$?
24113         if [ $RC -ne 0 ]; then
24114                 error "error, failed to take i_mutex, rc=$?"
24115         fi
24116         rm -f $DIR/$tfile
24117 }
24118 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24119
24120 # Verify we do NOT take the i_mutex in the normal case
24121 test_258b() {
24122 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24123         $LCTL set_param fail_loc=0x141d
24124         touch $DIR/$tfile
24125         chmod a+rwx $DIR
24126         chmod a+rw $DIR/$tfile
24127         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24128         RC=$?
24129         if [ $RC -ne 0 ]; then
24130                 error "error, took i_mutex unnecessarily, rc=$?"
24131         fi
24132         rm -f $DIR/$tfile
24133
24134 }
24135 run_test 258b "verify i_mutex security behavior"
24136
24137 test_259() {
24138         local file=$DIR/$tfile
24139         local before
24140         local after
24141
24142         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24143
24144         stack_trap "rm -f $file" EXIT
24145
24146         wait_delete_completed
24147         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24148         echo "before: $before"
24149
24150         $LFS setstripe -i 0 -c 1 $file
24151         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24152         sync_all_data
24153         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24154         echo "after write: $after"
24155
24156 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24157         do_facet ost1 $LCTL set_param fail_loc=0x2301
24158         $TRUNCATE $file 0
24159         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24160         echo "after truncate: $after"
24161
24162         stop ost1
24163         do_facet ost1 $LCTL set_param fail_loc=0
24164         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24165         sleep 2
24166         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24167         echo "after restart: $after"
24168         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24169                 error "missing truncate?"
24170
24171         return 0
24172 }
24173 run_test 259 "crash at delayed truncate"
24174
24175 test_260() {
24176 #define OBD_FAIL_MDC_CLOSE               0x806
24177         $LCTL set_param fail_loc=0x80000806
24178         touch $DIR/$tfile
24179
24180 }
24181 run_test 260 "Check mdc_close fail"
24182
24183 ### Data-on-MDT sanity tests ###
24184 test_270a() {
24185         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24186                 skip "Need MDS version at least 2.10.55 for DoM"
24187
24188         # create DoM file
24189         local dom=$DIR/$tdir/dom_file
24190         local tmp=$DIR/$tdir/tmp_file
24191
24192         mkdir_on_mdt0 $DIR/$tdir
24193
24194         # basic checks for DoM component creation
24195         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24196                 error "Can set MDT layout to non-first entry"
24197
24198         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24199                 error "Can define multiple entries as MDT layout"
24200
24201         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24202
24203         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24204         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24205         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24206
24207         local mdtidx=$($LFS getstripe -m $dom)
24208         local mdtname=MDT$(printf %04x $mdtidx)
24209         local facet=mds$((mdtidx + 1))
24210         local space_check=1
24211
24212         # Skip free space checks with ZFS
24213         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24214
24215         # write
24216         sync
24217         local size_tmp=$((65536 * 3))
24218         local mdtfree1=$(do_facet $facet \
24219                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24220
24221         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24222         # check also direct IO along write
24223         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24224         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24225         sync
24226         cmp $tmp $dom || error "file data is different"
24227         [ $(stat -c%s $dom) == $size_tmp ] ||
24228                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24229         if [ $space_check == 1 ]; then
24230                 local mdtfree2=$(do_facet $facet \
24231                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24232
24233                 # increase in usage from by $size_tmp
24234                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24235                         error "MDT free space wrong after write: " \
24236                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24237         fi
24238
24239         # truncate
24240         local size_dom=10000
24241
24242         $TRUNCATE $dom $size_dom
24243         [ $(stat -c%s $dom) == $size_dom ] ||
24244                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24245         if [ $space_check == 1 ]; then
24246                 mdtfree1=$(do_facet $facet \
24247                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24248                 # decrease in usage from $size_tmp to new $size_dom
24249                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24250                   $(((size_tmp - size_dom) / 1024)) ] ||
24251                         error "MDT free space is wrong after truncate: " \
24252                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24253         fi
24254
24255         # append
24256         cat $tmp >> $dom
24257         sync
24258         size_dom=$((size_dom + size_tmp))
24259         [ $(stat -c%s $dom) == $size_dom ] ||
24260                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24261         if [ $space_check == 1 ]; then
24262                 mdtfree2=$(do_facet $facet \
24263                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24264                 # increase in usage by $size_tmp from previous
24265                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24266                         error "MDT free space is wrong after append: " \
24267                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24268         fi
24269
24270         # delete
24271         rm $dom
24272         if [ $space_check == 1 ]; then
24273                 mdtfree1=$(do_facet $facet \
24274                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24275                 # decrease in usage by $size_dom from previous
24276                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24277                         error "MDT free space is wrong after removal: " \
24278                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24279         fi
24280
24281         # combined striping
24282         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24283                 error "Can't create DoM + OST striping"
24284
24285         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24286         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24287         # check also direct IO along write
24288         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24289         sync
24290         cmp $tmp $dom || error "file data is different"
24291         [ $(stat -c%s $dom) == $size_tmp ] ||
24292                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24293         rm $dom $tmp
24294
24295         return 0
24296 }
24297 run_test 270a "DoM: basic functionality tests"
24298
24299 test_270b() {
24300         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24301                 skip "Need MDS version at least 2.10.55"
24302
24303         local dom=$DIR/$tdir/dom_file
24304         local max_size=1048576
24305
24306         mkdir -p $DIR/$tdir
24307         $LFS setstripe -E $max_size -L mdt $dom
24308
24309         # truncate over the limit
24310         $TRUNCATE $dom $(($max_size + 1)) &&
24311                 error "successful truncate over the maximum size"
24312         # write over the limit
24313         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24314                 error "successful write over the maximum size"
24315         # append over the limit
24316         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24317         echo "12345" >> $dom && error "successful append over the maximum size"
24318         rm $dom
24319
24320         return 0
24321 }
24322 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24323
24324 test_270c() {
24325         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24326                 skip "Need MDS version at least 2.10.55"
24327
24328         mkdir -p $DIR/$tdir
24329         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24330
24331         # check files inherit DoM EA
24332         touch $DIR/$tdir/first
24333         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24334                 error "bad pattern"
24335         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24336                 error "bad stripe count"
24337         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24338                 error "bad stripe size"
24339
24340         # check directory inherits DoM EA and uses it as default
24341         mkdir $DIR/$tdir/subdir
24342         touch $DIR/$tdir/subdir/second
24343         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24344                 error "bad pattern in sub-directory"
24345         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24346                 error "bad stripe count in sub-directory"
24347         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24348                 error "bad stripe size in sub-directory"
24349         return 0
24350 }
24351 run_test 270c "DoM: DoM EA inheritance tests"
24352
24353 test_270d() {
24354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24355                 skip "Need MDS version at least 2.10.55"
24356
24357         mkdir -p $DIR/$tdir
24358         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24359
24360         # inherit default DoM striping
24361         mkdir $DIR/$tdir/subdir
24362         touch $DIR/$tdir/subdir/f1
24363
24364         # change default directory striping
24365         $LFS setstripe -c 1 $DIR/$tdir/subdir
24366         touch $DIR/$tdir/subdir/f2
24367         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24368                 error "wrong default striping in file 2"
24369         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24370                 error "bad pattern in file 2"
24371         return 0
24372 }
24373 run_test 270d "DoM: change striping from DoM to RAID0"
24374
24375 test_270e() {
24376         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24377                 skip "Need MDS version at least 2.10.55"
24378
24379         mkdir -p $DIR/$tdir/dom
24380         mkdir -p $DIR/$tdir/norm
24381         DOMFILES=20
24382         NORMFILES=10
24383         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24384         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24385
24386         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24387         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24388
24389         # find DoM files by layout
24390         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24391         [ $NUM -eq  $DOMFILES ] ||
24392                 error "lfs find -L: found $NUM, expected $DOMFILES"
24393         echo "Test 1: lfs find 20 DOM files by layout: OK"
24394
24395         # there should be 1 dir with default DOM striping
24396         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24397         [ $NUM -eq  1 ] ||
24398                 error "lfs find -L: found $NUM, expected 1 dir"
24399         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24400
24401         # find DoM files by stripe size
24402         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24403         [ $NUM -eq  $DOMFILES ] ||
24404                 error "lfs find -S: found $NUM, expected $DOMFILES"
24405         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24406
24407         # find files by stripe offset except DoM files
24408         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24409         [ $NUM -eq  $NORMFILES ] ||
24410                 error "lfs find -i: found $NUM, expected $NORMFILES"
24411         echo "Test 5: lfs find no DOM files by stripe index: OK"
24412         return 0
24413 }
24414 run_test 270e "DoM: lfs find with DoM files test"
24415
24416 test_270f() {
24417         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24418                 skip "Need MDS version at least 2.10.55"
24419
24420         local mdtname=${FSNAME}-MDT0000-mdtlov
24421         local dom=$DIR/$tdir/dom_file
24422         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24423                                                 lod.$mdtname.dom_stripesize)
24424         local dom_limit=131072
24425
24426         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24427         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24428                                                 lod.$mdtname.dom_stripesize)
24429         [ ${dom_limit} -eq ${dom_current} ] ||
24430                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24431
24432         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24433         $LFS setstripe -d $DIR/$tdir
24434         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24435                 error "Can't set directory default striping"
24436
24437         # exceed maximum stripe size
24438         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24439                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24440         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24441                 error "Able to create DoM component size more than LOD limit"
24442
24443         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24444         dom_current=$(do_facet mds1 $LCTL get_param -n \
24445                                                 lod.$mdtname.dom_stripesize)
24446         [ 0 -eq ${dom_current} ] ||
24447                 error "Can't set zero DoM stripe limit"
24448         rm $dom
24449
24450         # attempt to create DoM file on server with disabled DoM should
24451         # remove DoM entry from layout and be succeed
24452         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24453                 error "Can't create DoM file (DoM is disabled)"
24454         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24455                 error "File has DoM component while DoM is disabled"
24456         rm $dom
24457
24458         # attempt to create DoM file with only DoM stripe should return error
24459         $LFS setstripe -E $dom_limit -L mdt $dom &&
24460                 error "Able to create DoM-only file while DoM is disabled"
24461
24462         # too low values to be aligned with smallest stripe size 64K
24463         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24464         dom_current=$(do_facet mds1 $LCTL get_param -n \
24465                                                 lod.$mdtname.dom_stripesize)
24466         [ 30000 -eq ${dom_current} ] &&
24467                 error "Can set too small DoM stripe limit"
24468
24469         # 64K is a minimal stripe size in Lustre, expect limit of that size
24470         [ 65536 -eq ${dom_current} ] ||
24471                 error "Limit is not set to 64K but ${dom_current}"
24472
24473         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24474         dom_current=$(do_facet mds1 $LCTL get_param -n \
24475                                                 lod.$mdtname.dom_stripesize)
24476         echo $dom_current
24477         [ 2147483648 -eq ${dom_current} ] &&
24478                 error "Can set too large DoM stripe limit"
24479
24480         do_facet mds1 $LCTL set_param -n \
24481                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24482         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24483                 error "Can't create DoM component size after limit change"
24484         do_facet mds1 $LCTL set_param -n \
24485                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24486         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24487                 error "Can't create DoM file after limit decrease"
24488         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24489                 error "Can create big DoM component after limit decrease"
24490         touch ${dom}_def ||
24491                 error "Can't create file with old default layout"
24492
24493         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24494         return 0
24495 }
24496 run_test 270f "DoM: maximum DoM stripe size checks"
24497
24498 test_270g() {
24499         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24500                 skip "Need MDS version at least 2.13.52"
24501         local dom=$DIR/$tdir/$tfile
24502
24503         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24504         local lodname=${FSNAME}-MDT0000-mdtlov
24505
24506         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24507         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24508         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24509         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24510
24511         local dom_limit=1024
24512         local dom_threshold="50%"
24513
24514         $LFS setstripe -d $DIR/$tdir
24515         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24516                 error "Can't set directory default striping"
24517
24518         do_facet mds1 $LCTL set_param -n \
24519                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24520         # set 0 threshold and create DOM file to change tunable stripesize
24521         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24522         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24523                 error "Failed to create $dom file"
24524         # now tunable dom_cur_stripesize should reach maximum
24525         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24526                                         lod.${lodname}.dom_stripesize_cur_kb)
24527         [[ $dom_current == $dom_limit ]] ||
24528                 error "Current DOM stripesize is not maximum"
24529         rm $dom
24530
24531         # set threshold for further tests
24532         do_facet mds1 $LCTL set_param -n \
24533                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24534         echo "DOM threshold is $dom_threshold free space"
24535         local dom_def
24536         local dom_set
24537         # Spoof bfree to exceed threshold
24538         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24539         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24540         for spfree in 40 20 0 15 30 55; do
24541                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24542                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24543                         error "Failed to create $dom file"
24544                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24545                                         lod.${lodname}.dom_stripesize_cur_kb)
24546                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24547                 [[ $dom_def != $dom_current ]] ||
24548                         error "Default stripe size was not changed"
24549                 if (( spfree > 0 )) ; then
24550                         dom_set=$($LFS getstripe -S $dom)
24551                         (( dom_set == dom_def * 1024 )) ||
24552                                 error "DOM component size is still old"
24553                 else
24554                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24555                                 error "DoM component is set with no free space"
24556                 fi
24557                 rm $dom
24558                 dom_current=$dom_def
24559         done
24560 }
24561 run_test 270g "DoM: default DoM stripe size depends on free space"
24562
24563 test_270h() {
24564         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24565                 skip "Need MDS version at least 2.13.53"
24566
24567         local mdtname=${FSNAME}-MDT0000-mdtlov
24568         local dom=$DIR/$tdir/$tfile
24569         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24570
24571         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24572         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24573
24574         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24575         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24576                 error "can't create OST file"
24577         # mirrored file with DOM entry in the second mirror
24578         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24579                 error "can't create mirror with DoM component"
24580
24581         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24582
24583         # DOM component in the middle and has other enries in the same mirror,
24584         # should succeed but lost DoM component
24585         $LFS setstripe --copy=${dom}_1 $dom ||
24586                 error "Can't create file from OST|DOM mirror layout"
24587         # check new file has no DoM layout after all
24588         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24589                 error "File has DoM component while DoM is disabled"
24590 }
24591 run_test 270h "DoM: DoM stripe removal when disabled on server"
24592
24593 test_270i() {
24594         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24595                 skip "Need MDS version at least 2.14.54"
24596
24597         mkdir $DIR/$tdir
24598         # DoM with plain layout
24599         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24600                 error "default plain layout with DoM must fail"
24601         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24602                 error "setstripe plain file layout with DoM must fail"
24603         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24604                 error "default DoM layout with bad striping must fail"
24605         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24606                 error "setstripe to DoM layout with bad striping must fail"
24607         return 0
24608 }
24609 run_test 270i "DoM: setting invalid DoM striping should fail"
24610
24611 test_270j() {
24612         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24613                 skip "Need MDS version at least 2.15.55.203"
24614
24615         local dom=$DIR/$tdir/$tfile
24616         local odv
24617         local ndv
24618
24619         mkdir -p $DIR/$tdir
24620
24621         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24622
24623         odv=$($LFS data_version $dom)
24624         chmod 666 $dom
24625         mv $dom ${dom}_moved
24626         link ${dom}_moved $dom
24627         setfattr -n user.attrx -v "some_attr" $dom
24628         ndv=$($LFS data_version $dom)
24629         (( $ndv == $odv )) ||
24630                 error "data version was changed by metadata operations"
24631
24632         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24633                 error "failed to write data into $dom"
24634         cancel_lru_locks mdc
24635         ndv=$($LFS data_version $dom)
24636         (( $ndv != $odv )) ||
24637                 error "data version wasn't changed on write"
24638
24639         odv=$ndv
24640         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24641         ndv=$($LFS data_version $dom)
24642         (( $ndv != $odv )) ||
24643                 error "data version wasn't changed on truncate down"
24644
24645         odv=$ndv
24646         $TRUNCATE $dom 25000
24647         ndv=$($LFS data_version $dom)
24648         (( $ndv != $odv )) ||
24649                 error "data version wasn't changed on truncate up"
24650
24651         # check also fallocate for ldiskfs
24652         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24653                 odv=$ndv
24654                 fallocate -l 1048576 $dom
24655                 ndv=$($LFS data_version $dom)
24656                 (( $ndv != $odv )) ||
24657                         error "data version wasn't changed on fallocate"
24658
24659                 odv=$ndv
24660                 fallocate -p --offset 4096 -l 4096 $dom
24661                 ndv=$($LFS data_version $dom)
24662                 (( $ndv != $odv )) ||
24663                         error "data version wasn't changed on fallocate punch"
24664         fi
24665 }
24666 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24667
24668 test_271a() {
24669         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24670                 skip "Need MDS version at least 2.10.55"
24671
24672         local dom=$DIR/$tdir/dom
24673
24674         mkdir -p $DIR/$tdir
24675
24676         $LFS setstripe -E 1024K -L mdt $dom
24677
24678         lctl set_param -n mdc.*.stats=clear
24679         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24680         cat $dom > /dev/null
24681         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24682         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24683         ls $dom
24684         rm -f $dom
24685 }
24686 run_test 271a "DoM: data is cached for read after write"
24687
24688 test_271b() {
24689         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24690                 skip "Need MDS version at least 2.10.55"
24691
24692         local dom=$DIR/$tdir/dom
24693
24694         mkdir -p $DIR/$tdir
24695
24696         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24697
24698         lctl set_param -n mdc.*.stats=clear
24699         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24700         cancel_lru_locks mdc
24701         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24702         # second stat to check size is cached on client
24703         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24704         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24705         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24706         rm -f $dom
24707 }
24708 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24709
24710 test_271ba() {
24711         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24712                 skip "Need MDS version at least 2.10.55"
24713
24714         local dom=$DIR/$tdir/dom
24715
24716         mkdir -p $DIR/$tdir
24717
24718         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24719
24720         lctl set_param -n mdc.*.stats=clear
24721         lctl set_param -n osc.*.stats=clear
24722         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24723         cancel_lru_locks mdc
24724         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24725         # second stat to check size is cached on client
24726         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24727         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24728         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24729         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24730         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24731         rm -f $dom
24732 }
24733 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24734
24735
24736 get_mdc_stats() {
24737         local mdtidx=$1
24738         local param=$2
24739         local mdt=MDT$(printf %04x $mdtidx)
24740
24741         if [ -z $param ]; then
24742                 lctl get_param -n mdc.*$mdt*.stats
24743         else
24744                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24745         fi
24746 }
24747
24748 test_271c() {
24749         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24750                 skip "Need MDS version at least 2.10.55"
24751
24752         local dom=$DIR/$tdir/dom
24753
24754         mkdir -p $DIR/$tdir
24755
24756         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24757
24758         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24759         local facet=mds$((mdtidx + 1))
24760
24761         cancel_lru_locks mdc
24762         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24763         createmany -o $dom 1000
24764         lctl set_param -n mdc.*.stats=clear
24765         smalliomany -w $dom 1000 200
24766         get_mdc_stats $mdtidx
24767         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24768         # Each file has 1 open, 1 IO enqueues, total 2000
24769         # but now we have also +1 getxattr for security.capability, total 3000
24770         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24771         unlinkmany $dom 1000
24772
24773         cancel_lru_locks mdc
24774         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24775         createmany -o $dom 1000
24776         lctl set_param -n mdc.*.stats=clear
24777         smalliomany -w $dom 1000 200
24778         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24779         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24780         # for OPEN and IO lock.
24781         [ $((enq - enq_2)) -ge 1000 ] ||
24782                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24783         unlinkmany $dom 1000
24784         return 0
24785 }
24786 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24787
24788 cleanup_271def_tests() {
24789         trap 0
24790         rm -f $1
24791 }
24792
24793 test_271d() {
24794         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24795                 skip "Need MDS version at least 2.10.57"
24796
24797         local dom=$DIR/$tdir/dom
24798         local tmp=$TMP/$tfile
24799         trap "cleanup_271def_tests $tmp" EXIT
24800
24801         mkdir -p $DIR/$tdir
24802
24803         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24804
24805         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24806
24807         cancel_lru_locks mdc
24808         dd if=/dev/urandom of=$tmp bs=1000 count=1
24809         dd if=$tmp of=$dom bs=1000 count=1
24810         cancel_lru_locks mdc
24811
24812         cat /etc/hosts >> $tmp
24813         lctl set_param -n mdc.*.stats=clear
24814
24815         # append data to the same file it should update local page
24816         echo "Append to the same page"
24817         cat /etc/hosts >> $dom
24818         local num=$(get_mdc_stats $mdtidx ost_read)
24819         local ra=$(get_mdc_stats $mdtidx req_active)
24820         local rw=$(get_mdc_stats $mdtidx req_waittime)
24821
24822         [ -z $num ] || error "$num READ RPC occured"
24823         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24824         echo "... DONE"
24825
24826         # compare content
24827         cmp $tmp $dom || error "file miscompare"
24828
24829         cancel_lru_locks mdc
24830         lctl set_param -n mdc.*.stats=clear
24831
24832         echo "Open and read file"
24833         cat $dom > /dev/null
24834         local num=$(get_mdc_stats $mdtidx ost_read)
24835         local ra=$(get_mdc_stats $mdtidx req_active)
24836         local rw=$(get_mdc_stats $mdtidx req_waittime)
24837
24838         [ -z $num ] || error "$num READ RPC occured"
24839         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24840         echo "... DONE"
24841
24842         # compare content
24843         cmp $tmp $dom || error "file miscompare"
24844
24845         return 0
24846 }
24847 run_test 271d "DoM: read on open (1K file in reply buffer)"
24848
24849 test_271f() {
24850         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24851                 skip "Need MDS version at least 2.10.57"
24852
24853         local dom=$DIR/$tdir/dom
24854         local tmp=$TMP/$tfile
24855         trap "cleanup_271def_tests $tmp" EXIT
24856
24857         mkdir -p $DIR/$tdir
24858
24859         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24860
24861         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24862
24863         cancel_lru_locks mdc
24864         dd if=/dev/urandom of=$tmp bs=265000 count=1
24865         dd if=$tmp of=$dom bs=265000 count=1
24866         cancel_lru_locks mdc
24867         cat /etc/hosts >> $tmp
24868         lctl set_param -n mdc.*.stats=clear
24869
24870         echo "Append to the same page"
24871         cat /etc/hosts >> $dom
24872         local num=$(get_mdc_stats $mdtidx ost_read)
24873         local ra=$(get_mdc_stats $mdtidx req_active)
24874         local rw=$(get_mdc_stats $mdtidx req_waittime)
24875
24876         [ -z $num ] || error "$num READ RPC occured"
24877         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24878         echo "... DONE"
24879
24880         # compare content
24881         cmp $tmp $dom || error "file miscompare"
24882
24883         cancel_lru_locks mdc
24884         lctl set_param -n mdc.*.stats=clear
24885
24886         echo "Open and read file"
24887         cat $dom > /dev/null
24888         local num=$(get_mdc_stats $mdtidx ost_read)
24889         local ra=$(get_mdc_stats $mdtidx req_active)
24890         local rw=$(get_mdc_stats $mdtidx req_waittime)
24891
24892         [ -z $num ] && num=0
24893         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24894         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24895         echo "... DONE"
24896
24897         # compare content
24898         cmp $tmp $dom || error "file miscompare"
24899
24900         return 0
24901 }
24902 run_test 271f "DoM: read on open (200K file and read tail)"
24903
24904 test_271g() {
24905         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24906                 skip "Skipping due to old client or server version"
24907
24908         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24909         # to get layout
24910         $CHECKSTAT -t file $DIR1/$tfile
24911
24912         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24913         MULTIOP_PID=$!
24914         sleep 1
24915         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24916         $LCTL set_param fail_loc=0x80000314
24917         rm $DIR1/$tfile || error "Unlink fails"
24918         RC=$?
24919         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24920         [ $RC -eq 0 ] || error "Failed write to stale object"
24921 }
24922 run_test 271g "Discard DoM data vs client flush race"
24923
24924 test_272a() {
24925         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24926                 skip "Need MDS version at least 2.11.50"
24927
24928         local dom=$DIR/$tdir/dom
24929         mkdir -p $DIR/$tdir
24930
24931         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24932         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24933                 error "failed to write data into $dom"
24934         local old_md5=$(md5sum $dom)
24935
24936         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24937                 error "failed to migrate to the same DoM component"
24938
24939         local new_md5=$(md5sum $dom)
24940
24941         [ "$old_md5" == "$new_md5" ] ||
24942                 error "md5sum differ: $old_md5, $new_md5"
24943
24944         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24945                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24946 }
24947 run_test 272a "DoM migration: new layout with the same DOM component"
24948
24949 test_272b() {
24950         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24951                 skip "Need MDS version at least 2.11.50"
24952
24953         local dom=$DIR/$tdir/dom
24954         mkdir -p $DIR/$tdir
24955         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24956         stack_trap "rm -rf $DIR/$tdir"
24957
24958         local mdtidx=$($LFS getstripe -m $dom)
24959         local mdtname=MDT$(printf %04x $mdtidx)
24960         local facet=mds$((mdtidx + 1))
24961
24962         local mdtfree1=$(do_facet $facet \
24963                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24964         dd if=/dev/urandom of=$dom bs=2M count=1 ||
24965                 error "failed to write data into $dom"
24966         local old_md5=$(md5sum $dom)
24967         cancel_lru_locks mdc
24968         local mdtfree1=$(do_facet $facet \
24969                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24970
24971         $LFS migrate -c2 $dom ||
24972                 error "failed to migrate to the new composite layout"
24973         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
24974                 error "MDT stripe was not removed"
24975         ! getfattr -n trusted.dataver $dom &> /dev/null ||
24976                 error "$dir1 shouldn't have DATAVER EA"
24977
24978         cancel_lru_locks mdc
24979         local new_md5=$(md5sum $dom)
24980         [ "$old_md5" == "$new_md5" ] ||
24981                 error "$old_md5 != $new_md5"
24982
24983         # Skip free space checks with ZFS
24984         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24985                 local mdtfree2=$(do_facet $facet \
24986                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24987                 [ $mdtfree2 -gt $mdtfree1 ] ||
24988                         error "MDT space is not freed after migration"
24989         fi
24990         return 0
24991 }
24992 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24993
24994 test_272c() {
24995         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24996                 skip "Need MDS version at least 2.11.50"
24997
24998         local dom=$DIR/$tdir/$tfile
24999         mkdir -p $DIR/$tdir
25000         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25001         stack_trap "rm -rf $DIR/$tdir"
25002
25003         local mdtidx=$($LFS getstripe -m $dom)
25004         local mdtname=MDT$(printf %04x $mdtidx)
25005         local facet=mds$((mdtidx + 1))
25006
25007         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25008                 error "failed to write data into $dom"
25009         local old_md5=$(md5sum $dom)
25010         cancel_lru_locks mdc
25011         local mdtfree1=$(do_facet $facet \
25012                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25013
25014         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25015                 error "failed to migrate to the new composite layout"
25016         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25017                 error "MDT stripe was not removed"
25018
25019         cancel_lru_locks mdc
25020         local new_md5=$(md5sum $dom)
25021         [ "$old_md5" == "$new_md5" ] ||
25022                 error "$old_md5 != $new_md5"
25023
25024         # Skip free space checks with ZFS
25025         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25026                 local mdtfree2=$(do_facet $facet \
25027                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25028                 [ $mdtfree2 -gt $mdtfree1 ] ||
25029                         error "MDS space is not freed after migration"
25030         fi
25031         return 0
25032 }
25033 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25034
25035 test_272d() {
25036         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25037                 skip "Need MDS version at least 2.12.55"
25038
25039         local dom=$DIR/$tdir/$tfile
25040         mkdir -p $DIR/$tdir
25041         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25042
25043         local mdtidx=$($LFS getstripe -m $dom)
25044         local mdtname=MDT$(printf %04x $mdtidx)
25045         local facet=mds$((mdtidx + 1))
25046
25047         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25048                 error "failed to write data into $dom"
25049         local old_md5=$(md5sum $dom)
25050         cancel_lru_locks mdc
25051         local mdtfree1=$(do_facet $facet \
25052                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25053
25054         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25055                 error "failed mirroring to the new composite layout"
25056         $LFS mirror resync $dom ||
25057                 error "failed mirror resync"
25058         $LFS mirror split --mirror-id 1 -d $dom ||
25059                 error "failed mirror split"
25060
25061         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25062                 error "MDT stripe was not removed"
25063
25064         cancel_lru_locks mdc
25065         local new_md5=$(md5sum $dom)
25066         [ "$old_md5" == "$new_md5" ] ||
25067                 error "$old_md5 != $new_md5"
25068
25069         # Skip free space checks with ZFS
25070         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25071                 local mdtfree2=$(do_facet $facet \
25072                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25073                 [ $mdtfree2 -gt $mdtfree1 ] ||
25074                         error "MDS space is not freed after DOM mirror deletion"
25075         fi
25076         return 0
25077 }
25078 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25079
25080 test_272e() {
25081         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25082                 skip "Need MDS version at least 2.12.55"
25083
25084         local dom=$DIR/$tdir/$tfile
25085         mkdir -p $DIR/$tdir
25086         $LFS setstripe -c 2 $dom
25087
25088         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25089                 error "failed to write data into $dom"
25090         local old_md5=$(md5sum $dom)
25091         cancel_lru_locks
25092
25093         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25094                 error "failed mirroring to the DOM layout"
25095         $LFS mirror resync $dom ||
25096                 error "failed mirror resync"
25097         $LFS mirror split --mirror-id 1 -d $dom ||
25098                 error "failed mirror split"
25099
25100         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25101                 error "MDT stripe wasn't set"
25102
25103         cancel_lru_locks
25104         local new_md5=$(md5sum $dom)
25105         [ "$old_md5" == "$new_md5" ] ||
25106                 error "$old_md5 != $new_md5"
25107
25108         return 0
25109 }
25110 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25111
25112 test_272f() {
25113         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25114                 skip "Need MDS version at least 2.12.55"
25115
25116         local dom=$DIR/$tdir/$tfile
25117         mkdir -p $DIR/$tdir
25118         $LFS setstripe -c 2 $dom
25119
25120         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25121                 error "failed to write data into $dom"
25122         local old_md5=$(md5sum $dom)
25123         cancel_lru_locks
25124
25125         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25126                 error "failed migrating to the DOM file"
25127
25128         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25129                 error "MDT stripe wasn't set"
25130
25131         cancel_lru_locks
25132         local new_md5=$(md5sum $dom)
25133         [ "$old_md5" != "$new_md5" ] &&
25134                 error "$old_md5 != $new_md5"
25135
25136         return 0
25137 }
25138 run_test 272f "DoM migration: OST-striped file to DOM file"
25139
25140 test_273a() {
25141         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25142                 skip "Need MDS version at least 2.11.50"
25143
25144         # Layout swap cannot be done if either file has DOM component,
25145         # this will never be supported, migration should be used instead
25146
25147         local dom=$DIR/$tdir/$tfile
25148         mkdir -p $DIR/$tdir
25149
25150         $LFS setstripe -c2 ${dom}_plain
25151         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25152         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25153                 error "can swap layout with DoM component"
25154         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25155                 error "can swap layout with DoM component"
25156
25157         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25158         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25159                 error "can swap layout with DoM component"
25160         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25161                 error "can swap layout with DoM component"
25162         return 0
25163 }
25164 run_test 273a "DoM: layout swapping should fail with DOM"
25165
25166 test_273b() {
25167         mkdir -p $DIR/$tdir
25168         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25169
25170 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25171         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25172
25173         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25174 }
25175 run_test 273b "DoM: race writeback and object destroy"
25176
25177 test_273c() {
25178         mkdir -p $DIR/$tdir
25179         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25180
25181         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25182         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25183
25184         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25185 }
25186 run_test 273c "race writeback and object destroy"
25187
25188 test_275() {
25189         remote_ost_nodsh && skip "remote OST with nodsh"
25190         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25191                 skip "Need OST version >= 2.10.57"
25192
25193         local file=$DIR/$tfile
25194         local oss
25195
25196         oss=$(comma_list $(osts_nodes))
25197
25198         dd if=/dev/urandom of=$file bs=1M count=2 ||
25199                 error "failed to create a file"
25200         stack_trap "rm -f $file"
25201         cancel_lru_locks osc
25202
25203         #lock 1
25204         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25205                 error "failed to read a file"
25206
25207 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25208         $LCTL set_param fail_loc=0x8000031f
25209
25210         cancel_lru_locks osc &
25211         sleep 1
25212
25213 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25214         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25215         #IO takes another lock, but matches the PENDING one
25216         #and places it to the IO RPC
25217         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25218                 error "failed to read a file with PENDING lock"
25219 }
25220 run_test 275 "Read on a canceled duplicate lock"
25221
25222 test_276() {
25223         remote_ost_nodsh && skip "remote OST with nodsh"
25224         local pid
25225
25226         do_facet ost1 "(while true; do \
25227                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25228                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25229         pid=$!
25230
25231         for LOOP in $(seq 20); do
25232                 stop ost1
25233                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25234         done
25235         kill -9 $pid
25236         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25237                 rm $TMP/sanity_276_pid"
25238 }
25239 run_test 276 "Race between mount and obd_statfs"
25240
25241 test_277() {
25242         $LCTL set_param ldlm.namespaces.*.lru_size=0
25243         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25244         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25245                           awk '/^used_mb/ { print $2 }')
25246         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25247         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25248                 oflag=direct conv=notrunc
25249         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25250                     awk '/^used_mb/ { print $2 }')
25251         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25252 }
25253 run_test 277 "Direct IO shall drop page cache"
25254
25255 test_278() {
25256         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25257         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25258         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25259                 skip "needs the same host for mdt1 mdt2" && return
25260
25261         local pid1
25262         local pid2
25263
25264 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25265         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25266         stop mds2 &
25267         pid2=$!
25268
25269         stop mds1
25270
25271         echo "Starting MDTs"
25272         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25273         wait $pid2
25274 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25275 #will return NULL
25276         do_facet mds2 $LCTL set_param fail_loc=0
25277
25278         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25279         wait_recovery_complete mds2
25280 }
25281 run_test 278 "Race starting MDS between MDTs stop/start"
25282
25283 test_280() {
25284         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25285                 skip "Need MGS version at least 2.13.52"
25286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25287         combined_mgs_mds || skip "needs combined MGS/MDT"
25288
25289         umount_client $MOUNT
25290 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25291         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25292
25293         mount_client $MOUNT &
25294         sleep 1
25295         stop mgs || error "stop mgs failed"
25296         #for a race mgs would crash
25297         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25298         # make sure we unmount client before remounting
25299         wait
25300         umount_client $MOUNT
25301         mount_client $MOUNT || error "mount client failed"
25302 }
25303 run_test 280 "Race between MGS umount and client llog processing"
25304
25305 cleanup_test_300() {
25306         trap 0
25307         umask $SAVE_UMASK
25308 }
25309 test_striped_dir() {
25310         local mdt_index=$1
25311         local stripe_count
25312         local stripe_index
25313
25314         mkdir -p $DIR/$tdir
25315
25316         SAVE_UMASK=$(umask)
25317         trap cleanup_test_300 RETURN EXIT
25318
25319         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25320                                                 $DIR/$tdir/striped_dir ||
25321                 error "set striped dir error"
25322
25323         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25324         [ "$mode" = "755" ] || error "expect 755 got $mode"
25325
25326         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25327                 error "getdirstripe failed"
25328         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25329         if [ "$stripe_count" != "2" ]; then
25330                 error "1:stripe_count is $stripe_count, expect 2"
25331         fi
25332         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25333         if [ "$stripe_count" != "2" ]; then
25334                 error "2:stripe_count is $stripe_count, expect 2"
25335         fi
25336
25337         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25338         if [ "$stripe_index" != "$mdt_index" ]; then
25339                 error "stripe_index is $stripe_index, expect $mdt_index"
25340         fi
25341
25342         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25343                 error "nlink error after create striped dir"
25344
25345         mkdir $DIR/$tdir/striped_dir/a
25346         mkdir $DIR/$tdir/striped_dir/b
25347
25348         stat $DIR/$tdir/striped_dir/a ||
25349                 error "create dir under striped dir failed"
25350         stat $DIR/$tdir/striped_dir/b ||
25351                 error "create dir under striped dir failed"
25352
25353         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25354                 error "nlink error after mkdir"
25355
25356         rmdir $DIR/$tdir/striped_dir/a
25357         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25358                 error "nlink error after rmdir"
25359
25360         rmdir $DIR/$tdir/striped_dir/b
25361         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25362                 error "nlink error after rmdir"
25363
25364         chattr +i $DIR/$tdir/striped_dir
25365         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25366                 error "immutable flags not working under striped dir!"
25367         chattr -i $DIR/$tdir/striped_dir
25368
25369         rmdir $DIR/$tdir/striped_dir ||
25370                 error "rmdir striped dir error"
25371
25372         cleanup_test_300
25373
25374         true
25375 }
25376
25377 test_300a() {
25378         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25379                 skip "skipped for lustre < 2.7.0"
25380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25382
25383         test_striped_dir 0 || error "failed on striped dir on MDT0"
25384         test_striped_dir 1 || error "failed on striped dir on MDT0"
25385 }
25386 run_test 300a "basic striped dir sanity test"
25387
25388 test_300b() {
25389         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25390                 skip "skipped for lustre < 2.7.0"
25391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25393
25394         local i
25395         local mtime1
25396         local mtime2
25397         local mtime3
25398
25399         test_mkdir $DIR/$tdir || error "mkdir fail"
25400         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25401                 error "set striped dir error"
25402         for i in {0..9}; do
25403                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25404                 sleep 1
25405                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25406                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25407                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25408                 sleep 1
25409                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25410                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25411                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25412         done
25413         true
25414 }
25415 run_test 300b "check ctime/mtime for striped dir"
25416
25417 test_300c() {
25418         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25419                 skip "skipped for lustre < 2.7.0"
25420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25422
25423         local file_count
25424
25425         mkdir_on_mdt0 $DIR/$tdir
25426         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25427                 error "set striped dir error"
25428
25429         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25430                 error "chown striped dir failed"
25431
25432         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25433                 error "create 5k files failed"
25434
25435         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25436
25437         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25438
25439         rm -rf $DIR/$tdir
25440 }
25441 run_test 300c "chown && check ls under striped directory"
25442
25443 test_300d() {
25444         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25445                 skip "skipped for lustre < 2.7.0"
25446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25448
25449         local stripe_count
25450         local file
25451
25452         mkdir -p $DIR/$tdir
25453         $LFS setstripe -c 2 $DIR/$tdir
25454
25455         #local striped directory
25456         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25457                 error "set striped dir error"
25458         #look at the directories for debug purposes
25459         ls -l $DIR/$tdir
25460         $LFS getdirstripe $DIR/$tdir
25461         ls -l $DIR/$tdir/striped_dir
25462         $LFS getdirstripe $DIR/$tdir/striped_dir
25463         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25464                 error "create 10 files failed"
25465
25466         #remote striped directory
25467         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25468                 error "set striped dir error"
25469         #look at the directories for debug purposes
25470         ls -l $DIR/$tdir
25471         $LFS getdirstripe $DIR/$tdir
25472         ls -l $DIR/$tdir/remote_striped_dir
25473         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25474         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25475                 error "create 10 files failed"
25476
25477         for file in $(find $DIR/$tdir); do
25478                 stripe_count=$($LFS getstripe -c $file)
25479                 [ $stripe_count -eq 2 ] ||
25480                         error "wrong stripe $stripe_count for $file"
25481         done
25482
25483         rm -rf $DIR/$tdir
25484 }
25485 run_test 300d "check default stripe under striped directory"
25486
25487 test_300e() {
25488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25489                 skip "Need MDS version at least 2.7.55"
25490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25492
25493         local stripe_count
25494         local file
25495
25496         mkdir -p $DIR/$tdir
25497
25498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25499                 error "set striped dir error"
25500
25501         touch $DIR/$tdir/striped_dir/a
25502         touch $DIR/$tdir/striped_dir/b
25503         touch $DIR/$tdir/striped_dir/c
25504
25505         mkdir $DIR/$tdir/striped_dir/dir_a
25506         mkdir $DIR/$tdir/striped_dir/dir_b
25507         mkdir $DIR/$tdir/striped_dir/dir_c
25508
25509         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25510                 error "set striped adir under striped dir error"
25511
25512         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25513                 error "set striped bdir under striped dir error"
25514
25515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25516                 error "set striped cdir under striped dir error"
25517
25518         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25519                 error "rename dir under striped dir fails"
25520
25521         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25522                 error "rename dir under different stripes fails"
25523
25524         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25525                 error "rename file under striped dir should succeed"
25526
25527         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25528                 error "rename dir under striped dir should succeed"
25529
25530         rm -rf $DIR/$tdir
25531 }
25532 run_test 300e "check rename under striped directory"
25533
25534 test_300f() {
25535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25537         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25538                 skip "Need MDS version at least 2.7.55"
25539
25540         local stripe_count
25541         local file
25542
25543         rm -rf $DIR/$tdir
25544         mkdir -p $DIR/$tdir
25545
25546         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25547                 error "set striped dir error"
25548
25549         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25550                 error "set striped dir error"
25551
25552         touch $DIR/$tdir/striped_dir/a
25553         mkdir $DIR/$tdir/striped_dir/dir_a
25554         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25555                 error "create striped dir under striped dir fails"
25556
25557         touch $DIR/$tdir/striped_dir1/b
25558         mkdir $DIR/$tdir/striped_dir1/dir_b
25559         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25560                 error "create striped dir under striped dir fails"
25561
25562         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25563                 error "rename dir under different striped dir should fail"
25564
25565         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25566                 error "rename striped dir under diff striped dir should fail"
25567
25568         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25569                 error "rename file under diff striped dirs fails"
25570
25571         rm -rf $DIR/$tdir
25572 }
25573 run_test 300f "check rename cross striped directory"
25574
25575 test_300_check_default_striped_dir()
25576 {
25577         local dirname=$1
25578         local default_count=$2
25579         local default_index=$3
25580         local stripe_count
25581         local stripe_index
25582         local dir_stripe_index
25583         local dir
25584
25585         echo "checking $dirname $default_count $default_index"
25586         $LFS setdirstripe -D -c $default_count -i $default_index \
25587                                 -H all_char $DIR/$tdir/$dirname ||
25588                 error "set default stripe on striped dir error"
25589         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25590         [ $stripe_count -eq $default_count ] ||
25591                 error "expect $default_count get $stripe_count for $dirname"
25592
25593         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25594         [ $stripe_index -eq $default_index ] ||
25595                 error "expect $default_index get $stripe_index for $dirname"
25596
25597         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25598                                                 error "create dirs failed"
25599
25600         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25601         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25602         for dir in $(find $DIR/$tdir/$dirname/*); do
25603                 stripe_count=$($LFS getdirstripe -c $dir)
25604                 (( $stripe_count == $default_count )) ||
25605                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25606                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25607                 error "stripe count $default_count != $stripe_count for $dir"
25608
25609                 stripe_index=$($LFS getdirstripe -i $dir)
25610                 [ $default_index -eq -1 ] ||
25611                         [ $stripe_index -eq $default_index ] ||
25612                         error "$stripe_index != $default_index for $dir"
25613
25614                 #check default stripe
25615                 stripe_count=$($LFS getdirstripe -D -c $dir)
25616                 [ $stripe_count -eq $default_count ] ||
25617                 error "default count $default_count != $stripe_count for $dir"
25618
25619                 stripe_index=$($LFS getdirstripe -D -i $dir)
25620                 [ $stripe_index -eq $default_index ] ||
25621                 error "default index $default_index != $stripe_index for $dir"
25622         done
25623         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25624 }
25625
25626 test_300g() {
25627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25628         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25629                 skip "Need MDS version at least 2.7.55"
25630
25631         local dir
25632         local stripe_count
25633         local stripe_index
25634
25635         mkdir_on_mdt0 $DIR/$tdir
25636         mkdir $DIR/$tdir/normal_dir
25637
25638         #Checking when client cache stripe index
25639         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25640         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25641                 error "create striped_dir failed"
25642
25643         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25644                 error "create dir0 fails"
25645         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25646         [ $stripe_index -eq 0 ] ||
25647                 error "dir0 expect index 0 got $stripe_index"
25648
25649         mkdir $DIR/$tdir/striped_dir/dir1 ||
25650                 error "create dir1 fails"
25651         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25652         [ $stripe_index -eq 1 ] ||
25653                 error "dir1 expect index 1 got $stripe_index"
25654
25655         #check default stripe count/stripe index
25656         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25657         test_300_check_default_striped_dir normal_dir 1 0
25658         test_300_check_default_striped_dir normal_dir -1 1
25659         test_300_check_default_striped_dir normal_dir 2 -1
25660
25661         #delete default stripe information
25662         echo "delete default stripeEA"
25663         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25664                 error "set default stripe on striped dir error"
25665
25666         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25667         for dir in $(find $DIR/$tdir/normal_dir/*); do
25668                 stripe_count=$($LFS getdirstripe -c $dir)
25669                 [ $stripe_count -eq 0 ] ||
25670                         error "expect 1 get $stripe_count for $dir"
25671         done
25672 }
25673 run_test 300g "check default striped directory for normal directory"
25674
25675 test_300h() {
25676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25678                 skip "Need MDS version at least 2.7.55"
25679
25680         local dir
25681         local stripe_count
25682
25683         mkdir $DIR/$tdir
25684         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25685                 error "set striped dir error"
25686
25687         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25688         test_300_check_default_striped_dir striped_dir 1 0
25689         test_300_check_default_striped_dir striped_dir -1 1
25690         test_300_check_default_striped_dir striped_dir 2 -1
25691
25692         #delete default stripe information
25693         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25694                 error "set default stripe on striped dir error"
25695
25696         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25697         for dir in $(find $DIR/$tdir/striped_dir/*); do
25698                 stripe_count=$($LFS getdirstripe -c $dir)
25699                 [ $stripe_count -eq 0 ] ||
25700                         error "expect 1 get $stripe_count for $dir"
25701         done
25702 }
25703 run_test 300h "check default striped directory for striped directory"
25704
25705 test_300i() {
25706         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25707         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25708         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25709                 skip "Need MDS version at least 2.7.55"
25710
25711         local stripe_count
25712         local file
25713
25714         mkdir $DIR/$tdir
25715
25716         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25717                 error "set striped dir error"
25718
25719         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25720                 error "create files under striped dir failed"
25721
25722         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25723                 error "set striped hashdir error"
25724
25725         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25726                 error "create dir0 under hash dir failed"
25727         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25728                 error "create dir1 under hash dir failed"
25729         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25730                 error "create dir2 under hash dir failed"
25731
25732         # unfortunately, we need to umount to clear dir layout cache for now
25733         # once we fully implement dir layout, we can drop this
25734         umount_client $MOUNT || error "umount failed"
25735         mount_client $MOUNT || error "mount failed"
25736
25737         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25738         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25739         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25740
25741         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25742                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25743                         error "create crush2 dir $tdir/hashdir/d3 failed"
25744                 $LFS find -H crush2 $DIR/$tdir/hashdir
25745                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25746                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25747
25748                 # mkdir with an invalid hash type (hash=fail_val) from client
25749                 # should be replaced on MDS with a valid (default) hash type
25750                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25751                 $LCTL set_param fail_loc=0x1901 fail_val=99
25752                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25753
25754                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25755                 local expect=$(do_facet mds1 \
25756                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25757                 [[ $hash == $expect ]] ||
25758                         error "d99 hash '$hash' != expected hash '$expect'"
25759         fi
25760
25761         #set the stripe to be unknown hash type on read
25762         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25763         $LCTL set_param fail_loc=0x1901 fail_val=99
25764         for ((i = 0; i < 10; i++)); do
25765                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25766                         error "stat f-$i failed"
25767                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25768         done
25769
25770         touch $DIR/$tdir/striped_dir/f0 &&
25771                 error "create under striped dir with unknown hash should fail"
25772
25773         $LCTL set_param fail_loc=0
25774
25775         umount_client $MOUNT || error "umount failed"
25776         mount_client $MOUNT || error "mount failed"
25777
25778         return 0
25779 }
25780 run_test 300i "client handle unknown hash type striped directory"
25781
25782 test_300j() {
25783         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25785         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25786                 skip "Need MDS version at least 2.7.55"
25787
25788         local stripe_count
25789         local file
25790
25791         mkdir $DIR/$tdir
25792
25793         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25794         $LCTL set_param fail_loc=0x1702
25795         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25796                 error "set striped dir error"
25797
25798         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25799                 error "create files under striped dir failed"
25800
25801         $LCTL set_param fail_loc=0
25802
25803         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25804
25805         return 0
25806 }
25807 run_test 300j "test large update record"
25808
25809 test_300k() {
25810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25812         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25813                 skip "Need MDS version at least 2.7.55"
25814
25815         # this test needs a huge transaction
25816         local kb
25817         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25818              osd*.$FSNAME-MDT0000.kbytestotal")
25819         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25820
25821         local stripe_count
25822         local file
25823
25824         mkdir $DIR/$tdir
25825
25826         #define OBD_FAIL_LARGE_STRIPE   0x1703
25827         $LCTL set_param fail_loc=0x1703
25828         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25829                 error "set striped dir error"
25830         $LCTL set_param fail_loc=0
25831
25832         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25833                 error "getstripeddir fails"
25834         rm -rf $DIR/$tdir/striped_dir ||
25835                 error "unlink striped dir fails"
25836
25837         return 0
25838 }
25839 run_test 300k "test large striped directory"
25840
25841 test_300l() {
25842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25843         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25844         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25845                 skip "Need MDS version at least 2.7.55"
25846
25847         local stripe_index
25848
25849         test_mkdir -p $DIR/$tdir/striped_dir
25850         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25851                         error "chown $RUNAS_ID failed"
25852         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25853                 error "set default striped dir failed"
25854
25855         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25856         $LCTL set_param fail_loc=0x80000158
25857         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25858
25859         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25860         [ $stripe_index -eq 1 ] ||
25861                 error "expect 1 get $stripe_index for $dir"
25862 }
25863 run_test 300l "non-root user to create dir under striped dir with stale layout"
25864
25865 test_300m() {
25866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25867         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25868         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25869                 skip "Need MDS version at least 2.7.55"
25870
25871         mkdir -p $DIR/$tdir/striped_dir
25872         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25873                 error "set default stripes dir error"
25874
25875         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25876
25877         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25878         [ $stripe_count -eq 0 ] ||
25879                         error "expect 0 get $stripe_count for a"
25880
25881         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25882                 error "set default stripes dir error"
25883
25884         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25885
25886         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25887         [ $stripe_count -eq 0 ] ||
25888                         error "expect 0 get $stripe_count for b"
25889
25890         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25891                 error "set default stripes dir error"
25892
25893         mkdir $DIR/$tdir/striped_dir/c &&
25894                 error "default stripe_index is invalid, mkdir c should fails"
25895
25896         rm -rf $DIR/$tdir || error "rmdir fails"
25897 }
25898 run_test 300m "setstriped directory on single MDT FS"
25899
25900 cleanup_300n() {
25901         local list=$(comma_list $(mdts_nodes))
25902
25903         trap 0
25904         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25905 }
25906
25907 test_300n() {
25908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25909         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25910         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25911                 skip "Need MDS version at least 2.7.55"
25912         remote_mds_nodsh && skip "remote MDS with nodsh"
25913
25914         local stripe_index
25915         local list=$(comma_list $(mdts_nodes))
25916
25917         trap cleanup_300n RETURN EXIT
25918         mkdir -p $DIR/$tdir
25919         chmod 777 $DIR/$tdir
25920         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25921                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25922                 error "create striped dir succeeds with gid=0"
25923
25924         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25925         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25926                 error "create striped dir fails with gid=-1"
25927
25928         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25929         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25930                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25931                 error "set default striped dir succeeds with gid=0"
25932
25933
25934         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25935         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25936                 error "set default striped dir fails with gid=-1"
25937
25938
25939         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25940         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25941                                         error "create test_dir fails"
25942         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25943                                         error "create test_dir1 fails"
25944         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25945                                         error "create test_dir2 fails"
25946         cleanup_300n
25947 }
25948 run_test 300n "non-root user to create dir under striped dir with default EA"
25949
25950 test_300o() {
25951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25953         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25954                 skip "Need MDS version at least 2.7.55"
25955
25956         local numfree1
25957         local numfree2
25958
25959         mkdir -p $DIR/$tdir
25960
25961         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
25962         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
25963         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
25964                 skip "not enough free inodes $numfree1 $numfree2"
25965         fi
25966
25967         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
25968         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
25969         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
25970                 skip "not enough free space $numfree1 $numfree2"
25971         fi
25972
25973         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25974                 error "setdirstripe fails"
25975
25976         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25977                 error "create dirs fails"
25978
25979         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25980         ls $DIR/$tdir/striped_dir > /dev/null ||
25981                 error "ls striped dir fails"
25982         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25983                 error "unlink big striped dir fails"
25984 }
25985 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25986
25987 test_300p() {
25988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25989         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25990         remote_mds_nodsh && skip "remote MDS with nodsh"
25991
25992         mkdir_on_mdt0 $DIR/$tdir
25993
25994         #define OBD_FAIL_OUT_ENOSPC     0x1704
25995         do_facet mds2 lctl set_param fail_loc=0x80001704
25996         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25997                  && error "create striped directory should fail"
25998
25999         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26000
26001         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26002         true
26003 }
26004 run_test 300p "create striped directory without space"
26005
26006 test_300q() {
26007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26008         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26009
26010         local fd=$(free_fd)
26011         local cmd="exec $fd<$tdir"
26012         cd $DIR
26013         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26014         eval $cmd
26015         cmd="exec $fd<&-"
26016         trap "eval $cmd" EXIT
26017         cd $tdir || error "cd $tdir fails"
26018         rmdir  ../$tdir || error "rmdir $tdir fails"
26019         mkdir local_dir && error "create dir succeeds"
26020         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26021         eval $cmd
26022         return 0
26023 }
26024 run_test 300q "create remote directory under orphan directory"
26025
26026 test_300r() {
26027         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26028                 skip "Need MDS version at least 2.7.55" && return
26029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26030
26031         mkdir $DIR/$tdir
26032
26033         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26034                 error "set striped dir error"
26035
26036         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26037                 error "getstripeddir fails"
26038
26039         local stripe_count
26040         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26041                       awk '/lmv_stripe_count:/ { print $2 }')
26042
26043         [ $MDSCOUNT -ne $stripe_count ] &&
26044                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26045
26046         rm -rf $DIR/$tdir/striped_dir ||
26047                 error "unlink striped dir fails"
26048 }
26049 run_test 300r "test -1 striped directory"
26050
26051 test_300s_helper() {
26052         local count=$1
26053
26054         local stripe_dir=$DIR/$tdir/striped_dir.$count
26055
26056         $LFS mkdir -c $count $stripe_dir ||
26057                 error "lfs mkdir -c error"
26058
26059         $LFS getdirstripe $stripe_dir ||
26060                 error "lfs getdirstripe fails"
26061
26062         local stripe_count
26063         stripe_count=$($LFS getdirstripe $stripe_dir |
26064                       awk '/lmv_stripe_count:/ { print $2 }')
26065
26066         [ $count -ne $stripe_count ] &&
26067                 error_noexit "bad stripe count $stripe_count expected $count"
26068
26069         local dupe_stripes
26070         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26071                 awk '/0x/ {count[$1] += 1}; END {
26072                         for (idx in count) {
26073                                 if (count[idx]>1) {
26074                                         print "index " idx " count " count[idx]
26075                                 }
26076                         }
26077                 }')
26078
26079         if [[ -n "$dupe_stripes" ]] ; then
26080                 lfs getdirstripe $stripe_dir
26081                 error_noexit "Dupe MDT above: $dupe_stripes "
26082         fi
26083
26084         rm -rf $stripe_dir ||
26085                 error_noexit "unlink $stripe_dir fails"
26086 }
26087
26088 test_300s() {
26089         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26090                 skip "Need MDS version at least 2.7.55" && return
26091         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26092
26093         mkdir $DIR/$tdir
26094         for count in $(seq 2 $MDSCOUNT); do
26095                 test_300s_helper $count
26096         done
26097 }
26098 run_test 300s "test lfs mkdir -c without -i"
26099
26100 test_300t() {
26101         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26102                 skip "need MDS 2.14.55 or later"
26103         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26104
26105         local testdir="$DIR/$tdir/striped_dir"
26106         local dir1=$testdir/dir1
26107         local dir2=$testdir/dir2
26108
26109         mkdir -p $testdir
26110
26111         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26112                 error "failed to set default stripe count for $testdir"
26113
26114         mkdir $dir1
26115         local stripe_count=$($LFS getdirstripe -c $dir1)
26116
26117         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26118
26119         local max_count=$((MDSCOUNT - 1))
26120         local mdts=$(comma_list $(mdts_nodes))
26121
26122         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26123         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26124
26125         mkdir $dir2
26126         stripe_count=$($LFS getdirstripe -c $dir2)
26127
26128         (( $stripe_count == $max_count )) || error "wrong stripe count"
26129 }
26130 run_test 300t "test max_mdt_stripecount"
26131
26132 prepare_remote_file() {
26133         mkdir $DIR/$tdir/src_dir ||
26134                 error "create remote source failed"
26135
26136         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26137                  error "cp to remote source failed"
26138         touch $DIR/$tdir/src_dir/a
26139
26140         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26141                 error "create remote target dir failed"
26142
26143         touch $DIR/$tdir/tgt_dir/b
26144
26145         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26146                 error "rename dir cross MDT failed!"
26147
26148         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26149                 error "src_child still exists after rename"
26150
26151         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26152                 error "missing file(a) after rename"
26153
26154         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26155                 error "diff after rename"
26156 }
26157
26158 test_310a() {
26159         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26161
26162         local remote_file=$DIR/$tdir/tgt_dir/b
26163
26164         mkdir -p $DIR/$tdir
26165
26166         prepare_remote_file || error "prepare remote file failed"
26167
26168         #open-unlink file
26169         $OPENUNLINK $remote_file $remote_file ||
26170                 error "openunlink $remote_file failed"
26171         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26172 }
26173 run_test 310a "open unlink remote file"
26174
26175 test_310b() {
26176         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26178
26179         local remote_file=$DIR/$tdir/tgt_dir/b
26180
26181         mkdir -p $DIR/$tdir
26182
26183         prepare_remote_file || error "prepare remote file failed"
26184
26185         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26186         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26187         $CHECKSTAT -t file $remote_file || error "check file failed"
26188 }
26189 run_test 310b "unlink remote file with multiple links while open"
26190
26191 test_310c() {
26192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26193         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26194
26195         local remote_file=$DIR/$tdir/tgt_dir/b
26196
26197         mkdir -p $DIR/$tdir
26198
26199         prepare_remote_file || error "prepare remote file failed"
26200
26201         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26202         multiop_bg_pause $remote_file O_uc ||
26203                         error "mulitop failed for remote file"
26204         MULTIPID=$!
26205         $MULTIOP $DIR/$tfile Ouc
26206         kill -USR1 $MULTIPID
26207         wait $MULTIPID
26208 }
26209 run_test 310c "open-unlink remote file with multiple links"
26210
26211 #LU-4825
26212 test_311() {
26213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26214         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26215         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26216                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26217         remote_mds_nodsh && skip "remote MDS with nodsh"
26218
26219         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26220         local mdts=$(comma_list $(mdts_nodes))
26221
26222         mkdir -p $DIR/$tdir
26223         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26224         createmany -o $DIR/$tdir/$tfile. 1000
26225
26226         # statfs data is not real time, let's just calculate it
26227         old_iused=$((old_iused + 1000))
26228
26229         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26230                         osp.*OST0000*MDT0000.create_count")
26231         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26232                                 osp.*OST0000*MDT0000.max_create_count")
26233         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26234
26235         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26236         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26237         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26238
26239         unlinkmany $DIR/$tdir/$tfile. 1000
26240
26241         do_nodes $mdts "$LCTL set_param -n \
26242                         osp.*OST0000*.max_create_count=$max_count"
26243         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26244                 do_nodes $mdts "$LCTL set_param -n \
26245                                 osp.*OST0000*.create_count=$count"
26246         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26247                         grep "=0" && error "create_count is zero"
26248
26249         local new_iused
26250         for i in $(seq 120); do
26251                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26252                 # system may be too busy to destroy all objs in time, use
26253                 # a somewhat small value to not fail autotest
26254                 [ $((old_iused - new_iused)) -gt 400 ] && break
26255                 sleep 1
26256         done
26257
26258         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26259         [ $((old_iused - new_iused)) -gt 400 ] ||
26260                 error "objs not destroyed after unlink"
26261 }
26262 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26263
26264 zfs_get_objid()
26265 {
26266         local ost=$1
26267         local tf=$2
26268         local fid=($($LFS getstripe $tf | grep 0x))
26269         local seq=${fid[3]#0x}
26270         local objid=${fid[1]}
26271
26272         local vdevdir=$(dirname $(facet_vdevice $ost))
26273         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26274         local zfs_zapid=$(do_facet $ost $cmd |
26275                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26276                           awk '/Object/{getline; print $1}')
26277         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26278                           awk "/$objid = /"'{printf $3}')
26279
26280         echo $zfs_objid
26281 }
26282
26283 zfs_object_blksz() {
26284         local ost=$1
26285         local objid=$2
26286
26287         local vdevdir=$(dirname $(facet_vdevice $ost))
26288         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26289         local blksz=$(do_facet $ost $cmd $objid |
26290                       awk '/dblk/{getline; printf $4}')
26291
26292         case "${blksz: -1}" in
26293                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26294                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26295                 *) ;;
26296         esac
26297
26298         echo $blksz
26299 }
26300
26301 test_312() { # LU-4856
26302         remote_ost_nodsh && skip "remote OST with nodsh"
26303         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26304
26305         local max_blksz=$(do_facet ost1 \
26306                           $ZFS get -p recordsize $(facet_device ost1) |
26307                           awk '!/VALUE/{print $3}')
26308         local tf=$DIR/$tfile
26309
26310         $LFS setstripe -c1 $tf
26311         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26312
26313         # Get ZFS object id
26314         local zfs_objid=$(zfs_get_objid $facet $tf)
26315         # block size change by sequential overwrite
26316         local bs
26317
26318         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26319                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26320
26321                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26322                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26323         done
26324         rm -f $tf
26325
26326         $LFS setstripe -c1 $tf
26327         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26328
26329         # block size change by sequential append write
26330         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26331         zfs_objid=$(zfs_get_objid $facet $tf)
26332         local count
26333
26334         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26335                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26336                         oflag=sync conv=notrunc
26337
26338                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26339                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26340                         error "blksz error, actual $blksz, " \
26341                                 "expected: 2 * $count * $PAGE_SIZE"
26342         done
26343         rm -f $tf
26344
26345         # random write
26346         $LFS setstripe -c1 $tf
26347         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26348         zfs_objid=$(zfs_get_objid $facet $tf)
26349
26350         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26351         blksz=$(zfs_object_blksz $facet $zfs_objid)
26352         (( blksz == PAGE_SIZE )) ||
26353                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26354
26355         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26356         blksz=$(zfs_object_blksz $facet $zfs_objid)
26357         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26358
26359         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26360         blksz=$(zfs_object_blksz $facet $zfs_objid)
26361         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26362 }
26363 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26364
26365 test_313() {
26366         remote_ost_nodsh && skip "remote OST with nodsh"
26367
26368         local file=$DIR/$tfile
26369
26370         rm -f $file
26371         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26372
26373         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26374         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26375         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26376                 error "write should failed"
26377         do_facet ost1 "$LCTL set_param fail_loc=0"
26378         rm -f $file
26379 }
26380 run_test 313 "io should fail after last_rcvd update fail"
26381
26382 test_314() {
26383         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26384
26385         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26386         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26387         rm -f $DIR/$tfile
26388         wait_delete_completed
26389         do_facet ost1 "$LCTL set_param fail_loc=0"
26390 }
26391 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26392
26393 test_315() { # LU-618
26394         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26395
26396         local file=$DIR/$tfile
26397         rm -f $file
26398
26399         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26400                 error "multiop file write failed"
26401         $MULTIOP $file oO_RDONLY:r4063232_c &
26402         PID=$!
26403
26404         sleep 2
26405
26406         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26407         kill -USR1 $PID
26408
26409         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26410         rm -f $file
26411 }
26412 run_test 315 "read should be accounted"
26413
26414 test_316() {
26415         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26416         large_xattr_enabled || skip "ea_inode feature disabled"
26417
26418         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26419         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26420         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26421         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26422
26423         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26424 }
26425 run_test 316 "lfs migrate of file with large_xattr enabled"
26426
26427 test_317() {
26428         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26429                 skip "Need MDS version at least 2.11.53"
26430         if [ "$ost1_FSTYPE" == "zfs" ]; then
26431                 skip "LU-10370: no implementation for ZFS"
26432         fi
26433
26434         local trunc_sz
26435         local grant_blk_size
26436
26437         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26438                         awk '/grant_block_size:/ { print $2; exit; }')
26439         #
26440         # Create File of size 5M. Truncate it to below size's and verify
26441         # blocks count.
26442         #
26443         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26444                 error "Create file $DIR/$tfile failed"
26445         stack_trap "rm -f $DIR/$tfile" EXIT
26446
26447         for trunc_sz in 2097152 4097 4000 509 0; do
26448                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26449                         error "truncate $tfile to $trunc_sz failed"
26450                 local sz=$(stat --format=%s $DIR/$tfile)
26451                 local blk=$(stat --format=%b $DIR/$tfile)
26452                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26453                                      grant_blk_size) * 8))
26454
26455                 if [[ $blk -ne $trunc_blk ]]; then
26456                         $(which stat) $DIR/$tfile
26457                         error "Expected Block $trunc_blk got $blk for $tfile"
26458                 fi
26459
26460                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26461                         error "Expected Size $trunc_sz got $sz for $tfile"
26462         done
26463
26464         #
26465         # sparse file test
26466         # Create file with a hole and write actual 65536 bytes which aligned
26467         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26468         #
26469         local bs=65536
26470         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26471                 error "Create file : $DIR/$tfile"
26472
26473         #
26474         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26475         # blocks. The block count must drop to 8.
26476         #
26477         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26478                 ((bs - grant_blk_size) + 1)))
26479         $TRUNCATE $DIR/$tfile $trunc_sz ||
26480                 error "truncate $tfile to $trunc_sz failed"
26481
26482         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26483         sz=$(stat --format=%s $DIR/$tfile)
26484         blk=$(stat --format=%b $DIR/$tfile)
26485
26486         if [[ $blk -ne $trunc_bsz ]]; then
26487                 $(which stat) $DIR/$tfile
26488                 error "Expected Block $trunc_bsz got $blk for $tfile"
26489         fi
26490
26491         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26492                 error "Expected Size $trunc_sz got $sz for $tfile"
26493 }
26494 run_test 317 "Verify blocks get correctly update after truncate"
26495
26496 test_318() {
26497         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26498         local old_max_active=$($LCTL get_param -n \
26499                             ${llite_name}.max_read_ahead_async_active \
26500                             2>/dev/null)
26501
26502         $LCTL set_param llite.*.max_read_ahead_async_active=256
26503         local max_active=$($LCTL get_param -n \
26504                            ${llite_name}.max_read_ahead_async_active \
26505                            2>/dev/null)
26506         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26507
26508         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26509                 error "set max_read_ahead_async_active should succeed"
26510
26511         $LCTL set_param llite.*.max_read_ahead_async_active=512
26512         max_active=$($LCTL get_param -n \
26513                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26514         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26515
26516         # restore @max_active
26517         [ $old_max_active -ne 0 ] && $LCTL set_param \
26518                 llite.*.max_read_ahead_async_active=$old_max_active
26519
26520         local old_threshold=$($LCTL get_param -n \
26521                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26522         local max_per_file_mb=$($LCTL get_param -n \
26523                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26524
26525         local invalid=$(($max_per_file_mb + 1))
26526         $LCTL set_param \
26527                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26528                         && error "set $invalid should fail"
26529
26530         local valid=$(($invalid - 1))
26531         $LCTL set_param \
26532                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26533                         error "set $valid should succeed"
26534         local threshold=$($LCTL get_param -n \
26535                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26536         [ $threshold -eq $valid ] || error \
26537                 "expect threshold $valid got $threshold"
26538         $LCTL set_param \
26539                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26540 }
26541 run_test 318 "Verify async readahead tunables"
26542
26543 test_319() {
26544         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26545
26546         local before=$(date +%s)
26547         local evict
26548         local mdir=$DIR/$tdir
26549         local file=$mdir/xxx
26550
26551         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26552         touch $file
26553
26554 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26555         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26556         $LFS migrate -m1 $mdir &
26557
26558         sleep 1
26559         dd if=$file of=/dev/null
26560         wait
26561         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26562           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26563
26564         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26565 }
26566 run_test 319 "lost lease lock on migrate error"
26567
26568 test_360() {
26569         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26570                 skip "Need OST version at least 2.15.58.96"
26571         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26572
26573         check_set_fallocate_or_skip
26574         do_facet ost1 "$LCTL set_param osd-ldiskfs.delayed_unlink_mb=1MiB"
26575
26576         mkdir $DIR/$tdir/
26577         do_facet ost1 $LCTL set_param debug=+inode
26578         do_facet ost1 $LCTL clear
26579         local files=100
26580
26581         for ((i = 0; i < $files; i++)); do
26582                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26583                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26584         done
26585         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26586
26587         for ((i = 0; i < $files; i++)); do
26588                 unlink $DIR/$tdir/$tfile.$i ||
26589                         error "unlink $DIR/$tdir/$tfile.$i failed"
26590         done
26591
26592         local count=0
26593         local loop
26594
26595         for (( loop = 0; loop < 30 && count < min; loop++)); do
26596                 sleep 1
26597                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26598                 echo "Count[$loop]: $count"
26599         done
26600         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26601 }
26602 run_test 360 "ldiskfs unlink in a separate thread"
26603
26604 test_398a() { # LU-4198
26605         local ost1_imp=$(get_osc_import_name client ost1)
26606         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26607                          cut -d'.' -f2)
26608
26609         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26610         stack_trap "rm -f $DIR/$tfile"
26611         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26612
26613         # request a new lock on client
26614         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26615
26616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26617         local lock_count=$($LCTL get_param -n \
26618                            ldlm.namespaces.$imp_name.lru_size)
26619         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26620
26621         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26622
26623         # no lock cached, should use lockless DIO and not enqueue new lock
26624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26625         lock_count=$($LCTL get_param -n \
26626                      ldlm.namespaces.$imp_name.lru_size)
26627         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26628
26629         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26630
26631         # no lock cached, should use locked DIO append
26632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26633                 conv=notrunc || error "DIO append failed"
26634         lock_count=$($LCTL get_param -n \
26635                      ldlm.namespaces.$imp_name.lru_size)
26636         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26637 }
26638 run_test 398a "direct IO should cancel lock otherwise lockless"
26639
26640 test_398b() { # LU-4198
26641         local before=$(date +%s)
26642         local njobs=4
26643         local size=48
26644
26645         which fio || skip_env "no fio installed"
26646         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26648
26649         # Single page, multiple pages, stripe size, 4*stripe size
26650         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26651                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26652                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26653                         --numjobs=$njobs --fallocate=none \
26654                         --iodepth=16 --allow_file_create=0 \
26655                         --size=$((size/njobs))M \
26656                         --filename=$DIR/$tfile &
26657                 bg_pid=$!
26658
26659                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26660                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26661                         --numjobs=$njobs --fallocate=none \
26662                         --iodepth=16 --allow_file_create=0 \
26663                         --size=$((size/njobs))M \
26664                         --filename=$DIR/$tfile || true
26665                 wait $bg_pid
26666         done
26667
26668         evict=$(do_facet client $LCTL get_param \
26669                 osc.$FSNAME-OST*-osc-*/state |
26670             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26671
26672         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26673                 (do_facet client $LCTL get_param \
26674                         osc.$FSNAME-OST*-osc-*/state;
26675                     error "eviction happened: $evict before:$before")
26676
26677         rm -f $DIR/$tfile
26678 }
26679 run_test 398b "DIO and buffer IO race"
26680
26681 test_398c() { # LU-4198
26682         local ost1_imp=$(get_osc_import_name client ost1)
26683         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26684                          cut -d'.' -f2)
26685
26686         which fio || skip_env "no fio installed"
26687
26688         saved_debug=$($LCTL get_param -n debug)
26689         $LCTL set_param debug=0
26690
26691         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26692         ((size /= 1024)) # by megabytes
26693         ((size /= 2)) # write half of the OST at most
26694         [ $size -gt 40 ] && size=40 #reduce test time anyway
26695
26696         $LFS setstripe -c 1 $DIR/$tfile
26697
26698         # it seems like ldiskfs reserves more space than necessary if the
26699         # writing blocks are not mapped, so it extends the file firstly
26700         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26701         cancel_lru_locks osc
26702
26703         # clear and verify rpc_stats later
26704         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26705
26706         local njobs=4
26707         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26708         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26709                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26710                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26711                 --filename=$DIR/$tfile
26712         [ $? -eq 0 ] || error "fio write error"
26713
26714         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26715                 error "Locks were requested while doing AIO"
26716
26717         # get the percentage of 1-page I/O
26718         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26719                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26720                 awk '{print $7}')
26721         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26722
26723         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26724         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26725                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26726                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26727                 --filename=$DIR/$tfile
26728         [ $? -eq 0 ] || error "fio mixed read write error"
26729
26730         echo "AIO with large block size ${size}M"
26731         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26732                 --numjobs=1 --fallocate=none --ioengine=libaio \
26733                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26734                 --filename=$DIR/$tfile
26735         [ $? -eq 0 ] || error "fio large block size failed"
26736
26737         rm -f $DIR/$tfile
26738         $LCTL set_param debug="$saved_debug"
26739 }
26740 run_test 398c "run fio to test AIO"
26741
26742 test_398d() { #  LU-13846
26743         which aiocp || skip_env "no aiocp installed"
26744         local aio_file=$DIR/$tfile.aio
26745
26746         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26747
26748         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26749         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26750         stack_trap "rm -f $DIR/$tfile $aio_file"
26751
26752         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26753
26754         # test memory unaligned aio
26755         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26756                 error "unaligned aio failed"
26757         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26758
26759         rm -f $DIR/$tfile $aio_file
26760 }
26761 run_test 398d "run aiocp to verify block size > stripe size"
26762
26763 test_398e() {
26764         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26765         touch $DIR/$tfile.new
26766         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26767 }
26768 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26769
26770 test_398f() { #  LU-14687
26771         which aiocp || skip_env "no aiocp installed"
26772         local aio_file=$DIR/$tfile.aio
26773
26774         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26775
26776         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26777         stack_trap "rm -f $DIR/$tfile $aio_file"
26778
26779         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26780         $LCTL set_param fail_loc=0x1418
26781         # make sure we don't crash and fail properly
26782         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26783                 error "aio with page allocation failure succeeded"
26784         $LCTL set_param fail_loc=0
26785         diff $DIR/$tfile $aio_file
26786         [[ $? != 0 ]] || error "no diff after failed aiocp"
26787 }
26788 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26789
26790 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26791 # stripe and i/o size must be > stripe size
26792 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26793 # single RPC in flight.  This test shows async DIO submission is working by
26794 # showing multiple RPCs in flight.
26795 test_398g() { #  LU-13798
26796         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26797
26798         # We need to do some i/o first to acquire enough grant to put our RPCs
26799         # in flight; otherwise a new connection may not have enough grant
26800         # available
26801         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26802                 error "parallel dio failed"
26803         stack_trap "rm -f $DIR/$tfile"
26804
26805         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26806         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26807         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26808         stack_trap "$LCTL set_param -n $pages_per_rpc"
26809
26810         # Recreate file so it's empty
26811         rm -f $DIR/$tfile
26812         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26813         #Pause rpc completion to guarantee we see multiple rpcs in flight
26814         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26815         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26816         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26817
26818         # Clear rpc stats
26819         $LCTL set_param osc.*.rpc_stats=c
26820
26821         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26822                 error "parallel dio failed"
26823         stack_trap "rm -f $DIR/$tfile"
26824
26825         $LCTL get_param osc.*-OST0000-*.rpc_stats
26826         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26827                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26828                 grep "8:" | awk '{print $8}')
26829         # We look at the "8 rpcs in flight" field, and verify A) it is present
26830         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26831         # as expected for an 8M DIO to a file with 1M stripes.
26832         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26833
26834         # Verify turning off parallel dio works as expected
26835         # Clear rpc stats
26836         $LCTL set_param osc.*.rpc_stats=c
26837         $LCTL set_param llite.*.parallel_dio=0
26838         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26839
26840         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26841                 error "dio with parallel dio disabled failed"
26842
26843         # Ideally, we would see only one RPC in flight here, but there is an
26844         # unavoidable race between i/o completion and RPC in flight counting,
26845         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26846         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26847         # So instead we just verify it's always < 8.
26848         $LCTL get_param osc.*-OST0000-*.rpc_stats
26849         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26850                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26851                 grep '^$' -B1 | grep . | awk '{print $1}')
26852         [ $ret != "8:" ] ||
26853                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26854 }
26855 run_test 398g "verify parallel dio async RPC submission"
26856
26857 test_398h() { #  LU-13798
26858         local dio_file=$DIR/$tfile.dio
26859
26860         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26861
26862         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26863         stack_trap "rm -f $DIR/$tfile $dio_file"
26864
26865         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26866                 error "parallel dio failed"
26867         diff $DIR/$tfile $dio_file
26868         [[ $? == 0 ]] || error "file diff after aiocp"
26869 }
26870 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26871
26872 test_398i() { #  LU-13798
26873         local dio_file=$DIR/$tfile.dio
26874
26875         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26876
26877         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26878         stack_trap "rm -f $DIR/$tfile $dio_file"
26879
26880         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26881         $LCTL set_param fail_loc=0x1418
26882         # make sure we don't crash and fail properly
26883         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26884                 error "parallel dio page allocation failure succeeded"
26885         diff $DIR/$tfile $dio_file
26886         [[ $? != 0 ]] || error "no diff after failed aiocp"
26887 }
26888 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26889
26890 test_398j() { #  LU-13798
26891         # Stripe size > RPC size but less than i/o size tests split across
26892         # stripes and RPCs for individual i/o op
26893         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26894
26895         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26896         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26897         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26898         stack_trap "$LCTL set_param -n $pages_per_rpc"
26899
26900         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26901                 error "parallel dio write failed"
26902         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26903
26904         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26905                 error "parallel dio read failed"
26906         diff $DIR/$tfile $DIR/$tfile.2
26907         [[ $? == 0 ]] || error "file diff after parallel dio read"
26908 }
26909 run_test 398j "test parallel dio where stripe size > rpc_size"
26910
26911 test_398k() { #  LU-13798
26912         wait_delete_completed
26913         wait_mds_ost_sync
26914
26915         # 4 stripe file; we will cause out of space on OST0
26916         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26917
26918         # Fill OST0 (if it's not too large)
26919         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26920                    head -n1)
26921         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26922                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26923         fi
26924         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26925         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26926                 error "dd should fill OST0"
26927         stack_trap "rm -f $DIR/$tfile.1"
26928
26929         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26930         err=$?
26931
26932         ls -la $DIR/$tfile
26933         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26934                 error "file is not 0 bytes in size"
26935
26936         # dd above should not succeed, but don't error until here so we can
26937         # get debug info above
26938         [[ $err != 0 ]] ||
26939                 error "parallel dio write with enospc succeeded"
26940         stack_trap "rm -f $DIR/$tfile"
26941 }
26942 run_test 398k "test enospc on first stripe"
26943
26944 test_398l() { #  LU-13798
26945         wait_delete_completed
26946         wait_mds_ost_sync
26947
26948         # 4 stripe file; we will cause out of space on OST0
26949         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
26950         # happens on the second i/o chunk we issue
26951         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
26952
26953         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
26954         stack_trap "rm -f $DIR/$tfile"
26955
26956         # Fill OST0 (if it's not too large)
26957         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26958                    head -n1)
26959         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26960                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26961         fi
26962         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26963         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26964                 error "dd should fill OST0"
26965         stack_trap "rm -f $DIR/$tfile.1"
26966
26967         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
26968         err=$?
26969         stack_trap "rm -f $DIR/$tfile.2"
26970
26971         # Check that short write completed as expected
26972         ls -la $DIR/$tfile.2
26973         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
26974                 error "file is not 1M in size"
26975
26976         # dd above should not succeed, but don't error until here so we can
26977         # get debug info above
26978         [[ $err != 0 ]] ||
26979                 error "parallel dio write with enospc succeeded"
26980
26981         # Truncate source file to same length as output file and diff them
26982         $TRUNCATE $DIR/$tfile 1048576
26983         diff $DIR/$tfile $DIR/$tfile.2
26984         [[ $? == 0 ]] || error "data incorrect after short write"
26985 }
26986 run_test 398l "test enospc on intermediate stripe/RPC"
26987
26988 test_398m() { #  LU-13798
26989         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26990
26991         # Set up failure on OST0, the first stripe:
26992         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
26993         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
26994         # OST0 is on ost1, OST1 is on ost2.
26995         # So this fail_val specifies OST0
26996         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
26997         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26998
26999         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27000                 error "parallel dio write with failure on first stripe succeeded"
27001         stack_trap "rm -f $DIR/$tfile"
27002         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27003
27004         # Place data in file for read
27005         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27006                 error "parallel dio write failed"
27007
27008         # Fail read on OST0, first stripe
27009         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27010         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27011         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27012                 error "parallel dio read with error on first stripe succeeded"
27013         rm -f $DIR/$tfile.2
27014         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27015
27016         # Switch to testing on OST1, second stripe
27017         # Clear file contents, maintain striping
27018         echo > $DIR/$tfile
27019         # Set up failure on OST1, second stripe:
27020         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27021         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27022
27023         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27024                 error "parallel dio write with failure on second stripe succeeded"
27025         stack_trap "rm -f $DIR/$tfile"
27026         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27027
27028         # Place data in file for read
27029         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27030                 error "parallel dio write failed"
27031
27032         # Fail read on OST1, second stripe
27033         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27034         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27035         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27036                 error "parallel dio read with error on second stripe succeeded"
27037         rm -f $DIR/$tfile.2
27038         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27039 }
27040 run_test 398m "test RPC failures with parallel dio"
27041
27042 # Parallel submission of DIO should not cause problems for append, but it's
27043 # important to verify.
27044 test_398n() { #  LU-13798
27045         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27046
27047         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27048                 error "dd to create source file failed"
27049         stack_trap "rm -f $DIR/$tfile"
27050
27051         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27052                 error "parallel dio write with failure on second stripe succeeded"
27053         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27054         diff $DIR/$tfile $DIR/$tfile.1
27055         [[ $? == 0 ]] || error "data incorrect after append"
27056
27057 }
27058 run_test 398n "test append with parallel DIO"
27059
27060 test_398o() {
27061         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27062 }
27063 run_test 398o "right kms with DIO"
27064
27065 test_398p()
27066 {
27067         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27068         which aiocp || skip_env "no aiocp installed"
27069
27070         local stripe_size=$((1024 * 1024)) #1 MiB
27071         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27072         local file_size=$((25 * stripe_size))
27073
27074         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27075         stack_trap "rm -f $DIR/$tfile*"
27076         # Just a bit bigger than the largest size in the test set below
27077         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27078                 error "buffered i/o to create file failed"
27079
27080         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27081                 $((stripe_size * 4)); do
27082
27083                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27084
27085                 echo "bs: $bs, file_size $file_size"
27086                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27087                         $DIR/$tfile.1 $DIR/$tfile.2 &
27088                 pid_dio1=$!
27089                 # Buffered I/O with similar but not the same block size
27090                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27091                         conv=notrunc &
27092                 pid_bio2=$!
27093                 wait $pid_dio1
27094                 rc1=$?
27095                 wait $pid_bio2
27096                 rc2=$?
27097                 if (( rc1 != 0 )); then
27098                         error "aio copy 1 w/bsize $bs failed: $rc1"
27099                 fi
27100                 if (( rc2 != 0 )); then
27101                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27102                 fi
27103
27104                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27105                         error "size incorrect"
27106                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27107                         error "files differ, bsize $bs"
27108                 rm -f $DIR/$tfile.2
27109         done
27110 }
27111 run_test 398p "race aio with buffered i/o"
27112
27113 test_398q()
27114 {
27115         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27116
27117         local stripe_size=$((1024 * 1024)) #1 MiB
27118         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27119         local file_size=$((25 * stripe_size))
27120
27121         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27122         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27123
27124         # Just a bit bigger than the largest size in the test set below
27125         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27126                 error "buffered i/o to create file failed"
27127
27128         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27129                 $((stripe_size * 4)); do
27130
27131                 echo "bs: $bs, file_size $file_size"
27132                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27133                         conv=notrunc oflag=direct iflag=direct &
27134                 pid_dio1=$!
27135                 # Buffered I/O with similar but not the same block size
27136                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27137                         conv=notrunc &
27138                 pid_bio2=$!
27139                 wait $pid_dio1
27140                 rc1=$?
27141                 wait $pid_bio2
27142                 rc2=$?
27143                 if (( rc1 != 0 )); then
27144                         error "dio copy 1 w/bsize $bs failed: $rc1"
27145                 fi
27146                 if (( rc2 != 0 )); then
27147                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27148                 fi
27149
27150                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27151                         error "size incorrect"
27152                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27153                         error "files differ, bsize $bs"
27154         done
27155
27156         rm -f $DIR/$tfile*
27157 }
27158 run_test 398q "race dio with buffered i/o"
27159
27160 test_fake_rw() {
27161         local read_write=$1
27162         if [ "$read_write" = "write" ]; then
27163                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27164         elif [ "$read_write" = "read" ]; then
27165                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27166         else
27167                 error "argument error"
27168         fi
27169
27170         # turn off debug for performance testing
27171         local saved_debug=$($LCTL get_param -n debug)
27172         $LCTL set_param debug=0
27173
27174         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27175
27176         # get ost1 size - $FSNAME-OST0000
27177         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27178         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27179         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27180
27181         if [ "$read_write" = "read" ]; then
27182                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27183         fi
27184
27185         local start_time=$(date +%s.%N)
27186         $dd_cmd bs=1M count=$blocks oflag=sync ||
27187                 error "real dd $read_write error"
27188         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27189
27190         if [ "$read_write" = "write" ]; then
27191                 rm -f $DIR/$tfile
27192         fi
27193
27194         # define OBD_FAIL_OST_FAKE_RW           0x238
27195         do_facet ost1 $LCTL set_param fail_loc=0x238
27196
27197         local start_time=$(date +%s.%N)
27198         $dd_cmd bs=1M count=$blocks oflag=sync ||
27199                 error "fake dd $read_write error"
27200         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27201
27202         if [ "$read_write" = "write" ]; then
27203                 # verify file size
27204                 cancel_lru_locks osc
27205                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27206                         error "$tfile size not $blocks MB"
27207         fi
27208         do_facet ost1 $LCTL set_param fail_loc=0
27209
27210         echo "fake $read_write $duration_fake vs. normal $read_write" \
27211                 "$duration in seconds"
27212         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27213                 error_not_in_vm "fake write is slower"
27214
27215         $LCTL set_param -n debug="$saved_debug"
27216         rm -f $DIR/$tfile
27217 }
27218 test_399a() { # LU-7655 for OST fake write
27219         remote_ost_nodsh && skip "remote OST with nodsh"
27220
27221         test_fake_rw write
27222 }
27223 run_test 399a "fake write should not be slower than normal write"
27224
27225 test_399b() { # LU-8726 for OST fake read
27226         remote_ost_nodsh && skip "remote OST with nodsh"
27227         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27228                 skip_env "ldiskfs only test"
27229         fi
27230
27231         test_fake_rw read
27232 }
27233 run_test 399b "fake read should not be slower than normal read"
27234
27235 test_400a() { # LU-1606, was conf-sanity test_74
27236         if ! which $CC > /dev/null 2>&1; then
27237                 skip_env "$CC is not installed"
27238         fi
27239
27240         local extra_flags=''
27241         local out=$TMP/$tfile
27242         local prefix=/usr/include/lustre
27243         local prog
27244
27245         # Oleg removes .c files in his test rig so test if any c files exist
27246         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27247                 skip_env "Needed .c test files are missing"
27248
27249         if ! [[ -d $prefix ]]; then
27250                 # Assume we're running in tree and fixup the include path.
27251                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27252                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27253                 extra_flags+=" -L$LUSTRE/utils/.libs"
27254         fi
27255
27256         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27257                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27258                         error "client api broken"
27259         done
27260         rm -f $out
27261 }
27262 run_test 400a "Lustre client api program can compile and link"
27263
27264 test_400b() { # LU-1606, LU-5011
27265         local header
27266         local out=$TMP/$tfile
27267         local prefix=/usr/include/linux/lustre
27268
27269         # We use a hard coded prefix so that this test will not fail
27270         # when run in tree. There are headers in lustre/include/lustre/
27271         # that are not packaged (like lustre_idl.h) and have more
27272         # complicated include dependencies (like config.h and lnet/types.h).
27273         # Since this test about correct packaging we just skip them when
27274         # they don't exist (see below) rather than try to fixup cppflags.
27275
27276         if ! which $CC > /dev/null 2>&1; then
27277                 skip_env "$CC is not installed"
27278         fi
27279
27280         for header in $prefix/*.h; do
27281                 if ! [[ -f "$header" ]]; then
27282                         continue
27283                 fi
27284
27285                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27286                         continue # lustre_ioctl.h is internal header
27287                 fi
27288
27289                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27290                         error "cannot compile '$header'"
27291         done
27292         rm -f $out
27293 }
27294 run_test 400b "packaged headers can be compiled"
27295
27296 test_401a() { #LU-7437
27297         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27298         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27299
27300         #count the number of parameters by "list_param -R"
27301         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27302         #count the number of parameters by listing proc files
27303         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27304         echo "proc_dirs='$proc_dirs'"
27305         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27306         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27307                       sort -u | wc -l)
27308
27309         [ $params -eq $procs ] ||
27310                 error "found $params parameters vs. $procs proc files"
27311
27312         # test the list_param -D option only returns directories
27313         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27314         #count the number of parameters by listing proc directories
27315         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27316                 sort -u | wc -l)
27317
27318         [ $params -eq $procs ] ||
27319                 error "found $params parameters vs. $procs proc files"
27320 }
27321 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27322
27323 test_401b() {
27324         # jobid_var may not allow arbitrary values, so use jobid_name
27325         # if available
27326         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27327                 local testname=jobid_name tmp='testing%p'
27328         else
27329                 local testname=jobid_var tmp=testing
27330         fi
27331
27332         local save=$($LCTL get_param -n $testname)
27333
27334         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27335                 error "no error returned when setting bad parameters"
27336
27337         local jobid_new=$($LCTL get_param -n foe $testname baz)
27338         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27339
27340         $LCTL set_param -n fog=bam $testname=$save bat=fog
27341         local jobid_old=$($LCTL get_param -n foe $testname bag)
27342         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27343 }
27344 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27345
27346 test_401c() {
27347         # jobid_var may not allow arbitrary values, so use jobid_name
27348         # if available
27349         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27350                 local testname=jobid_name
27351         else
27352                 local testname=jobid_var
27353         fi
27354
27355         local jobid_var_old=$($LCTL get_param -n $testname)
27356         local jobid_var_new
27357
27358         $LCTL set_param $testname= &&
27359                 error "no error returned for 'set_param a='"
27360
27361         jobid_var_new=$($LCTL get_param -n $testname)
27362         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27363                 error "$testname was changed by setting without value"
27364
27365         $LCTL set_param $testname &&
27366                 error "no error returned for 'set_param a'"
27367
27368         jobid_var_new=$($LCTL get_param -n $testname)
27369         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27370                 error "$testname was changed by setting without value"
27371 }
27372 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27373
27374 test_401d() {
27375         # jobid_var may not allow arbitrary values, so use jobid_name
27376         # if available
27377         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27378                 local testname=jobid_name new_value='foo=bar%p'
27379         else
27380                 local testname=jobid_var new_valuie=foo=bar
27381         fi
27382
27383         local jobid_var_old=$($LCTL get_param -n $testname)
27384         local jobid_var_new
27385
27386         $LCTL set_param $testname=$new_value ||
27387                 error "'set_param a=b' did not accept a value containing '='"
27388
27389         jobid_var_new=$($LCTL get_param -n $testname)
27390         [[ "$jobid_var_new" == "$new_value" ]] ||
27391                 error "'set_param a=b' failed on a value containing '='"
27392
27393         # Reset the $testname to test the other format
27394         $LCTL set_param $testname=$jobid_var_old
27395         jobid_var_new=$($LCTL get_param -n $testname)
27396         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27397                 error "failed to reset $testname"
27398
27399         $LCTL set_param $testname $new_value ||
27400                 error "'set_param a b' did not accept a value containing '='"
27401
27402         jobid_var_new=$($LCTL get_param -n $testname)
27403         [[ "$jobid_var_new" == "$new_value" ]] ||
27404                 error "'set_param a b' failed on a value containing '='"
27405
27406         $LCTL set_param $testname $jobid_var_old
27407         jobid_var_new=$($LCTL get_param -n $testname)
27408         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27409                 error "failed to reset $testname"
27410 }
27411 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27412
27413 test_401e() { # LU-14779
27414         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27415                 error "lctl list_param MGC* failed"
27416         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27417         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27418                 error "lctl get_param lru_size failed"
27419 }
27420 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27421
27422 test_402() {
27423         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27424         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27425                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27426         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27427                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27428                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27429         remote_mds_nodsh && skip "remote MDS with nodsh"
27430
27431         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27432 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27433         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27434         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27435                 echo "Touch failed - OK"
27436 }
27437 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27438
27439 test_403() {
27440         local file1=$DIR/$tfile.1
27441         local file2=$DIR/$tfile.2
27442         local tfile=$TMP/$tfile
27443
27444         rm -f $file1 $file2 $tfile
27445
27446         touch $file1
27447         ln $file1 $file2
27448
27449         # 30 sec OBD_TIMEOUT in ll_getattr()
27450         # right before populating st_nlink
27451         $LCTL set_param fail_loc=0x80001409
27452         stat -c %h $file1 > $tfile &
27453
27454         # create an alias, drop all locks and reclaim the dentry
27455         < $file2
27456         cancel_lru_locks mdc
27457         cancel_lru_locks osc
27458         sysctl -w vm.drop_caches=2
27459
27460         wait
27461
27462         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27463
27464         rm -f $tfile $file1 $file2
27465 }
27466 run_test 403 "i_nlink should not drop to zero due to aliasing"
27467
27468 test_404() { # LU-6601
27469         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27470                 skip "Need server version newer than 2.8.52"
27471         remote_mds_nodsh && skip "remote MDS with nodsh"
27472
27473         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27474                 awk '/osp .*-osc-MDT/ { print $4}')
27475
27476         local osp
27477         for osp in $mosps; do
27478                 echo "Deactivate: " $osp
27479                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27480                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27481                         awk -vp=$osp '$4 == p { print $2 }')
27482                 [ $stat = IN ] || {
27483                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27484                         error "deactivate error"
27485                 }
27486                 echo "Activate: " $osp
27487                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27488                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27489                         awk -vp=$osp '$4 == p { print $2 }')
27490                 [ $stat = UP ] || {
27491                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27492                         error "activate error"
27493                 }
27494         done
27495 }
27496 run_test 404 "validate manual {de}activated works properly for OSPs"
27497
27498 test_405() {
27499         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27500         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27501                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27502                         skip "Layout swap lock is not supported"
27503
27504         check_swap_layouts_support
27505         check_swap_layout_no_dom $DIR
27506
27507         test_mkdir $DIR/$tdir
27508         swap_lock_test -d $DIR/$tdir ||
27509                 error "One layout swap locked test failed"
27510 }
27511 run_test 405 "Various layout swap lock tests"
27512
27513 test_406() {
27514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27515         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27516         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27518         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27519                 skip "Need MDS version at least 2.8.50"
27520
27521         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27522         local test_pool=$TESTNAME
27523
27524         pool_add $test_pool || error "pool_add failed"
27525         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27526                 error "pool_add_targets failed"
27527
27528         save_layout_restore_at_exit $MOUNT
27529
27530         # parent set default stripe count only, child will stripe from both
27531         # parent and fs default
27532         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27533                 error "setstripe $MOUNT failed"
27534         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27535         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27536         for i in $(seq 10); do
27537                 local f=$DIR/$tdir/$tfile.$i
27538                 touch $f || error "touch failed"
27539                 local count=$($LFS getstripe -c $f)
27540                 [ $count -eq $OSTCOUNT ] ||
27541                         error "$f stripe count $count != $OSTCOUNT"
27542                 local offset=$($LFS getstripe -i $f)
27543                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27544                 local size=$($LFS getstripe -S $f)
27545                 [ $size -eq $((def_stripe_size * 2)) ] ||
27546                         error "$f stripe size $size != $((def_stripe_size * 2))"
27547                 local pool=$($LFS getstripe -p $f)
27548                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27549         done
27550
27551         # change fs default striping, delete parent default striping, now child
27552         # will stripe from new fs default striping only
27553         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27554                 error "change $MOUNT default stripe failed"
27555         $LFS setstripe -c 0 $DIR/$tdir ||
27556                 error "delete $tdir default stripe failed"
27557         for i in $(seq 11 20); do
27558                 local f=$DIR/$tdir/$tfile.$i
27559                 touch $f || error "touch $f failed"
27560                 local count=$($LFS getstripe -c $f)
27561                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27562                 local offset=$($LFS getstripe -i $f)
27563                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27564                 local size=$($LFS getstripe -S $f)
27565                 [ $size -eq $def_stripe_size ] ||
27566                         error "$f stripe size $size != $def_stripe_size"
27567                 local pool=$($LFS getstripe -p $f)
27568                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27569         done
27570
27571         unlinkmany $DIR/$tdir/$tfile. 1 20
27572
27573         local f=$DIR/$tdir/$tfile
27574         pool_remove_all_targets $test_pool $f
27575         pool_remove $test_pool $f
27576 }
27577 run_test 406 "DNE support fs default striping"
27578
27579 test_407() {
27580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27581         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27582                 skip "Need MDS version at least 2.8.55"
27583         remote_mds_nodsh && skip "remote MDS with nodsh"
27584
27585         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27586                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27587         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27588                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27589         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27590
27591         #define OBD_FAIL_DT_TXN_STOP    0x2019
27592         for idx in $(seq $MDSCOUNT); do
27593                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27594         done
27595         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27596         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27597                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27598         true
27599 }
27600 run_test 407 "transaction fail should cause operation fail"
27601
27602 test_408() {
27603         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27604
27605         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27606         lctl set_param fail_loc=0x8000040a
27607         # let ll_prepare_partial_page() fail
27608         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27609
27610         rm -f $DIR/$tfile
27611
27612         # create at least 100 unused inodes so that
27613         # shrink_icache_memory(0) should not return 0
27614         touch $DIR/$tfile-{0..100}
27615         rm -f $DIR/$tfile-{0..100}
27616         sync
27617
27618         echo 2 > /proc/sys/vm/drop_caches
27619 }
27620 run_test 408 "drop_caches should not hang due to page leaks"
27621
27622 test_409()
27623 {
27624         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27625
27626         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27627         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27628         touch $DIR/$tdir/guard || error "(2) Fail to create"
27629
27630         local PREFIX=$(str_repeat 'A' 128)
27631         echo "Create 1K hard links start at $(date)"
27632         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27633                 error "(3) Fail to hard link"
27634
27635         echo "Links count should be right although linkEA overflow"
27636         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27637         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27638         [ $linkcount -eq 1001 ] ||
27639                 error "(5) Unexpected hard links count: $linkcount"
27640
27641         echo "List all links start at $(date)"
27642         ls -l $DIR/$tdir/foo > /dev/null ||
27643                 error "(6) Fail to list $DIR/$tdir/foo"
27644
27645         echo "Unlink hard links start at $(date)"
27646         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27647                 error "(7) Fail to unlink"
27648         echo "Unlink hard links finished at $(date)"
27649 }
27650 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27651
27652 test_410()
27653 {
27654         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27655                 skip "Need client version at least 2.9.59"
27656         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27657                 skip "Need MODULES build"
27658
27659         # Create a file, and stat it from the kernel
27660         local testfile=$DIR/$tfile
27661         touch $testfile
27662
27663         local run_id=$RANDOM
27664         local my_ino=$(stat --format "%i" $testfile)
27665
27666         # Try to insert the module. This will always fail as the
27667         # module is designed to not be inserted.
27668         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27669             &> /dev/null
27670
27671         # Anything but success is a test failure
27672         dmesg | grep -q \
27673             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27674             error "no inode match"
27675 }
27676 run_test 410 "Test inode number returned from kernel thread"
27677
27678 cleanup_test411_cgroup() {
27679         trap 0
27680         cat $1/memory.stat
27681         rmdir "$1"
27682 }
27683
27684 test_411a() {
27685         local cg_basedir=/sys/fs/cgroup/memory
27686         # LU-9966
27687         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27688                 skip "no setup for cgroup"
27689
27690         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27691                 error "test file creation failed"
27692         cancel_lru_locks osc
27693
27694         # Create a very small memory cgroup to force a slab allocation error
27695         local cgdir=$cg_basedir/osc_slab_alloc
27696         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27697         trap "cleanup_test411_cgroup $cgdir" EXIT
27698         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27699         echo 1M > $cgdir/memory.limit_in_bytes
27700
27701         # Should not LBUG, just be killed by oom-killer
27702         # dd will return 0 even allocation failure in some environment.
27703         # So don't check return value
27704         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27705         cleanup_test411_cgroup $cgdir
27706
27707         return 0
27708 }
27709 run_test 411a "Slab allocation error with cgroup does not LBUG"
27710
27711 test_411b() {
27712         local cg_basedir=/sys/fs/cgroup/memory
27713         # LU-9966
27714         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27715                 skip "no setup for cgroup"
27716         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27717         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27718         # limit, so we have 384M in cgroup
27719         # (arm) this seems to hit OOM more often than x86, so 1024M
27720         if [[ $(uname -m) = aarch64 ]]; then
27721                 local memlimit_mb=1024
27722         else
27723                 local memlimit_mb=384
27724         fi
27725
27726         # Create a cgroup and set memory limit
27727         # (tfile is used as an easy way to get a recognizable cgroup name)
27728         local cgdir=$cg_basedir/$tfile
27729         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27730         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27731         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27732
27733         echo "writing first file"
27734         # Write a file 4x the memory limit in size
27735         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27736                 error "(1) failed to write successfully"
27737
27738         sync
27739         cancel_lru_locks osc
27740
27741         rm -f $DIR/$tfile
27742         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27743
27744         # Try writing at a larger block size
27745         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27746         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27747         # need *some* memory to do IO in)
27748         echo "writing at larger block size"
27749         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27750                 error "(3) failed to write successfully"
27751
27752         sync
27753         cancel_lru_locks osc
27754         rm -f $DIR/$tfile
27755         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27756
27757         # Try writing multiple files at once
27758         echo "writing multiple files"
27759         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27760         local pid1=$!
27761         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27762         local pid2=$!
27763         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27764         local pid3=$!
27765         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27766         local pid4=$!
27767
27768         wait $pid1
27769         local rc1=$?
27770         wait $pid2
27771         local rc2=$?
27772         wait $pid3
27773         local rc3=$?
27774         wait $pid4
27775         local rc4=$?
27776         if (( rc1 != 0)); then
27777                 error "error $rc1 writing to file from $pid1"
27778         fi
27779         if (( rc2 != 0)); then
27780                 error "error $rc2 writing to file from $pid2"
27781         fi
27782         if (( rc3 != 0)); then
27783                 error "error $rc3 writing to file from $pid3"
27784         fi
27785         if (( rc4 != 0)); then
27786                 error "error $rc4 writing to file from $pid4"
27787         fi
27788
27789         sync
27790         cancel_lru_locks osc
27791
27792         # These files can be large-ish (~1 GiB total), so delete them rather
27793         # than leave for later cleanup
27794         rm -f $DIR/$tfile.*
27795         return 0
27796 }
27797 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27798
27799 test_412() {
27800         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27801         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27802                 skip "Need server version at least 2.10.55"
27803
27804         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27805                 error "mkdir failed"
27806         $LFS getdirstripe $DIR/$tdir
27807         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27808         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27809                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27810         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27811         [ $stripe_count -eq 2 ] ||
27812                 error "expect 2 get $stripe_count"
27813
27814         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27815
27816         local index
27817         local index2
27818
27819         # subdirs should be on the same MDT as parent
27820         for i in $(seq 0 $((MDSCOUNT - 1))); do
27821                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27822                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27823                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27824                 (( index == i )) || error "mdt$i/sub on MDT$index"
27825         done
27826
27827         # stripe offset -1, ditto
27828         for i in {1..10}; do
27829                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27830                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27831                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27832                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27833                 (( index == index2 )) ||
27834                         error "qos$i on MDT$index, sub on MDT$index2"
27835         done
27836
27837         local testdir=$DIR/$tdir/inherit
27838
27839         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27840         # inherit 2 levels
27841         for i in 1 2; do
27842                 testdir=$testdir/s$i
27843                 mkdir $testdir || error "mkdir $testdir failed"
27844                 index=$($LFS getstripe -m $testdir)
27845                 (( index == 1 )) ||
27846                         error "$testdir on MDT$index"
27847         done
27848
27849         # not inherit any more
27850         testdir=$testdir/s3
27851         mkdir $testdir || error "mkdir $testdir failed"
27852         getfattr -d -m dmv $testdir | grep dmv &&
27853                 error "default LMV set on $testdir" || true
27854 }
27855 run_test 412 "mkdir on specific MDTs"
27856
27857 TEST413_COUNT=${TEST413_COUNT:-200}
27858
27859 #
27860 # set_maxage() is used by test_413 only.
27861 # This is a helper function to set maxage. Does not return any value.
27862 # Input: maxage to set
27863 #
27864 set_maxage() {
27865         local lmv_qos_maxage
27866         local lod_qos_maxage
27867         local new_maxage=$1
27868
27869         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27870         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27871         stack_trap "$LCTL set_param \
27872                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27873         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27874                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27875         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27876                 lod.*.mdt_qos_maxage=$new_maxage
27877         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27878                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27879 }
27880
27881 generate_uneven_mdts() {
27882         local threshold=$1
27883         local ffree
27884         local bavail
27885         local max
27886         local min
27887         local max_index
27888         local min_index
27889         local tmp
27890         local i
27891
27892         echo
27893         echo "Check for uneven MDTs: "
27894
27895         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27896         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27897         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27898
27899         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27900         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27901         max_index=0
27902         min_index=0
27903         for ((i = 1; i < ${#ffree[@]}; i++)); do
27904                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27905                 if [ $tmp -gt $max ]; then
27906                         max=$tmp
27907                         max_index=$i
27908                 fi
27909                 if [ $tmp -lt $min ]; then
27910                         min=$tmp
27911                         min_index=$i
27912                 fi
27913         done
27914
27915         (( min > 0 )) || skip "low space on MDT$min_index"
27916         (( ${ffree[min_index]} > 0 )) ||
27917                 skip "no free files on MDT$min_index"
27918         (( ${ffree[min_index]} < 10000000 )) ||
27919                 skip "too many free files on MDT$min_index"
27920
27921         # Check if we need to generate uneven MDTs
27922         local diff=$(((max - min) * 100 / min))
27923         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27924         local testdir # individual folder within $testdirp
27925         local start
27926         local cmd
27927
27928         # fallocate is faster to consume space on MDT, if available
27929         if check_fallocate_supported mds$((min_index + 1)); then
27930                 cmd="fallocate -l 128K "
27931         else
27932                 cmd="dd if=/dev/zero bs=128K count=1 of="
27933         fi
27934
27935         echo "using cmd $cmd"
27936         for (( i = 0; diff < threshold; i++ )); do
27937                 testdir=${testdirp}/$i
27938                 [ -d $testdir ] && continue
27939
27940                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27941
27942                 mkdir -p $testdirp
27943                 # generate uneven MDTs, create till $threshold% diff
27944                 echo -n "weight diff=$diff% must be > $threshold% ..."
27945                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27946                 $LFS mkdir -i $min_index $testdir ||
27947                         error "mkdir $testdir failed"
27948                 $LFS setstripe -E 1M -L mdt $testdir ||
27949                         error "setstripe $testdir failed"
27950                 start=$SECONDS
27951                 for (( f = 0; f < TEST413_COUNT; f++ )); do
27952                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
27953                 done
27954                 sync; sleep 1; sync
27955
27956                 # wait for QOS to update
27957                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
27958
27959                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
27960                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
27961                 max=$(((${ffree[max_index]} >> 8) *
27962                         (${bavail[max_index]} * bsize >> 16)))
27963                 min=$(((${ffree[min_index]} >> 8) *
27964                         (${bavail[min_index]} * bsize >> 16)))
27965                 (( min > 0 )) || skip "low space on MDT$min_index"
27966                 diff=$(((max - min) * 100 / min))
27967         done
27968
27969         echo "MDT filesfree available: ${ffree[*]}"
27970         echo "MDT blocks available: ${bavail[*]}"
27971         echo "weight diff=$diff%"
27972 }
27973
27974 test_qos_mkdir() {
27975         local mkdir_cmd=$1
27976         local stripe_count=$2
27977         local mdts=$(comma_list $(mdts_nodes))
27978
27979         local testdir
27980         local lmv_qos_prio_free
27981         local lmv_qos_threshold_rr
27982         local lod_qos_prio_free
27983         local lod_qos_threshold_rr
27984         local total
27985         local count
27986         local i
27987
27988         # @total is total directories created if it's testing plain
27989         # directories, otherwise it's total stripe object count for
27990         # striped directories test.
27991         # remote/striped directory unlinking is slow on zfs and may
27992         # timeout, test with fewer directories
27993         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
27994
27995         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
27996         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
27997         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27998                 head -n1)
27999         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28000         stack_trap "$LCTL set_param \
28001                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28002         stack_trap "$LCTL set_param \
28003                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28004
28005         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28006                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28007         lod_qos_prio_free=${lod_qos_prio_free%%%}
28008         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28009                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28010         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28011         stack_trap "do_nodes $mdts $LCTL set_param \
28012                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28013         stack_trap "do_nodes $mdts $LCTL set_param \
28014                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28015
28016         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28017         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28018
28019         testdir=$DIR/$tdir-s$stripe_count/rr
28020
28021         local stripe_index=$($LFS getstripe -m $testdir)
28022         local test_mkdir_rr=true
28023
28024         getfattr -d -m dmv -e hex $testdir | grep dmv
28025         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28026                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28027                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28028                         test_mkdir_rr=false
28029         fi
28030
28031         echo
28032         $test_mkdir_rr &&
28033                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28034                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28035
28036         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28037         for (( i = 0; i < total / stripe_count; i++ )); do
28038                 eval $mkdir_cmd $testdir/subdir$i ||
28039                         error "$mkdir_cmd subdir$i failed"
28040         done
28041
28042         for (( i = 0; i < $MDSCOUNT; i++ )); do
28043                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28044                 echo "$count directories created on MDT$i"
28045                 if $test_mkdir_rr; then
28046                         (( count == total / stripe_count / MDSCOUNT )) ||
28047                                 error "subdirs are not evenly distributed"
28048                 elif (( i == stripe_index )); then
28049                         (( count == total / stripe_count )) ||
28050                                 error "$count subdirs created on MDT$i"
28051                 else
28052                         (( count == 0 )) ||
28053                                 error "$count subdirs created on MDT$i"
28054                 fi
28055
28056                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28057                         count=$($LFS getdirstripe $testdir/* |
28058                                 grep -c -P "^\s+$i\t")
28059                         echo "$count stripes created on MDT$i"
28060                         # deviation should < 5% of average
28061                         delta=$((count - total / MDSCOUNT))
28062                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28063                                 error "stripes are not evenly distributed"
28064                 fi
28065         done
28066
28067         echo
28068         echo "Check for uneven MDTs: "
28069
28070         local ffree
28071         local bavail
28072         local max
28073         local min
28074         local max_index
28075         local min_index
28076         local tmp
28077
28078         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28079         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28080         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28081
28082         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28083         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28084         max_index=0
28085         min_index=0
28086         for ((i = 1; i < ${#ffree[@]}; i++)); do
28087                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28088                 if [ $tmp -gt $max ]; then
28089                         max=$tmp
28090                         max_index=$i
28091                 fi
28092                 if [ $tmp -lt $min ]; then
28093                         min=$tmp
28094                         min_index=$i
28095                 fi
28096         done
28097         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28098
28099         (( min > 0 )) || skip "low space on MDT$min_index"
28100         (( ${ffree[min_index]} < 10000000 )) ||
28101                 skip "too many free files on MDT$min_index"
28102
28103         generate_uneven_mdts 120
28104
28105         echo "MDT filesfree available: ${ffree[*]}"
28106         echo "MDT blocks available: ${bavail[*]}"
28107         echo "weight diff=$(((max - min) * 100 / min))%"
28108         echo
28109         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28110
28111         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28112         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28113         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28114         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28115         # decrease statfs age, so that it can be updated in time
28116         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28117         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28118
28119         sleep 1
28120
28121         testdir=$DIR/$tdir-s$stripe_count/qos
28122
28123         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28124         for (( i = 0; i < total / stripe_count; i++ )); do
28125                 eval $mkdir_cmd $testdir/subdir$i ||
28126                         error "$mkdir_cmd subdir$i failed"
28127         done
28128
28129         max=0
28130         for (( i = 0; i < $MDSCOUNT; i++ )); do
28131                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28132                 (( count > max )) && max=$count
28133                 echo "$count directories created on MDT$i : curmax=$max"
28134         done
28135
28136         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28137
28138         # D-value should > 10% of average
28139         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28140                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28141
28142         # ditto for stripes
28143         if (( stripe_count > 1 )); then
28144                 max=0
28145                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28146                         count=$($LFS getdirstripe $testdir/* |
28147                                 grep -c -P "^\s+$i\t")
28148                         (( count > max )) && max=$count
28149                         echo "$count stripes created on MDT$i"
28150                 done
28151
28152                 min=$($LFS getdirstripe $testdir/* |
28153                         grep -c -P "^\s+$min_index\t")
28154                 (( max - min > total / MDSCOUNT / 10 )) ||
28155                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28156         fi
28157 }
28158
28159 most_full_mdt() {
28160         local ffree
28161         local bavail
28162         local bsize
28163         local min
28164         local min_index
28165         local tmp
28166
28167         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28168         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28169         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28170
28171         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28172         min_index=0
28173         for ((i = 1; i < ${#ffree[@]}; i++)); do
28174                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28175                 (( tmp < min )) && min=$tmp && min_index=$i
28176         done
28177
28178         echo -n $min_index
28179 }
28180
28181 test_413a() {
28182         [ $MDSCOUNT -lt 2 ] &&
28183                 skip "We need at least 2 MDTs for this test"
28184
28185         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28186                 skip "Need server version at least 2.12.52"
28187
28188         local stripe_max=$((MDSCOUNT - 1))
28189         local stripe_count
28190
28191         # let caller set maxage for latest result
28192         set_maxage 1
28193
28194         # fill MDT unevenly
28195         generate_uneven_mdts 120
28196
28197         # test 4-stripe directory at most, otherwise it's too slow
28198         # We are being very defensive. Although Autotest uses 4 MDTs.
28199         # We make sure stripe_max does not go over 4.
28200         (( stripe_max > 4 )) && stripe_max=4
28201         # unlinking striped directory is slow on zfs, and may timeout, only test
28202         # plain directory
28203         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28204         for stripe_count in $(seq 1 $stripe_max); do
28205                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28206                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28207                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28208                         error "mkdir failed"
28209                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28210         done
28211 }
28212 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28213
28214 test_413b() {
28215         [ $MDSCOUNT -lt 2 ] &&
28216                 skip "We need at least 2 MDTs for this test"
28217
28218         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28219                 skip "Need server version at least 2.12.52"
28220
28221         local stripe_max=$((MDSCOUNT - 1))
28222         local testdir
28223         local stripe_count
28224
28225         # let caller set maxage for latest result
28226         set_maxage 1
28227
28228         # fill MDT unevenly
28229         generate_uneven_mdts 120
28230
28231         # test 4-stripe directory at most, otherwise it's too slow
28232         # We are being very defensive. Although Autotest uses 4 MDTs.
28233         # We make sure stripe_max does not go over 4.
28234         (( stripe_max > 4 )) && stripe_max=4
28235         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28236         for stripe_count in $(seq 1 $stripe_max); do
28237                 testdir=$DIR/$tdir-s$stripe_count
28238                 mkdir $testdir || error "mkdir $testdir failed"
28239                 mkdir $testdir/rr || error "mkdir rr failed"
28240                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28241                         error "mkdir qos failed"
28242                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28243                         $testdir/rr || error "setdirstripe rr failed"
28244                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28245                         error "setdirstripe failed"
28246                 test_qos_mkdir "mkdir" $stripe_count
28247         done
28248 }
28249 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28250
28251 test_413c() {
28252         (( $MDSCOUNT >= 2 )) ||
28253                 skip "We need at least 2 MDTs for this test"
28254
28255         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28256                 skip "Need server version at least 2.14.51"
28257
28258         local testdir
28259         local inherit
28260         local inherit_rr
28261         local lmv_qos_maxage
28262         local lod_qos_maxage
28263
28264         # let caller set maxage for latest result
28265         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28266         $LCTL set_param lmv.*.qos_maxage=1
28267         stack_trap "$LCTL set_param \
28268                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28269         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28270                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28271         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28272                 lod.*.mdt_qos_maxage=1
28273         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28274                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28275
28276         # fill MDT unevenly
28277         generate_uneven_mdts 120
28278
28279         testdir=$DIR/${tdir}-s1
28280         mkdir $testdir || error "mkdir $testdir failed"
28281         mkdir $testdir/rr || error "mkdir rr failed"
28282         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28283         # default max_inherit is -1, default max_inherit_rr is 0
28284         $LFS setdirstripe -D -c 1 $testdir/rr ||
28285                 error "setdirstripe rr failed"
28286         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28287                 error "setdirstripe qos failed"
28288         test_qos_mkdir "mkdir" 1
28289
28290         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28291         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28292         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28293         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28294         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28295
28296         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28297         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28298         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28299         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28300         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28301         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28302         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28303                 error "level2 shouldn't have default LMV" || true
28304 }
28305 run_test 413c "mkdir with default LMV max inherit rr"
28306
28307 test_413d() {
28308         (( MDSCOUNT >= 2 )) ||
28309                 skip "We need at least 2 MDTs for this test"
28310
28311         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28312                 skip "Need server version at least 2.14.51"
28313
28314         local lmv_qos_threshold_rr
28315
28316         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28317                 head -n1)
28318         stack_trap "$LCTL set_param \
28319                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28320
28321         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28322         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28323         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28324                 error "$tdir shouldn't have default LMV"
28325         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28326                 error "mkdir sub failed"
28327
28328         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28329
28330         (( count == 100 )) || error "$count subdirs on MDT0"
28331 }
28332 run_test 413d "inherit ROOT default LMV"
28333
28334 test_413e() {
28335         (( MDSCOUNT >= 2 )) ||
28336                 skip "We need at least 2 MDTs for this test"
28337         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28338                 skip "Need server version at least 2.14.55"
28339
28340         local testdir=$DIR/$tdir
28341         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28342         local max_inherit
28343         local sub_max_inherit
28344
28345         mkdir -p $testdir || error "failed to create $testdir"
28346
28347         # set default max-inherit to -1 if stripe count is 0 or 1
28348         $LFS setdirstripe -D -c 1 $testdir ||
28349                 error "failed to set default LMV"
28350         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28351         (( max_inherit == -1 )) ||
28352                 error "wrong max_inherit value $max_inherit"
28353
28354         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28355         $LFS setdirstripe -D -c -1 $testdir ||
28356                 error "failed to set default LMV"
28357         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28358         (( max_inherit > 0 )) ||
28359                 error "wrong max_inherit value $max_inherit"
28360
28361         # and the subdir will decrease the max_inherit by 1
28362         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28363         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28364         (( sub_max_inherit == max_inherit - 1)) ||
28365                 error "wrong max-inherit of subdir $sub_max_inherit"
28366
28367         # check specified --max-inherit and warning message
28368         stack_trap "rm -f $tmpfile"
28369         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28370                 error "failed to set default LMV"
28371         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28372         (( max_inherit == -1 )) ||
28373                 error "wrong max_inherit value $max_inherit"
28374
28375         # check the warning messages
28376         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28377                 error "failed to detect warning string"
28378         fi
28379 }
28380 run_test 413e "check default max-inherit value"
28381
28382 test_fs_dmv_inherit()
28383 {
28384         local testdir=$DIR/$tdir
28385
28386         local count
28387         local inherit
28388         local inherit_rr
28389
28390         for i in 1 2; do
28391                 mkdir $testdir || error "mkdir $testdir failed"
28392                 count=$($LFS getdirstripe -D -c $testdir)
28393                 (( count == 1 )) ||
28394                         error "$testdir default LMV count mismatch $count != 1"
28395                 inherit=$($LFS getdirstripe -D -X $testdir)
28396                 (( inherit == 3 - i )) ||
28397                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28398                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28399                 (( inherit_rr == 3 - i )) ||
28400                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28401                 testdir=$testdir/sub
28402         done
28403
28404         mkdir $testdir || error "mkdir $testdir failed"
28405         count=$($LFS getdirstripe -D -c $testdir)
28406         (( count == 0 )) ||
28407                 error "$testdir default LMV count not zero: $count"
28408 }
28409
28410 test_413f() {
28411         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28412
28413         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28414                 skip "Need server version at least 2.14.55"
28415
28416         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28417                 error "dump $DIR default LMV failed"
28418         stack_trap "setfattr --restore=$TMP/dmv.ea"
28419
28420         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28421                 error "set $DIR default LMV failed"
28422
28423         test_fs_dmv_inherit
28424 }
28425 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28426
28427 test_413g() {
28428         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28429
28430         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28431         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28432                 error "dump $DIR default LMV failed"
28433         stack_trap "setfattr --restore=$TMP/dmv.ea"
28434
28435         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28436                 error "set $DIR default LMV failed"
28437
28438         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28439                 error "mount $MOUNT2 failed"
28440         stack_trap "umount_client $MOUNT2"
28441
28442         local saved_DIR=$DIR
28443
28444         export DIR=$MOUNT2
28445
28446         stack_trap "export DIR=$saved_DIR"
28447
28448         # first check filesystem-wide default LMV inheritance
28449         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28450
28451         # then check subdirs are spread to all MDTs
28452         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28453
28454         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28455
28456         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28457 }
28458 run_test 413g "enforce ROOT default LMV on subdir mount"
28459
28460 test_413h() {
28461         (( MDSCOUNT >= 2 )) ||
28462                 skip "We need at least 2 MDTs for this test"
28463
28464         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28465                 skip "Need server version at least 2.15.50.6"
28466
28467         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28468
28469         stack_trap "$LCTL set_param \
28470                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28471         $LCTL set_param lmv.*.qos_maxage=1
28472
28473         local depth=5
28474         local rr_depth=4
28475         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28476         local count=$((MDSCOUNT * 20))
28477
28478         generate_uneven_mdts 50
28479
28480         mkdir -p $dir || error "mkdir $dir failed"
28481         stack_trap "rm -rf $dir"
28482         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28483                 --max-inherit-rr=$rr_depth $dir
28484
28485         for ((d=0; d < depth + 2; d++)); do
28486                 log "dir=$dir:"
28487                 for ((sub=0; sub < count; sub++)); do
28488                         mkdir $dir/d$sub
28489                 done
28490                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28491                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28492                 # subdirs within $rr_depth should be created round-robin
28493                 if (( d < rr_depth )); then
28494                         (( ${num[0]} != count )) ||
28495                                 error "all objects created on MDT ${num[1]}"
28496                 fi
28497
28498                 dir=$dir/d0
28499         done
28500 }
28501 run_test 413h "don't stick to parent for round-robin dirs"
28502
28503 test_413i() {
28504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28505
28506         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28507                 skip "Need server version at least 2.14.55"
28508
28509         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28510                 error "dump $DIR default LMV failed"
28511         stack_trap "setfattr --restore=$TMP/dmv.ea"
28512
28513         local testdir=$DIR/$tdir
28514         local def_max_rr=1
28515         local def_max=3
28516         local count
28517
28518         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28519                 --max-inherit-rr=$def_max_rr $DIR ||
28520                 error "set $DIR default LMV failed"
28521
28522         for i in $(seq 2 3); do
28523                 def_max=$((def_max - 1))
28524                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28525
28526                 mkdir $testdir
28527                 # RR is decremented and keeps zeroed once exhausted
28528                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28529                 (( count == def_max_rr )) ||
28530                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28531
28532                 # max-inherit is decremented
28533                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28534                 (( count == def_max )) ||
28535                         error_noexit "$testdir: max-inherit $count != $def_max"
28536
28537                 testdir=$testdir/d$i
28538         done
28539
28540         # d3 is the last inherited from ROOT, no inheritance anymore
28541         # i.e. no the default layout anymore
28542         mkdir -p $testdir/d4/d5
28543         count=$($LFS getdirstripe -D --max-inherit $testdir)
28544         (( count == -1 )) ||
28545                 error_noexit "$testdir: max-inherit $count != -1"
28546
28547         local p_count=$($LFS getdirstripe -i $testdir)
28548
28549         for i in $(seq 4 5); do
28550                 testdir=$testdir/d$i
28551
28552                 # the root default layout is not applied once exhausted
28553                 count=$($LFS getdirstripe -i $testdir)
28554                 (( count == p_count )) ||
28555                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28556         done
28557
28558         $LFS setdirstripe -i 0 $DIR/d2
28559         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28560         (( count == -1 )) ||
28561                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28562 }
28563 run_test 413i "check default layout inheritance"
28564
28565 test_413z() {
28566         local pids=""
28567         local subdir
28568         local pid
28569
28570         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28571                 unlinkmany $subdir/f. $TEST413_COUNT &
28572                 pids="$pids $!"
28573         done
28574
28575         for pid in $pids; do
28576                 wait $pid
28577         done
28578
28579         true
28580 }
28581 run_test 413z "413 test cleanup"
28582
28583 test_414() {
28584 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28585         $LCTL set_param fail_loc=0x80000521
28586         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28587         rm -f $DIR/$tfile
28588 }
28589 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28590
28591 test_415() {
28592         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28593         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28594                 skip "Need server version at least 2.11.52"
28595
28596         # LU-11102
28597         local total=500
28598         local max=120
28599
28600         # this test may be slow on ZFS
28601         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28602
28603         # though this test is designed for striped directory, let's test normal
28604         # directory too since lock is always saved as CoS lock.
28605         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28606         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28607         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28608         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28609         wait_delete_completed_mds
28610
28611         # run a loop without concurrent touch to measure rename duration.
28612         # only for test debug/robustness, NOT part of COS functional test.
28613         local start_time=$SECONDS
28614         for ((i = 0; i < total; i++)); do
28615                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28616                         > /dev/null
28617         done
28618         local baseline=$((SECONDS - start_time))
28619         echo "rename $total files without 'touch' took $baseline sec"
28620
28621         (
28622                 while true; do
28623                         touch $DIR/$tdir
28624                 done
28625         ) &
28626         local setattr_pid=$!
28627
28628         # rename files back to original name so unlinkmany works
28629         start_time=$SECONDS
28630         for ((i = 0; i < total; i++)); do
28631                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28632                         > /dev/null
28633         done
28634         local duration=$((SECONDS - start_time))
28635
28636         kill -9 $setattr_pid
28637
28638         echo "rename $total files with 'touch' took $duration sec"
28639         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28640         (( duration <= max )) ||
28641                 error_not_in_vm "rename took $duration > $max sec"
28642 }
28643 run_test 415 "lock revoke is not missing"
28644
28645 test_416() {
28646         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28647                 skip "Need server version at least 2.11.55"
28648
28649         # define OBD_FAIL_OSD_TXN_START    0x19a
28650         do_facet mds1 lctl set_param fail_loc=0x19a
28651
28652         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28653
28654         true
28655 }
28656 run_test 416 "transaction start failure won't cause system hung"
28657
28658 cleanup_417() {
28659         trap 0
28660         do_nodes $(comma_list $(mdts_nodes)) \
28661                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28662         do_nodes $(comma_list $(mdts_nodes)) \
28663                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28664         do_nodes $(comma_list $(mdts_nodes)) \
28665                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28666 }
28667
28668 test_417() {
28669         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28670         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28671                 skip "Need MDS version at least 2.11.56"
28672
28673         trap cleanup_417 RETURN EXIT
28674
28675         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28676         do_nodes $(comma_list $(mdts_nodes)) \
28677                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28678         $LFS migrate -m 0 $DIR/$tdir.1 &&
28679                 error "migrate dir $tdir.1 should fail"
28680
28681         do_nodes $(comma_list $(mdts_nodes)) \
28682                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28683         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28684                 error "create remote dir $tdir.2 should fail"
28685
28686         do_nodes $(comma_list $(mdts_nodes)) \
28687                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28688         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28689                 error "create striped dir $tdir.3 should fail"
28690         true
28691 }
28692 run_test 417 "disable remote dir, striped dir and dir migration"
28693
28694 # Checks that the outputs of df [-i] and lfs df [-i] match
28695 #
28696 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28697 check_lfs_df() {
28698         local dir=$2
28699         local inodes
28700         local df_out
28701         local lfs_df_out
28702         local count
28703         local passed=false
28704
28705         # blocks or inodes
28706         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28707
28708         for count in {1..100}; do
28709                 do_nodes "$CLIENTS" \
28710                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28711                 sync; sleep 0.2
28712
28713                 # read the lines of interest
28714                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28715                         error "df $inodes $dir | tail -n +2 failed"
28716                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28717                         error "lfs df $inodes $dir | grep summary: failed"
28718
28719                 # skip first substrings of each output as they are different
28720                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28721                 # compare the two outputs
28722                 passed=true
28723                 #  skip "available" on MDT until LU-13997 is fixed.
28724                 #for i in {1..5}; do
28725                 for i in 1 2 4 5; do
28726                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28727                 done
28728                 $passed && break
28729         done
28730
28731         if ! $passed; then
28732                 df -P $inodes $dir
28733                 echo
28734                 lfs df $inodes $dir
28735                 error "df and lfs df $1 output mismatch: "      \
28736                       "df ${inodes}: ${df_out[*]}, "            \
28737                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28738         fi
28739 }
28740
28741 test_418() {
28742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28743
28744         local dir=$DIR/$tdir
28745         local numfiles=$((RANDOM % 4096 + 2))
28746         local numblocks=$((RANDOM % 256 + 1))
28747
28748         wait_delete_completed
28749         test_mkdir $dir
28750
28751         # check block output
28752         check_lfs_df blocks $dir
28753         # check inode output
28754         check_lfs_df inodes $dir
28755
28756         # create a single file and retest
28757         echo "Creating a single file and testing"
28758         createmany -o $dir/$tfile- 1 &>/dev/null ||
28759                 error "creating 1 file in $dir failed"
28760         check_lfs_df blocks $dir
28761         check_lfs_df inodes $dir
28762
28763         # create a random number of files
28764         echo "Creating $((numfiles - 1)) files and testing"
28765         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28766                 error "creating $((numfiles - 1)) files in $dir failed"
28767
28768         # write a random number of blocks to the first test file
28769         echo "Writing $numblocks 4K blocks and testing"
28770         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28771                 count=$numblocks &>/dev/null ||
28772                 error "dd to $dir/${tfile}-0 failed"
28773
28774         # retest
28775         check_lfs_df blocks $dir
28776         check_lfs_df inodes $dir
28777
28778         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28779                 error "unlinking $numfiles files in $dir failed"
28780 }
28781 run_test 418 "df and lfs df outputs match"
28782
28783 test_419()
28784 {
28785         local dir=$DIR/$tdir
28786
28787         mkdir -p $dir
28788         touch $dir/file
28789
28790         cancel_lru_locks mdc
28791
28792         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28793         $LCTL set_param fail_loc=0x1410
28794         cat $dir/file
28795         $LCTL set_param fail_loc=0
28796         rm -rf $dir
28797 }
28798 run_test 419 "Verify open file by name doesn't crash kernel"
28799
28800 test_420()
28801 {
28802         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28803                 skip "Need MDS version at least 2.12.53"
28804
28805         local SAVE_UMASK=$(umask)
28806         local dir=$DIR/$tdir
28807         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28808
28809         mkdir -p $dir
28810         umask 0000
28811         mkdir -m03777 $dir/testdir
28812         ls -dn $dir/testdir
28813         # Need to remove trailing '.' when SELinux is enabled
28814         local dirperms=$(ls -dn $dir/testdir |
28815                          awk '{ sub(/\.$/, "", $1); print $1}')
28816         [ $dirperms == "drwxrwsrwt" ] ||
28817                 error "incorrect perms on $dir/testdir"
28818
28819         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28820                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28821         ls -n $dir/testdir/testfile
28822         local fileperms=$(ls -n $dir/testdir/testfile |
28823                           awk '{ sub(/\.$/, "", $1); print $1}')
28824         [ $fileperms == "-rwxr-xr-x" ] ||
28825                 error "incorrect perms on $dir/testdir/testfile"
28826
28827         umask $SAVE_UMASK
28828 }
28829 run_test 420 "clear SGID bit on non-directories for non-members"
28830
28831 test_421a() {
28832         local cnt
28833         local fid1
28834         local fid2
28835
28836         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28837                 skip "Need MDS version at least 2.12.54"
28838
28839         test_mkdir $DIR/$tdir
28840         createmany -o $DIR/$tdir/f 3
28841         cnt=$(ls -1 $DIR/$tdir | wc -l)
28842         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28843
28844         fid1=$(lfs path2fid $DIR/$tdir/f1)
28845         fid2=$(lfs path2fid $DIR/$tdir/f2)
28846         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28847
28848         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28849         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28850
28851         cnt=$(ls -1 $DIR/$tdir | wc -l)
28852         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28853
28854         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28855         createmany -o $DIR/$tdir/f 3
28856         cnt=$(ls -1 $DIR/$tdir | wc -l)
28857         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28858
28859         fid1=$(lfs path2fid $DIR/$tdir/f1)
28860         fid2=$(lfs path2fid $DIR/$tdir/f2)
28861         echo "remove using fsname $FSNAME"
28862         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28863
28864         cnt=$(ls -1 $DIR/$tdir | wc -l)
28865         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28866 }
28867 run_test 421a "simple rm by fid"
28868
28869 test_421b() {
28870         local cnt
28871         local FID1
28872         local FID2
28873
28874         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28875                 skip "Need MDS version at least 2.12.54"
28876
28877         test_mkdir $DIR/$tdir
28878         createmany -o $DIR/$tdir/f 3
28879         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28880         MULTIPID=$!
28881
28882         FID1=$(lfs path2fid $DIR/$tdir/f1)
28883         FID2=$(lfs path2fid $DIR/$tdir/f2)
28884         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28885
28886         kill -USR1 $MULTIPID
28887         wait
28888
28889         cnt=$(ls $DIR/$tdir | wc -l)
28890         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28891 }
28892 run_test 421b "rm by fid on open file"
28893
28894 test_421c() {
28895         local cnt
28896         local FIDS
28897
28898         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28899                 skip "Need MDS version at least 2.12.54"
28900
28901         test_mkdir $DIR/$tdir
28902         createmany -o $DIR/$tdir/f 3
28903         touch $DIR/$tdir/$tfile
28904         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28905         cnt=$(ls -1 $DIR/$tdir | wc -l)
28906         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28907
28908         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28909         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28910
28911         cnt=$(ls $DIR/$tdir | wc -l)
28912         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
28913 }
28914 run_test 421c "rm by fid against hardlinked files"
28915
28916 test_421d() {
28917         local cnt
28918         local FIDS
28919
28920         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28921                 skip "Need MDS version at least 2.12.54"
28922
28923         test_mkdir $DIR/$tdir
28924         createmany -o $DIR/$tdir/f 4097
28925         cnt=$(ls -1 $DIR/$tdir | wc -l)
28926         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
28927
28928         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
28929         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28930
28931         cnt=$(ls $DIR/$tdir | wc -l)
28932         rm -rf $DIR/$tdir
28933         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28934 }
28935 run_test 421d "rmfid en masse"
28936
28937 test_421e() {
28938         local cnt
28939         local FID
28940
28941         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28942         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28943                 skip "Need MDS version at least 2.12.54"
28944
28945         mkdir -p $DIR/$tdir
28946         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
28947         createmany -o $DIR/$tdir/striped_dir/f 512
28948         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
28949         [ $cnt != 512 ] && error "unexpected #files: $cnt"
28950
28951         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
28952                 sed "s/[/][^:]*://g")
28953         $LFS rmfid $DIR $FIDS || error "rmfid failed"
28954
28955         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
28956         rm -rf $DIR/$tdir
28957         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
28958 }
28959 run_test 421e "rmfid in DNE"
28960
28961 test_421f() {
28962         local cnt
28963         local FID
28964
28965         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28966                 skip "Need MDS version at least 2.12.54"
28967
28968         test_mkdir $DIR/$tdir
28969         touch $DIR/$tdir/f
28970         cnt=$(ls -1 $DIR/$tdir | wc -l)
28971         [ $cnt != 1 ] && error "unexpected #files: $cnt"
28972
28973         FID=$(lfs path2fid $DIR/$tdir/f)
28974         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
28975         # rmfid should fail
28976         cnt=$(ls -1 $DIR/$tdir | wc -l)
28977         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
28978
28979         chmod a+rw $DIR/$tdir
28980         ls -la $DIR/$tdir
28981         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
28982         # rmfid should fail
28983         cnt=$(ls -1 $DIR/$tdir | wc -l)
28984         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
28985
28986         rm -f $DIR/$tdir/f
28987         $RUNAS touch $DIR/$tdir/f
28988         FID=$(lfs path2fid $DIR/$tdir/f)
28989         echo "rmfid as root"
28990         $LFS rmfid $DIR $FID || error "rmfid as root failed"
28991         cnt=$(ls -1 $DIR/$tdir | wc -l)
28992         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
28993
28994         rm -f $DIR/$tdir/f
28995         $RUNAS touch $DIR/$tdir/f
28996         cnt=$(ls -1 $DIR/$tdir | wc -l)
28997         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
28998         FID=$(lfs path2fid $DIR/$tdir/f)
28999         # rmfid w/o user_fid2path mount option should fail
29000         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29001         cnt=$(ls -1 $DIR/$tdir | wc -l)
29002         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29003
29004         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29005         stack_trap "rmdir $tmpdir"
29006         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29007                 error "failed to mount client'"
29008         stack_trap "umount_client $tmpdir"
29009
29010         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29011         # rmfid should succeed
29012         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29013         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29014
29015         # rmfid shouldn't allow to remove files due to dir's permission
29016         chmod a+rwx $tmpdir/$tdir
29017         touch $tmpdir/$tdir/f
29018         ls -la $tmpdir/$tdir
29019         FID=$(lfs path2fid $tmpdir/$tdir/f)
29020         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29021         return 0
29022 }
29023 run_test 421f "rmfid checks permissions"
29024
29025 test_421g() {
29026         local cnt
29027         local FIDS
29028
29029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29030         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29031                 skip "Need MDS version at least 2.12.54"
29032
29033         mkdir -p $DIR/$tdir
29034         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29035         createmany -o $DIR/$tdir/striped_dir/f 512
29036         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29037         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29038
29039         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29040                 sed "s/[/][^:]*://g")
29041
29042         rm -f $DIR/$tdir/striped_dir/f1*
29043         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29044         removed=$((512 - cnt))
29045
29046         # few files have been just removed, so we expect
29047         # rmfid to fail on their fids
29048         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29049         [ $removed != $errors ] && error "$errors != $removed"
29050
29051         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29052         rm -rf $DIR/$tdir
29053         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29054 }
29055 run_test 421g "rmfid to return errors properly"
29056
29057 test_421h() {
29058         local mount_other
29059         local mount_ret
29060         local rmfid_ret
29061         local old_fid
29062         local fidA
29063         local fidB
29064         local fidC
29065         local fidD
29066
29067         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29068                 skip "Need MDS version at least 2.15.53"
29069
29070         test_mkdir $DIR/$tdir
29071         test_mkdir $DIR/$tdir/subdir
29072         touch $DIR/$tdir/subdir/file0
29073         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29074         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29075         rm -f $DIR/$tdir/subdir/file0
29076         touch $DIR/$tdir/subdir/fileA
29077         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29078         echo File $DIR/$tdir/subdir/fileA FID $fidA
29079         touch $DIR/$tdir/subdir/fileB
29080         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29081         echo File $DIR/$tdir/subdir/fileB FID $fidB
29082         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29083         touch $DIR/$tdir/subdir/fileC
29084         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29085         echo File $DIR/$tdir/subdir/fileC FID $fidC
29086         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29087         touch $DIR/$tdir/fileD
29088         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29089         echo File $DIR/$tdir/fileD FID $fidD
29090
29091         # mount another client mount point with subdirectory mount
29092         export FILESET=/$tdir/subdir
29093         mount_other=${MOUNT}_other
29094         mount_client $mount_other ${MOUNT_OPTS}
29095         mount_ret=$?
29096         export FILESET=""
29097         (( mount_ret == 0 )) || error "mount $mount_other failed"
29098
29099         echo Removing FIDs:
29100         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29101         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29102         rmfid_ret=$?
29103
29104         umount_client $mount_other || error "umount $mount_other failed"
29105
29106         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29107
29108         # fileA should have been deleted
29109         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29110
29111         # fileB should have been deleted
29112         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29113
29114         # fileC should not have been deleted, fid also exists outside of fileset
29115         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29116
29117         # fileD should not have been deleted, it exists outside of fileset
29118         stat $DIR/$tdir/fileD || error "fileD deleted"
29119 }
29120 run_test 421h "rmfid with fileset mount"
29121
29122 test_422() {
29123         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29124         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29125         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29126         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29127         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29128
29129         local amc=$(at_max_get client)
29130         local amo=$(at_max_get mds1)
29131         local timeout=`lctl get_param -n timeout`
29132
29133         at_max_set 0 client
29134         at_max_set 0 mds1
29135
29136 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29137         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29138                         fail_val=$(((2*timeout + 10)*1000))
29139         touch $DIR/$tdir/d3/file &
29140         sleep 2
29141 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29142         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29143                         fail_val=$((2*timeout + 5))
29144         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29145         local pid=$!
29146         sleep 1
29147         kill -9 $pid
29148         sleep $((2 * timeout))
29149         echo kill $pid
29150         kill -9 $pid
29151         lctl mark touch
29152         touch $DIR/$tdir/d2/file3
29153         touch $DIR/$tdir/d2/file4
29154         touch $DIR/$tdir/d2/file5
29155
29156         wait
29157         at_max_set $amc client
29158         at_max_set $amo mds1
29159
29160         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29161         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29162                 error "Watchdog is always throttled"
29163 }
29164 run_test 422 "kill a process with RPC in progress"
29165
29166 stat_test() {
29167     df -h $MOUNT &
29168     df -h $MOUNT &
29169     df -h $MOUNT &
29170     df -h $MOUNT &
29171     df -h $MOUNT &
29172     df -h $MOUNT &
29173 }
29174
29175 test_423() {
29176     local _stats
29177     # ensure statfs cache is expired
29178     sleep 2;
29179
29180     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29181     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29182
29183     return 0
29184 }
29185 run_test 423 "statfs should return a right data"
29186
29187 test_424() {
29188 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29189         $LCTL set_param fail_loc=0x80000522
29190         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29191         rm -f $DIR/$tfile
29192 }
29193 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29194
29195 test_425() {
29196         test_mkdir -c -1 $DIR/$tdir
29197         $LFS setstripe -c -1 $DIR/$tdir
29198
29199         lru_resize_disable "" 100
29200         stack_trap "lru_resize_enable" EXIT
29201
29202         sleep 5
29203
29204         for i in $(seq $((MDSCOUNT * 125))); do
29205                 local t=$DIR/$tdir/$tfile_$i
29206
29207                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29208                         error_noexit "Create file $t"
29209         done
29210         stack_trap "rm -rf $DIR/$tdir" EXIT
29211
29212         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29213                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29214                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29215
29216                 [ $lock_count -le $lru_size ] ||
29217                         error "osc lock count $lock_count > lru size $lru_size"
29218         done
29219
29220         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29221                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29222                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29223
29224                 [ $lock_count -le $lru_size ] ||
29225                         error "mdc lock count $lock_count > lru size $lru_size"
29226         done
29227 }
29228 run_test 425 "lock count should not exceed lru size"
29229
29230 test_426() {
29231         splice-test -r $DIR/$tfile
29232         splice-test -rd $DIR/$tfile
29233         splice-test $DIR/$tfile
29234         splice-test -d $DIR/$tfile
29235 }
29236 run_test 426 "splice test on Lustre"
29237
29238 test_427() {
29239         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29240         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29241                 skip "Need MDS version at least 2.12.4"
29242         local log
29243
29244         mkdir $DIR/$tdir
29245         mkdir $DIR/$tdir/1
29246         mkdir $DIR/$tdir/2
29247         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29248         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29249
29250         $LFS getdirstripe $DIR/$tdir/1/dir
29251
29252         #first setfattr for creating updatelog
29253         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29254
29255 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29256         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29257         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29258         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29259
29260         sleep 2
29261         fail mds2
29262         wait_recovery_complete mds2 $((2*TIMEOUT))
29263
29264         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29265         echo $log | grep "get update log failed" &&
29266                 error "update log corruption is detected" || true
29267 }
29268 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29269
29270 test_428() {
29271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29272         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29273                               awk '/^max_cached_mb/ { print $2 }')
29274         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29275
29276         $LCTL set_param -n llite.*.max_cached_mb=64
29277
29278         mkdir $DIR/$tdir
29279         $LFS setstripe -c 1 $DIR/$tdir
29280         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29281         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29282         #test write
29283         for f in $(seq 4); do
29284                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29285         done
29286         wait
29287
29288         cancel_lru_locks osc
29289         # Test read
29290         for f in $(seq 4); do
29291                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29292         done
29293         wait
29294 }
29295 run_test 428 "large block size IO should not hang"
29296
29297 test_429() { # LU-7915 / LU-10948
29298         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29299         local testfile=$DIR/$tfile
29300         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29301         local new_flag=1
29302         local first_rpc
29303         local second_rpc
29304         local third_rpc
29305
29306         $LCTL get_param $ll_opencache_threshold_count ||
29307                 skip "client does not have opencache parameter"
29308
29309         set_opencache $new_flag
29310         stack_trap "restore_opencache"
29311         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29312                 error "enable opencache failed"
29313         touch $testfile
29314         # drop MDC DLM locks
29315         cancel_lru_locks mdc
29316         # clear MDC RPC stats counters
29317         $LCTL set_param $mdc_rpcstats=clear
29318
29319         # According to the current implementation, we need to run 3 times
29320         # open & close file to verify if opencache is enabled correctly.
29321         # 1st, RPCs are sent for lookup/open and open handle is released on
29322         #      close finally.
29323         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29324         #      so open handle won't be released thereafter.
29325         # 3rd, No RPC is sent out.
29326         $MULTIOP $testfile oc || error "multiop failed"
29327         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29328         echo "1st: $first_rpc RPCs in flight"
29329
29330         $MULTIOP $testfile oc || error "multiop failed"
29331         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29332         echo "2nd: $second_rpc RPCs in flight"
29333
29334         $MULTIOP $testfile oc || error "multiop failed"
29335         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29336         echo "3rd: $third_rpc RPCs in flight"
29337
29338         #verify no MDC RPC is sent
29339         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29340 }
29341 run_test 429 "verify if opencache flag on client side does work"
29342
29343 lseek_test_430() {
29344         local offset
29345         local file=$1
29346
29347         # data at [200K, 400K)
29348         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29349                 error "256K->512K dd fails"
29350         # data at [2M, 3M)
29351         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29352                 error "2M->3M dd fails"
29353         # data at [4M, 5M)
29354         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29355                 error "4M->5M dd fails"
29356         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29357         # start at first component hole #1
29358         printf "Seeking hole from 1000 ... "
29359         offset=$(lseek_test -l 1000 $file)
29360         echo $offset
29361         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29362         printf "Seeking data from 1000 ... "
29363         offset=$(lseek_test -d 1000 $file)
29364         echo $offset
29365         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29366
29367         # start at first component data block
29368         printf "Seeking hole from 300000 ... "
29369         offset=$(lseek_test -l 300000 $file)
29370         echo $offset
29371         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29372         printf "Seeking data from 300000 ... "
29373         offset=$(lseek_test -d 300000 $file)
29374         echo $offset
29375         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29376
29377         # start at the first component but beyond end of object size
29378         printf "Seeking hole from 1000000 ... "
29379         offset=$(lseek_test -l 1000000 $file)
29380         echo $offset
29381         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29382         printf "Seeking data from 1000000 ... "
29383         offset=$(lseek_test -d 1000000 $file)
29384         echo $offset
29385         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29386
29387         # start at second component stripe 2 (empty file)
29388         printf "Seeking hole from 1500000 ... "
29389         offset=$(lseek_test -l 1500000 $file)
29390         echo $offset
29391         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29392         printf "Seeking data from 1500000 ... "
29393         offset=$(lseek_test -d 1500000 $file)
29394         echo $offset
29395         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29396
29397         # start at second component stripe 1 (all data)
29398         printf "Seeking hole from 3000000 ... "
29399         offset=$(lseek_test -l 3000000 $file)
29400         echo $offset
29401         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29402         printf "Seeking data from 3000000 ... "
29403         offset=$(lseek_test -d 3000000 $file)
29404         echo $offset
29405         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29406
29407         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29408                 error "2nd dd fails"
29409         echo "Add data block at 640K...1280K"
29410
29411         # start at before new data block, in hole
29412         printf "Seeking hole from 600000 ... "
29413         offset=$(lseek_test -l 600000 $file)
29414         echo $offset
29415         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29416         printf "Seeking data from 600000 ... "
29417         offset=$(lseek_test -d 600000 $file)
29418         echo $offset
29419         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29420
29421         # start at the first component new data block
29422         printf "Seeking hole from 1000000 ... "
29423         offset=$(lseek_test -l 1000000 $file)
29424         echo $offset
29425         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29426         printf "Seeking data from 1000000 ... "
29427         offset=$(lseek_test -d 1000000 $file)
29428         echo $offset
29429         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29430
29431         # start at second component stripe 2, new data
29432         printf "Seeking hole from 1200000 ... "
29433         offset=$(lseek_test -l 1200000 $file)
29434         echo $offset
29435         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29436         printf "Seeking data from 1200000 ... "
29437         offset=$(lseek_test -d 1200000 $file)
29438         echo $offset
29439         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29440
29441         # start beyond file end
29442         printf "Using offset > filesize ... "
29443         lseek_test -l 4000000 $file && error "lseek should fail"
29444         printf "Using offset > filesize ... "
29445         lseek_test -d 4000000 $file && error "lseek should fail"
29446
29447         printf "Done\n\n"
29448 }
29449
29450 test_430a() {
29451         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29452                 skip "MDT does not support SEEK_HOLE"
29453
29454         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29455                 skip "OST does not support SEEK_HOLE"
29456
29457         local file=$DIR/$tdir/$tfile
29458
29459         mkdir -p $DIR/$tdir
29460
29461         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29462         # OST stripe #1 will have continuous data at [1M, 3M)
29463         # OST stripe #2 is empty
29464         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29465         lseek_test_430 $file
29466         rm $file
29467         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29468         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29469         lseek_test_430 $file
29470         rm $file
29471         $LFS setstripe -c2 -S 512K $file
29472         echo "Two stripes, stripe size 512K"
29473         lseek_test_430 $file
29474         rm $file
29475         # FLR with stale mirror
29476         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29477                        -N -c2 -S 1M $file
29478         echo "Mirrored file:"
29479         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29480         echo "Plain 2 stripes 1M"
29481         lseek_test_430 $file
29482         rm $file
29483 }
29484 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29485
29486 test_430b() {
29487         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29488                 skip "OST does not support SEEK_HOLE"
29489
29490         local offset
29491         local file=$DIR/$tdir/$tfile
29492
29493         mkdir -p $DIR/$tdir
29494         # Empty layout lseek should fail
29495         $MCREATE $file
29496         # seek from 0
29497         printf "Seeking hole from 0 ... "
29498         lseek_test -l 0 $file && error "lseek should fail"
29499         printf "Seeking data from 0 ... "
29500         lseek_test -d 0 $file && error "lseek should fail"
29501         rm $file
29502
29503         # 1M-hole file
29504         $LFS setstripe -E 1M -c2 -E eof $file
29505         $TRUNCATE $file 1048576
29506         printf "Seeking hole from 1000000 ... "
29507         offset=$(lseek_test -l 1000000 $file)
29508         echo $offset
29509         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29510         printf "Seeking data from 1000000 ... "
29511         lseek_test -d 1000000 $file && error "lseek should fail"
29512         rm $file
29513
29514         # full component followed by non-inited one
29515         $LFS setstripe -E 1M -c2 -E eof $file
29516         dd if=/dev/urandom of=$file bs=1M count=1
29517         printf "Seeking hole from 1000000 ... "
29518         offset=$(lseek_test -l 1000000 $file)
29519         echo $offset
29520         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29521         printf "Seeking hole from 1048576 ... "
29522         lseek_test -l 1048576 $file && error "lseek should fail"
29523         # init second component and truncate back
29524         echo "123" >> $file
29525         $TRUNCATE $file 1048576
29526         printf "Seeking hole from 1000000 ... "
29527         offset=$(lseek_test -l 1000000 $file)
29528         echo $offset
29529         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29530         printf "Seeking hole from 1048576 ... "
29531         lseek_test -l 1048576 $file && error "lseek should fail"
29532         # boundary checks for big values
29533         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29534         offset=$(lseek_test -d 0 $file.10g)
29535         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29536         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29537         offset=$(lseek_test -d 0 $file.100g)
29538         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29539         return 0
29540 }
29541 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29542
29543 test_430c() {
29544         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29545                 skip "OST does not support SEEK_HOLE"
29546
29547         local file=$DIR/$tdir/$tfile
29548         local start
29549
29550         mkdir -p $DIR/$tdir
29551         stack_trap "rm -f $file $file.tmp"
29552         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29553
29554         # cp version 8.33+ prefers lseek over fiemap
29555         local ver=$(cp --version | awk '{ print $4; exit; }')
29556
29557         echo "cp $ver installed"
29558         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29559                 start=$SECONDS
29560                 time cp -v $file $file.tmp || error "cp $file failed"
29561                 (( SECONDS - start < 5 )) || {
29562                         strace cp $file $file.tmp |&
29563                                 grep -E "open|read|seek|FIEMAP" |
29564                                 grep -A 100 $file
29565                         error "cp: too long runtime $((SECONDS - start))"
29566                 }
29567         else
29568                 echo "cp test skipped due to $ver < 8.33"
29569         fi
29570
29571         # tar version 1.29+ supports SEEK_HOLE/DATA
29572         ver=$(tar --version | awk '{ print $4; exit; }')
29573         echo "tar $ver installed"
29574         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29575                 start=$SECONDS
29576                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29577                 (( SECONDS - start < 5 )) || {
29578                         strace tar cf $file.tmp --sparse $file |&
29579                                 grep -E "open|read|seek|FIEMAP" |
29580                                 grep -A 100 $file
29581                         error "tar: too long runtime $((SECONDS - start))"
29582                 }
29583         else
29584                 echo "tar test skipped due to $ver < 1.29"
29585         fi
29586 }
29587 run_test 430c "lseek: external tools check"
29588
29589 test_431() { # LU-14187
29590         local file=$DIR/$tdir/$tfile
29591
29592         mkdir -p $DIR/$tdir
29593         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29594         dd if=/dev/urandom of=$file bs=4k count=1
29595         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29596         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29597         #define OBD_FAIL_OST_RESTART_IO 0x251
29598         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29599         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29600         cp $file $file.0
29601         cancel_lru_locks
29602         sync_all_data
29603         echo 3 > /proc/sys/vm/drop_caches
29604         diff  $file $file.0 || error "data diff"
29605 }
29606 run_test 431 "Restart transaction for IO"
29607
29608 cleanup_test_432() {
29609         do_facet mgs $LCTL nodemap_activate 0
29610         wait_nm_sync active
29611 }
29612
29613 test_432() {
29614         local tmpdir=$TMP/dir432
29615
29616         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29617                 skip "Need MDS version at least 2.14.52"
29618
29619         stack_trap cleanup_test_432 EXIT
29620         mkdir $DIR/$tdir
29621         mkdir $tmpdir
29622
29623         do_facet mgs $LCTL nodemap_activate 1
29624         wait_nm_sync active
29625         do_facet mgs $LCTL nodemap_modify --name default \
29626                 --property admin --value 1
29627         do_facet mgs $LCTL nodemap_modify --name default \
29628                 --property trusted --value 1
29629         cancel_lru_locks mdc
29630         wait_nm_sync default admin_nodemap
29631         wait_nm_sync default trusted_nodemap
29632
29633         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29634                grep -ci "Operation not permitted") -ne 0 ]; then
29635                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29636         fi
29637 }
29638 run_test 432 "mv dir from outside Lustre"
29639
29640 test_433() {
29641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29642
29643         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29644                 skip "inode cache not supported"
29645
29646         $LCTL set_param llite.*.inode_cache=0
29647         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29648
29649         local count=256
29650         local before
29651         local after
29652
29653         cancel_lru_locks mdc
29654         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29655         createmany -m $DIR/$tdir/f $count
29656         createmany -d $DIR/$tdir/d $count
29657         ls -l $DIR/$tdir > /dev/null
29658         stack_trap "rm -rf $DIR/$tdir"
29659
29660         before=$(num_objects)
29661         cancel_lru_locks mdc
29662         after=$(num_objects)
29663
29664         # sometimes even @before is less than 2 * count
29665         while (( before - after < count )); do
29666                 sleep 1
29667                 after=$(num_objects)
29668                 wait=$((wait + 1))
29669                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29670                 if (( wait > 60 )); then
29671                         error "inode slab grew from $before to $after"
29672                 fi
29673         done
29674
29675         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29676 }
29677 run_test 433 "ldlm lock cancel releases dentries and inodes"
29678
29679 test_434() {
29680         local file
29681         local getxattr_count
29682         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29683         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29684
29685         [[ $(getenforce) == "Disabled" ]] ||
29686                 skip "lsm selinux module have to be disabled for this test"
29687
29688         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29689                 error "fail to create $DIR/$tdir/ on MDT0000"
29690
29691         touch $DIR/$tdir/$tfile-{001..100}
29692
29693         # disable the xattr cache
29694         save_lustre_params client "llite.*.xattr_cache" > $p
29695         lctl set_param llite.*.xattr_cache=0
29696         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29697
29698         # clear clients mdc stats
29699         clear_stats $mdc_stat_param ||
29700                 error "fail to clear stats on mdc MDT0000"
29701
29702         for file in $DIR/$tdir/$tfile-{001..100}; do
29703                 getfattr -n security.selinux $file |&
29704                         grep -q "Operation not supported" ||
29705                         error "getxattr on security.selinux should return EOPNOTSUPP"
29706         done
29707
29708         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29709         (( getxattr_count < 100 )) ||
29710                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29711 }
29712 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29713
29714 test_440() {
29715         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29716                 source $LUSTRE/scripts/bash-completion/lustre
29717         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29718                 source /usr/share/bash-completion/completions/lustre
29719         else
29720                 skip "bash completion scripts not found"
29721         fi
29722
29723         local lctl_completions
29724         local lfs_completions
29725
29726         lctl_completions=$(_lustre_cmds lctl)
29727         if [[ ! $lctl_completions =~ "get_param" ]]; then
29728                 error "lctl bash completion failed"
29729         fi
29730
29731         lfs_completions=$(_lustre_cmds lfs)
29732         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29733                 error "lfs bash completion failed"
29734         fi
29735 }
29736 run_test 440 "bash completion for lfs, lctl"
29737
29738 prep_801() {
29739         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29740         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29741                 skip "Need server version at least 2.9.55"
29742
29743         start_full_debug_logging
29744 }
29745
29746 post_801() {
29747         stop_full_debug_logging
29748 }
29749
29750 barrier_stat() {
29751         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29752                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29753                            awk '/The barrier for/ { print $7 }')
29754                 echo $st
29755         else
29756                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29757                 echo \'$st\'
29758         fi
29759 }
29760
29761 barrier_expired() {
29762         local expired
29763
29764         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29765                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29766                           awk '/will be expired/ { print $7 }')
29767         else
29768                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29769         fi
29770
29771         echo $expired
29772 }
29773
29774 test_801a() {
29775         prep_801
29776
29777         echo "Start barrier_freeze at: $(date)"
29778         #define OBD_FAIL_BARRIER_DELAY          0x2202
29779         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29780         # Do not reduce barrier time - See LU-11873
29781         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29782
29783         sleep 2
29784         local b_status=$(barrier_stat)
29785         echo "Got barrier status at: $(date)"
29786         [ "$b_status" = "'freezing_p1'" ] ||
29787                 error "(1) unexpected barrier status $b_status"
29788
29789         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29790         wait
29791         b_status=$(barrier_stat)
29792         [ "$b_status" = "'frozen'" ] ||
29793                 error "(2) unexpected barrier status $b_status"
29794
29795         local expired=$(barrier_expired)
29796         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29797         sleep $((expired + 3))
29798
29799         b_status=$(barrier_stat)
29800         [ "$b_status" = "'expired'" ] ||
29801                 error "(3) unexpected barrier status $b_status"
29802
29803         # Do not reduce barrier time - See LU-11873
29804         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29805                 error "(4) fail to freeze barrier"
29806
29807         b_status=$(barrier_stat)
29808         [ "$b_status" = "'frozen'" ] ||
29809                 error "(5) unexpected barrier status $b_status"
29810
29811         echo "Start barrier_thaw at: $(date)"
29812         #define OBD_FAIL_BARRIER_DELAY          0x2202
29813         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29814         do_facet mgs $LCTL barrier_thaw $FSNAME &
29815
29816         sleep 2
29817         b_status=$(barrier_stat)
29818         echo "Got barrier status at: $(date)"
29819         [ "$b_status" = "'thawing'" ] ||
29820                 error "(6) unexpected barrier status $b_status"
29821
29822         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29823         wait
29824         b_status=$(barrier_stat)
29825         [ "$b_status" = "'thawed'" ] ||
29826                 error "(7) unexpected barrier status $b_status"
29827
29828         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29829         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29830         do_facet mgs $LCTL barrier_freeze $FSNAME
29831
29832         b_status=$(barrier_stat)
29833         [ "$b_status" = "'failed'" ] ||
29834                 error "(8) unexpected barrier status $b_status"
29835
29836         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29837         do_facet mgs $LCTL barrier_thaw $FSNAME
29838
29839         post_801
29840 }
29841 run_test 801a "write barrier user interfaces and stat machine"
29842
29843 test_801b() {
29844         prep_801
29845
29846         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29847         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29848         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29849         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29850         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29851
29852         cancel_lru_locks mdc
29853
29854         # 180 seconds should be long enough
29855         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29856
29857         local b_status=$(barrier_stat)
29858         [ "$b_status" = "'frozen'" ] ||
29859                 error "(6) unexpected barrier status $b_status"
29860
29861         mkdir $DIR/$tdir/d0/d10 &
29862         mkdir_pid=$!
29863
29864         touch $DIR/$tdir/d1/f13 &
29865         touch_pid=$!
29866
29867         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29868         ln_pid=$!
29869
29870         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29871         mv_pid=$!
29872
29873         rm -f $DIR/$tdir/d4/f12 &
29874         rm_pid=$!
29875
29876         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29877
29878         # To guarantee taht the 'stat' is not blocked
29879         b_status=$(barrier_stat)
29880         [ "$b_status" = "'frozen'" ] ||
29881                 error "(8) unexpected barrier status $b_status"
29882
29883         # let above commands to run at background
29884         sleep 5
29885
29886         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29887         ps -p $touch_pid || error "(10) touch should be blocked"
29888         ps -p $ln_pid || error "(11) link should be blocked"
29889         ps -p $mv_pid || error "(12) rename should be blocked"
29890         ps -p $rm_pid || error "(13) unlink should be blocked"
29891
29892         b_status=$(barrier_stat)
29893         [ "$b_status" = "'frozen'" ] ||
29894                 error "(14) unexpected barrier status $b_status"
29895
29896         do_facet mgs $LCTL barrier_thaw $FSNAME
29897         b_status=$(barrier_stat)
29898         [ "$b_status" = "'thawed'" ] ||
29899                 error "(15) unexpected barrier status $b_status"
29900
29901         wait $mkdir_pid || error "(16) mkdir should succeed"
29902         wait $touch_pid || error "(17) touch should succeed"
29903         wait $ln_pid || error "(18) link should succeed"
29904         wait $mv_pid || error "(19) rename should succeed"
29905         wait $rm_pid || error "(20) unlink should succeed"
29906
29907         post_801
29908 }
29909 run_test 801b "modification will be blocked by write barrier"
29910
29911 test_801c() {
29912         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29913
29914         prep_801
29915
29916         stop mds2 || error "(1) Fail to stop mds2"
29917
29918         do_facet mgs $LCTL barrier_freeze $FSNAME 30
29919
29920         local b_status=$(barrier_stat)
29921         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
29922                 do_facet mgs $LCTL barrier_thaw $FSNAME
29923                 error "(2) unexpected barrier status $b_status"
29924         }
29925
29926         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29927                 error "(3) Fail to rescan barrier bitmap"
29928
29929         # Do not reduce barrier time - See LU-11873
29930         do_facet mgs $LCTL barrier_freeze $FSNAME 20
29931
29932         b_status=$(barrier_stat)
29933         [ "$b_status" = "'frozen'" ] ||
29934                 error "(4) unexpected barrier status $b_status"
29935
29936         do_facet mgs $LCTL barrier_thaw $FSNAME
29937         b_status=$(barrier_stat)
29938         [ "$b_status" = "'thawed'" ] ||
29939                 error "(5) unexpected barrier status $b_status"
29940
29941         local devname=$(mdsdevname 2)
29942
29943         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
29944
29945         do_facet mgs $LCTL barrier_rescan $FSNAME ||
29946                 error "(7) Fail to rescan barrier bitmap"
29947
29948         post_801
29949 }
29950 run_test 801c "rescan barrier bitmap"
29951
29952 test_802b() {
29953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29954         remote_mds_nodsh && skip "remote MDS with nodsh"
29955
29956         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
29957                 skip "readonly option not available"
29958
29959         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
29960
29961         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
29962                 error "(2) Fail to copy"
29963
29964         # write back all cached data before setting MDT to readonly
29965         cancel_lru_locks
29966         sync_all_data
29967
29968         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
29969         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
29970
29971         echo "Modify should be refused"
29972         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
29973
29974         echo "Read should be allowed"
29975         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
29976                 error "(7) Read should succeed under ro mode"
29977
29978         # disable readonly
29979         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
29980 }
29981 run_test 802b "be able to set MDTs to readonly"
29982
29983 test_803a() {
29984         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29985         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
29986                 skip "MDS needs to be newer than 2.10.54"
29987
29988         mkdir_on_mdt0 $DIR/$tdir
29989         # Create some objects on all MDTs to trigger related logs objects
29990         for idx in $(seq $MDSCOUNT); do
29991                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
29992                         $DIR/$tdir/dir${idx} ||
29993                         error "Fail to create $DIR/$tdir/dir${idx}"
29994         done
29995
29996         wait_delete_completed # ensure old test cleanups are finished
29997         sleep 3
29998         echo "before create:"
29999         $LFS df -i $MOUNT
30000         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30001
30002         for i in {1..10}; do
30003                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30004                         error "Fail to create $DIR/$tdir/foo$i"
30005         done
30006
30007         # sync ZFS-on-MDS to refresh statfs data
30008         wait_zfs_commit mds1
30009         sleep 3
30010         echo "after create:"
30011         $LFS df -i $MOUNT
30012         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30013
30014         # allow for an llog to be cleaned up during the test
30015         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30016                 error "before ($before_used) + 10 > after ($after_used)"
30017
30018         for i in {1..10}; do
30019                 rm -rf $DIR/$tdir/foo$i ||
30020                         error "Fail to remove $DIR/$tdir/foo$i"
30021         done
30022
30023         # sync ZFS-on-MDS to refresh statfs data
30024         wait_zfs_commit mds1
30025         wait_delete_completed
30026         sleep 3 # avoid MDT return cached statfs
30027         echo "after unlink:"
30028         $LFS df -i $MOUNT
30029         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30030
30031         # allow for an llog to be created during the test
30032         [ $after_used -le $((before_used + 1)) ] ||
30033                 error "after ($after_used) > before ($before_used) + 1"
30034 }
30035 run_test 803a "verify agent object for remote object"
30036
30037 test_803b() {
30038         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30039         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30040                 skip "MDS needs to be newer than 2.13.56"
30041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30042
30043         for i in $(seq 0 $((MDSCOUNT - 1))); do
30044                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30045         done
30046
30047         local before=0
30048         local after=0
30049
30050         local tmp
30051
30052         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30053         for i in $(seq 0 $((MDSCOUNT - 1))); do
30054                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30055                         awk '/getattr/ { print $2 }')
30056                 before=$((before + tmp))
30057         done
30058         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30059         for i in $(seq 0 $((MDSCOUNT - 1))); do
30060                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30061                         awk '/getattr/ { print $2 }')
30062                 after=$((after + tmp))
30063         done
30064
30065         [ $before -eq $after ] || error "getattr count $before != $after"
30066 }
30067 run_test 803b "remote object can getattr from cache"
30068
30069 test_804() {
30070         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30071         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30072                 skip "MDS needs to be newer than 2.10.54"
30073         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30074
30075         mkdir -p $DIR/$tdir
30076         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30077                 error "Fail to create $DIR/$tdir/dir0"
30078
30079         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30080         local dev=$(mdsdevname 2)
30081
30082         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30083                 grep ${fid} || error "NOT found agent entry for dir0"
30084
30085         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30086                 error "Fail to create $DIR/$tdir/dir1"
30087
30088         touch $DIR/$tdir/dir1/foo0 ||
30089                 error "Fail to create $DIR/$tdir/dir1/foo0"
30090         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30091         local rc=0
30092
30093         for idx in $(seq $MDSCOUNT); do
30094                 dev=$(mdsdevname $idx)
30095                 do_facet mds${idx} \
30096                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30097                         grep ${fid} && rc=$idx
30098         done
30099
30100         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30101                 error "Fail to rename foo0 to foo1"
30102         if [ $rc -eq 0 ]; then
30103                 for idx in $(seq $MDSCOUNT); do
30104                         dev=$(mdsdevname $idx)
30105                         do_facet mds${idx} \
30106                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30107                         grep ${fid} && rc=$idx
30108                 done
30109         fi
30110
30111         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30112                 error "Fail to rename foo1 to foo2"
30113         if [ $rc -eq 0 ]; then
30114                 for idx in $(seq $MDSCOUNT); do
30115                         dev=$(mdsdevname $idx)
30116                         do_facet mds${idx} \
30117                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30118                         grep ${fid} && rc=$idx
30119                 done
30120         fi
30121
30122         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30123
30124         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30125                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30126         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30127                 error "Fail to rename foo2 to foo0"
30128         unlink $DIR/$tdir/dir1/foo0 ||
30129                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30130         rm -rf $DIR/$tdir/dir0 ||
30131                 error "Fail to rm $DIR/$tdir/dir0"
30132
30133         for idx in $(seq $MDSCOUNT); do
30134                 rc=0
30135
30136                 stop mds${idx}
30137                 dev=$(mdsdevname $idx)
30138                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30139                         rc=$?
30140                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30141                         error "mount mds$idx failed"
30142                 df $MOUNT > /dev/null 2>&1
30143
30144                 # e2fsck should not return error
30145                 [ $rc -eq 0 ] ||
30146                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30147         done
30148 }
30149 run_test 804 "verify agent entry for remote entry"
30150
30151 cleanup_805() {
30152         do_facet $SINGLEMDS zfs set quota=$old $fsset
30153         unlinkmany $DIR/$tdir/f- 1000000
30154         trap 0
30155 }
30156
30157 test_805() {
30158         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30159         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30160         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30161                 skip "netfree not implemented before 0.7"
30162         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30163                 skip "Need MDS version at least 2.10.57"
30164
30165         local fsset
30166         local freekb
30167         local usedkb
30168         local old
30169         local quota
30170         local pref="osd-zfs.$FSNAME-MDT0000."
30171
30172         # limit available space on MDS dataset to meet nospace issue
30173         # quickly. then ZFS 0.7.2 can use reserved space if asked
30174         # properly (using netfree flag in osd_declare_destroy()
30175         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30176         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30177                 gawk '{print $3}')
30178         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30179         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30180         let "usedkb=usedkb-freekb"
30181         let "freekb=freekb/2"
30182         if let "freekb > 5000"; then
30183                 let "freekb=5000"
30184         fi
30185         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30186         trap cleanup_805 EXIT
30187         mkdir_on_mdt0 $DIR/$tdir
30188         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30189                 error "Can't set PFL layout"
30190         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30191         rm -rf $DIR/$tdir || error "not able to remove"
30192         do_facet $SINGLEMDS zfs set quota=$old $fsset
30193         trap 0
30194 }
30195 run_test 805 "ZFS can remove from full fs"
30196
30197 # Size-on-MDS test
30198 check_lsom_data()
30199 {
30200         local file=$1
30201         local expect=$(stat -c %s $file)
30202
30203         check_lsom_size $1 $expect
30204
30205         local blocks=$($LFS getsom -b $file)
30206         expect=$(stat -c %b $file)
30207         [[ $blocks == $expect ]] ||
30208                 error "$file expected blocks: $expect, got: $blocks"
30209 }
30210
30211 check_lsom_size()
30212 {
30213         local size
30214         local expect=$2
30215
30216         cancel_lru_locks mdc
30217
30218         size=$($LFS getsom -s $1)
30219         [[ $size == $expect ]] ||
30220                 error "$file expected size: $expect, got: $size"
30221 }
30222
30223 test_806() {
30224         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30225                 skip "Need MDS version at least 2.11.52"
30226
30227         local bs=1048576
30228
30229         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30230
30231         disable_opencache
30232         stack_trap "restore_opencache"
30233
30234         # single-threaded write
30235         echo "Test SOM for single-threaded write"
30236         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30237                 error "write $tfile failed"
30238         check_lsom_size $DIR/$tfile $bs
30239
30240         local num=32
30241         local size=$(($num * $bs))
30242         local offset=0
30243         local i
30244
30245         echo "Test SOM for single client multi-threaded($num) write"
30246         $TRUNCATE $DIR/$tfile 0
30247         for ((i = 0; i < $num; i++)); do
30248                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30249                 local pids[$i]=$!
30250                 offset=$((offset + $bs))
30251         done
30252         for (( i=0; i < $num; i++ )); do
30253                 wait ${pids[$i]}
30254         done
30255         check_lsom_size $DIR/$tfile $size
30256
30257         $TRUNCATE $DIR/$tfile 0
30258         for ((i = 0; i < $num; i++)); do
30259                 offset=$((offset - $bs))
30260                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30261                 local pids[$i]=$!
30262         done
30263         for (( i=0; i < $num; i++ )); do
30264                 wait ${pids[$i]}
30265         done
30266         check_lsom_size $DIR/$tfile $size
30267
30268         # multi-client writes
30269         num=$(get_node_count ${CLIENTS//,/ })
30270         size=$(($num * $bs))
30271         offset=0
30272         i=0
30273
30274         echo "Test SOM for multi-client ($num) writes"
30275         $TRUNCATE $DIR/$tfile 0
30276         for client in ${CLIENTS//,/ }; do
30277                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30278                 local pids[$i]=$!
30279                 i=$((i + 1))
30280                 offset=$((offset + $bs))
30281         done
30282         for (( i=0; i < $num; i++ )); do
30283                 wait ${pids[$i]}
30284         done
30285         check_lsom_size $DIR/$tfile $offset
30286
30287         i=0
30288         $TRUNCATE $DIR/$tfile 0
30289         for client in ${CLIENTS//,/ }; do
30290                 offset=$((offset - $bs))
30291                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30292                 local pids[$i]=$!
30293                 i=$((i + 1))
30294         done
30295         for (( i=0; i < $num; i++ )); do
30296                 wait ${pids[$i]}
30297         done
30298         check_lsom_size $DIR/$tfile $size
30299
30300         # verify SOM blocks count
30301         echo "Verify SOM block count"
30302         $TRUNCATE $DIR/$tfile 0
30303         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30304                 error "failed to write file $tfile with fdatasync and fstat"
30305         check_lsom_data $DIR/$tfile
30306
30307         $TRUNCATE $DIR/$tfile 0
30308         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30309                 error "failed to write file $tfile with fdatasync"
30310         check_lsom_data $DIR/$tfile
30311
30312         $TRUNCATE $DIR/$tfile 0
30313         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30314                 error "failed to write file $tfile with sync IO"
30315         check_lsom_data $DIR/$tfile
30316
30317         # verify truncate
30318         echo "Test SOM for truncate"
30319         # use ftruncate to sync blocks on close request
30320         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30321         check_lsom_size $DIR/$tfile 16384
30322         check_lsom_data $DIR/$tfile
30323
30324         $TRUNCATE $DIR/$tfile 1234
30325         check_lsom_size $DIR/$tfile 1234
30326         # sync blocks on the MDT
30327         $MULTIOP $DIR/$tfile oc
30328         check_lsom_data $DIR/$tfile
30329 }
30330 run_test 806 "Verify Lazy Size on MDS"
30331
30332 test_807() {
30333         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30335                 skip "Need MDS version at least 2.11.52"
30336
30337         # Registration step
30338         changelog_register || error "changelog_register failed"
30339         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30340         changelog_users $SINGLEMDS | grep -q $cl_user ||
30341                 error "User $cl_user not found in changelog_users"
30342
30343         rm -rf $DIR/$tdir || error "rm $tdir failed"
30344         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30345         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30346         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30347         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30348                 error "truncate $tdir/trunc failed"
30349
30350         local bs=1048576
30351         echo "Test SOM for single-threaded write with fsync"
30352         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30353                 error "write $tfile failed"
30354         sync;sync;sync
30355
30356         # multi-client wirtes
30357         local num=$(get_node_count ${CLIENTS//,/ })
30358         local offset=0
30359         local i=0
30360
30361         echo "Test SOM for multi-client ($num) writes"
30362         touch $DIR/$tfile || error "touch $tfile failed"
30363         $TRUNCATE $DIR/$tfile 0
30364         for client in ${CLIENTS//,/ }; do
30365                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30366                 local pids[$i]=$!
30367                 i=$((i + 1))
30368                 offset=$((offset + $bs))
30369         done
30370         for (( i=0; i < $num; i++ )); do
30371                 wait ${pids[$i]}
30372         done
30373
30374         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30375         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30376         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30377         check_lsom_data $DIR/$tdir/trunc
30378         check_lsom_data $DIR/$tdir/single_dd
30379         check_lsom_data $DIR/$tfile
30380
30381         rm -rf $DIR/$tdir
30382         # Deregistration step
30383         changelog_deregister || error "changelog_deregister failed"
30384 }
30385 run_test 807 "verify LSOM syncing tool"
30386
30387 check_som_nologged()
30388 {
30389         local lines=$($LFS changelog $FSNAME-MDT0000 |
30390                 grep 'x=trusted.som' | wc -l)
30391         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30392 }
30393
30394 test_808() {
30395         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30396                 skip "Need MDS version at least 2.11.55"
30397
30398         # Registration step
30399         changelog_register || error "changelog_register failed"
30400
30401         touch $DIR/$tfile || error "touch $tfile failed"
30402         check_som_nologged
30403
30404         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30405                 error "write $tfile failed"
30406         check_som_nologged
30407
30408         $TRUNCATE $DIR/$tfile 1234
30409         check_som_nologged
30410
30411         $TRUNCATE $DIR/$tfile 1048576
30412         check_som_nologged
30413
30414         # Deregistration step
30415         changelog_deregister || error "changelog_deregister failed"
30416 }
30417 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30418
30419 check_som_nodata()
30420 {
30421         $LFS getsom $1
30422         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30423 }
30424
30425 test_809() {
30426         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30427                 skip "Need MDS version at least 2.11.56"
30428
30429         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30430                 error "failed to create DoM-only file $DIR/$tfile"
30431         touch $DIR/$tfile || error "touch $tfile failed"
30432         check_som_nodata $DIR/$tfile
30433
30434         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30435                 error "write $tfile failed"
30436         check_som_nodata $DIR/$tfile
30437
30438         $TRUNCATE $DIR/$tfile 1234
30439         check_som_nodata $DIR/$tfile
30440
30441         $TRUNCATE $DIR/$tfile 4097
30442         check_som_nodata $DIR/$file
30443 }
30444 run_test 809 "Verify no SOM xattr store for DoM-only files"
30445
30446 test_810() {
30447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30448         $GSS && skip_env "could not run with gss"
30449         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30450                 skip "OST < 2.12.58 doesn't align checksum"
30451
30452         set_checksums 1
30453         stack_trap "set_checksums $ORIG_CSUM" EXIT
30454         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30455
30456         local csum
30457         local before
30458         local after
30459         for csum in $CKSUM_TYPES; do
30460                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30461                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30462                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30463                         eval set -- $i
30464                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30465                         before=$(md5sum $DIR/$tfile)
30466                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30467                         after=$(md5sum $DIR/$tfile)
30468                         [ "$before" == "$after" ] ||
30469                                 error "$csum: $before != $after bs=$1 seek=$2"
30470                 done
30471         done
30472 }
30473 run_test 810 "partial page writes on ZFS (LU-11663)"
30474
30475 test_812a() {
30476         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30477                 skip "OST < 2.12.51 doesn't support this fail_loc"
30478
30479         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30480         # ensure ost1 is connected
30481         stat $DIR/$tfile >/dev/null || error "can't stat"
30482         wait_osc_import_state client ost1 FULL
30483         # no locks, no reqs to let the connection idle
30484         cancel_lru_locks osc
30485
30486         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30487 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30488         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30489         wait_osc_import_state client ost1 CONNECTING
30490         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30491
30492         stat $DIR/$tfile >/dev/null || error "can't stat file"
30493 }
30494 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30495
30496 test_812b() { # LU-12378
30497         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30498                 skip "OST < 2.12.51 doesn't support this fail_loc"
30499
30500         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30501         # ensure ost1 is connected
30502         stat $DIR/$tfile >/dev/null || error "can't stat"
30503         wait_osc_import_state client ost1 FULL
30504         # no locks, no reqs to let the connection idle
30505         cancel_lru_locks osc
30506
30507         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30508 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30509         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30510         wait_osc_import_state client ost1 CONNECTING
30511         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30512
30513         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30514         wait_osc_import_state client ost1 IDLE
30515 }
30516 run_test 812b "do not drop no resend request for idle connect"
30517
30518 test_812c() {
30519         local old
30520
30521         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30522
30523         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30524         $LFS getstripe $DIR/$tfile
30525         $LCTL set_param osc.*.idle_timeout=10
30526         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30527         # ensure ost1 is connected
30528         stat $DIR/$tfile >/dev/null || error "can't stat"
30529         wait_osc_import_state client ost1 FULL
30530         # no locks, no reqs to let the connection idle
30531         cancel_lru_locks osc
30532
30533 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30534         $LCTL set_param fail_loc=0x80000533
30535         sleep 15
30536         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30537 }
30538 run_test 812c "idle import vs lock enqueue race"
30539
30540 test_813() {
30541         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30542         [ -z "$file_heat_sav" ] && skip "no file heat support"
30543
30544         local readsample
30545         local writesample
30546         local readbyte
30547         local writebyte
30548         local readsample1
30549         local writesample1
30550         local readbyte1
30551         local writebyte1
30552
30553         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30554         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30555
30556         $LCTL set_param -n llite.*.file_heat=1
30557         echo "Turn on file heat"
30558         echo "Period second: $period_second, Decay percentage: $decay_pct"
30559
30560         echo "QQQQ" > $DIR/$tfile
30561         echo "QQQQ" > $DIR/$tfile
30562         echo "QQQQ" > $DIR/$tfile
30563         cat $DIR/$tfile > /dev/null
30564         cat $DIR/$tfile > /dev/null
30565         cat $DIR/$tfile > /dev/null
30566         cat $DIR/$tfile > /dev/null
30567
30568         local out=$($LFS heat_get $DIR/$tfile)
30569
30570         $LFS heat_get $DIR/$tfile
30571         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30572         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30573         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30574         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30575
30576         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30577         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30578         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30579         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30580
30581         sleep $((period_second + 3))
30582         echo "Sleep $((period_second + 3)) seconds..."
30583         # The recursion formula to calculate the heat of the file f is as
30584         # follow:
30585         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30586         # Where Hi is the heat value in the period between time points i*I and
30587         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30588         # to the weight of Ci.
30589         out=$($LFS heat_get $DIR/$tfile)
30590         $LFS heat_get $DIR/$tfile
30591         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30592         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30593         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30594         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30595
30596         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30597                 error "read sample ($readsample) is wrong"
30598         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30599                 error "write sample ($writesample) is wrong"
30600         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30601                 error "read bytes ($readbyte) is wrong"
30602         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30603                 error "write bytes ($writebyte) is wrong"
30604
30605         echo "QQQQ" > $DIR/$tfile
30606         echo "QQQQ" > $DIR/$tfile
30607         echo "QQQQ" > $DIR/$tfile
30608         cat $DIR/$tfile > /dev/null
30609         cat $DIR/$tfile > /dev/null
30610         cat $DIR/$tfile > /dev/null
30611         cat $DIR/$tfile > /dev/null
30612
30613         sleep $((period_second + 3))
30614         echo "Sleep $((period_second + 3)) seconds..."
30615
30616         out=$($LFS heat_get $DIR/$tfile)
30617         $LFS heat_get $DIR/$tfile
30618         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30619         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30620         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30621         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30622
30623         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30624                 4 * $decay_pct) / 100") -eq 1 ] ||
30625                 error "read sample ($readsample1) is wrong"
30626         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30627                 3 * $decay_pct) / 100") -eq 1 ] ||
30628                 error "write sample ($writesample1) is wrong"
30629         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30630                 20 * $decay_pct) / 100") -eq 1 ] ||
30631                 error "read bytes ($readbyte1) is wrong"
30632         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30633                 15 * $decay_pct) / 100") -eq 1 ] ||
30634                 error "write bytes ($writebyte1) is wrong"
30635
30636         echo "Turn off file heat for the file $DIR/$tfile"
30637         $LFS heat_set -o $DIR/$tfile
30638
30639         echo "QQQQ" > $DIR/$tfile
30640         echo "QQQQ" > $DIR/$tfile
30641         echo "QQQQ" > $DIR/$tfile
30642         cat $DIR/$tfile > /dev/null
30643         cat $DIR/$tfile > /dev/null
30644         cat $DIR/$tfile > /dev/null
30645         cat $DIR/$tfile > /dev/null
30646
30647         out=$($LFS heat_get $DIR/$tfile)
30648         $LFS heat_get $DIR/$tfile
30649         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30650         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30651         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30652         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30653
30654         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30655         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30656         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30657         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30658
30659         echo "Trun on file heat for the file $DIR/$tfile"
30660         $LFS heat_set -O $DIR/$tfile
30661
30662         echo "QQQQ" > $DIR/$tfile
30663         echo "QQQQ" > $DIR/$tfile
30664         echo "QQQQ" > $DIR/$tfile
30665         cat $DIR/$tfile > /dev/null
30666         cat $DIR/$tfile > /dev/null
30667         cat $DIR/$tfile > /dev/null
30668         cat $DIR/$tfile > /dev/null
30669
30670         out=$($LFS heat_get $DIR/$tfile)
30671         $LFS heat_get $DIR/$tfile
30672         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30673         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30674         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30675         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30676
30677         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30678         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30679         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30680         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30681
30682         $LFS heat_set -c $DIR/$tfile
30683         $LCTL set_param -n llite.*.file_heat=0
30684         echo "Turn off file heat support for the Lustre filesystem"
30685
30686         echo "QQQQ" > $DIR/$tfile
30687         echo "QQQQ" > $DIR/$tfile
30688         echo "QQQQ" > $DIR/$tfile
30689         cat $DIR/$tfile > /dev/null
30690         cat $DIR/$tfile > /dev/null
30691         cat $DIR/$tfile > /dev/null
30692         cat $DIR/$tfile > /dev/null
30693
30694         out=$($LFS heat_get $DIR/$tfile)
30695         $LFS heat_get $DIR/$tfile
30696         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30697         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30698         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30699         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30700
30701         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30702         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30703         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30704         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30705
30706         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30707         rm -f $DIR/$tfile
30708 }
30709 run_test 813 "File heat verfication"
30710
30711 test_814()
30712 {
30713         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30714         echo -n y >> $DIR/$tfile
30715         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30716         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30717 }
30718 run_test 814 "sparse cp works as expected (LU-12361)"
30719
30720 test_815()
30721 {
30722         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30723         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30724 }
30725 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30726
30727 test_816() {
30728         local ost1_imp=$(get_osc_import_name client ost1)
30729         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30730                          cut -d'.' -f2)
30731
30732         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30733         # ensure ost1 is connected
30734
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         lru_resize_disable osc
30740         local before
30741         local now
30742         before=$($LCTL get_param -n \
30743                  ldlm.namespaces.$imp_name.lru_size)
30744
30745         wait_osc_import_state client ost1 IDLE
30746         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30747         now=$($LCTL get_param -n \
30748               ldlm.namespaces.$imp_name.lru_size)
30749         [ $before == $now ] || error "lru_size changed $before != $now"
30750 }
30751 run_test 816 "do not reset lru_resize on idle reconnect"
30752
30753 cleanup_817() {
30754         umount $tmpdir
30755         exportfs -u localhost:$DIR/nfsexp
30756         rm -rf $DIR/nfsexp
30757 }
30758
30759 test_817() {
30760         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30761
30762         mkdir -p $DIR/nfsexp
30763         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30764                 error "failed to export nfs"
30765
30766         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30767         stack_trap cleanup_817 EXIT
30768
30769         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30770                 error "failed to mount nfs to $tmpdir"
30771
30772         cp /bin/true $tmpdir
30773         $DIR/nfsexp/true || error "failed to execute 'true' command"
30774 }
30775 run_test 817 "nfsd won't cache write lock for exec file"
30776
30777 test_818() {
30778         test_mkdir -i0 -c1 $DIR/$tdir
30779         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30780         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30781         stop $SINGLEMDS
30782
30783         # restore osp-syn threads
30784         stack_trap "fail $SINGLEMDS"
30785
30786         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30787         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30788         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30789                 error "start $SINGLEMDS failed"
30790         rm -rf $DIR/$tdir
30791
30792         local testid=$(echo $TESTNAME | tr '_' ' ')
30793
30794         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30795                 grep "run LFSCK" || error "run LFSCK is not suggested"
30796 }
30797 run_test 818 "unlink with failed llog"
30798
30799 test_819a() {
30800         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30801         cancel_lru_locks osc
30802         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30803         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30804         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30805         rm -f $TDIR/$tfile
30806 }
30807 run_test 819a "too big niobuf in read"
30808
30809 test_819b() {
30810         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30811         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30813         cancel_lru_locks osc
30814         sleep 1
30815         rm -f $TDIR/$tfile
30816 }
30817 run_test 819b "too big niobuf in write"
30818
30819
30820 function test_820_start_ost() {
30821         sleep 5
30822
30823         for num in $(seq $OSTCOUNT); do
30824                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30825         done
30826 }
30827
30828 test_820() {
30829         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30830
30831         mkdir $DIR/$tdir
30832         umount_client $MOUNT || error "umount failed"
30833         for num in $(seq $OSTCOUNT); do
30834                 stop ost$num
30835         done
30836
30837         # mount client with no active OSTs
30838         # so that the client can't initialize max LOV EA size
30839         # from OSC notifications
30840         mount_client $MOUNT || error "mount failed"
30841         # delay OST starting to keep this 0 max EA size for a while
30842         test_820_start_ost &
30843
30844         # create a directory on MDS2
30845         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30846                 error "Failed to create directory"
30847         # open intent should update default EA size
30848         # see mdc_update_max_ea_from_body()
30849         # notice this is the very first RPC to MDS2
30850         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30851         ret=$?
30852         echo $out
30853         # With SSK, this situation can lead to -EPERM being returned.
30854         # In that case, simply retry.
30855         if [ $ret -ne 0 ] && $SHARED_KEY; then
30856                 if echo "$out" | grep -q "not permitted"; then
30857                         cp /etc/services $DIR/$tdir/mds2
30858                         ret=$?
30859                 fi
30860         fi
30861         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30862 }
30863 run_test 820 "update max EA from open intent"
30864
30865 test_823() {
30866         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30867         local OST_MAX_PRECREATE=20000
30868
30869         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30870                 skip "Need MDS version at least 2.14.56"
30871
30872         save_lustre_params mds1 \
30873                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30874         do_facet $SINGLEMDS "$LCTL set_param -n \
30875                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30876         do_facet $SINGLEMDS "$LCTL set_param -n \
30877                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30878
30879         stack_trap "restore_lustre_params < $p; rm $p"
30880
30881         do_facet $SINGLEMDS "$LCTL set_param -n \
30882                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30883
30884         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30885                       osp.$FSNAME-OST0000*MDT0000.create_count")
30886         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30887                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30888         local expect_count=$(((($max/2)/256) * 256))
30889
30890         log "setting create_count to 100200:"
30891         log " -result- count: $count with max: $max, expecting: $expect_count"
30892
30893         [[ $count -eq expect_count ]] ||
30894                 error "Create count not set to max precreate."
30895 }
30896 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30897
30898 test_831() {
30899         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30900                 skip "Need MDS version 2.14.56"
30901
30902         local sync_changes=$(do_facet $SINGLEMDS \
30903                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30904
30905         [ "$sync_changes" -gt 100 ] &&
30906                 skip "Sync changes $sync_changes > 100 already"
30907
30908         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30909
30910         $LFS mkdir -i 0 $DIR/$tdir
30911         $LFS setstripe -c 1 -i 0 $DIR/$tdir
30912
30913         save_lustre_params mds1 \
30914                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
30915         save_lustre_params mds1 \
30916                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
30917
30918         do_facet mds1 "$LCTL set_param -n \
30919                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
30920                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
30921         stack_trap "restore_lustre_params < $p" EXIT
30922
30923         createmany -o $DIR/$tdir/f- 1000
30924         unlinkmany $DIR/$tdir/f- 1000 &
30925         local UNLINK_PID=$!
30926
30927         while sleep 1; do
30928                 sync_changes=$(do_facet mds1 \
30929                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30930                 # the check in the code is racy, fail the test
30931                 # if the value above the limit by 10.
30932                 [ $sync_changes -gt 110 ] && {
30933                         kill -2 $UNLINK_PID
30934                         wait
30935                         error "osp changes throttling failed, $sync_changes>110"
30936                 }
30937                 kill -0 $UNLINK_PID 2> /dev/null || break
30938         done
30939         wait
30940 }
30941 run_test 831 "throttling unlink/setattr queuing on OSP"
30942
30943 test_832() {
30944         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
30945         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
30946                 skip "Need MDS version 2.15.52+"
30947         is_rmentry_supported || skip "rm_entry not supported"
30948
30949         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30950         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
30951         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
30952                 error "mkdir remote_dir failed"
30953         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
30954                 error "mkdir striped_dir failed"
30955         touch $DIR/$tdir/file || error "touch file failed"
30956         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
30957         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
30958 }
30959 run_test 832 "lfs rm_entry"
30960
30961 test_833() {
30962         local file=$DIR/$tfile
30963
30964         stack_trap "rm -f $file" EXIT
30965         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
30966
30967         local wpid
30968         local rpid
30969         local rpid2
30970
30971         # Buffered I/O write
30972         (
30973                 while [ ! -e $DIR/sanity.833.lck ]; do
30974                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
30975                                 error "failed to write $file"
30976                         sleep 0.$((RANDOM % 4 + 1))
30977                 done
30978         )&
30979         wpid=$!
30980
30981         # Buffered I/O read
30982         (
30983                 while [ ! -e $DIR/sanity.833.lck ]; do
30984                         dd if=$file of=/dev/null bs=1M count=50 ||
30985                                 error "failed to read $file"
30986                         sleep 0.$((RANDOM % 4 + 1))
30987                 done
30988         )&
30989         rpid=$!
30990
30991         # Direct I/O read
30992         (
30993                 while [ ! -e $DIR/sanity.833.lck ]; do
30994                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
30995                                 error "failed to read $file in direct I/O mode"
30996                         sleep 0.$((RANDOM % 4 + 1))
30997                 done
30998         )&
30999         rpid2=$!
31000
31001         sleep 30
31002         touch $DIR/sanity.833.lck
31003         wait $wpid || error "$?: buffered write failed"
31004         wait $rpid || error "$?: buffered read failed"
31005         wait $rpid2 || error "$?: direct read failed"
31006 }
31007 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31008
31009 #
31010 # tests that do cleanup/setup should be run at the end
31011 #
31012
31013 test_900() {
31014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31015         local ls
31016
31017         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31018         $LCTL set_param fail_loc=0x903
31019
31020         cancel_lru_locks MGC
31021
31022         FAIL_ON_ERROR=true cleanup
31023         FAIL_ON_ERROR=true setup
31024 }
31025 run_test 900 "umount should not race with any mgc requeue thread"
31026
31027 # LUS-6253/LU-11185
31028 test_901() {
31029         local old
31030         local count
31031         local oldc
31032         local newc
31033         local olds
31034         local news
31035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31036
31037         # some get_param have a bug to handle dot in param name
31038         cancel_lru_locks MGC
31039         old=$(mount -t lustre | wc -l)
31040         # 1 config+sptlrpc
31041         # 2 params
31042         # 3 nodemap
31043         # 4 IR
31044         old=$((old * 4))
31045         oldc=0
31046         count=0
31047         while [ $old -ne $oldc ]; do
31048                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31049                 sleep 1
31050                 ((count++))
31051                 if [ $count -ge $TIMEOUT ]; then
31052                         error "too large timeout"
31053                 fi
31054         done
31055         umount_client $MOUNT || error "umount failed"
31056         mount_client $MOUNT || error "mount failed"
31057         cancel_lru_locks MGC
31058         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31059
31060         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31061
31062         return 0
31063 }
31064 run_test 901 "don't leak a mgc lock on client umount"
31065
31066 # LU-13377
31067 test_902() {
31068         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31069                 skip "client does not have LU-13377 fix"
31070         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31071         $LCTL set_param fail_loc=0x1415
31072         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31073         cancel_lru_locks osc
31074         rm -f $DIR/$tfile
31075 }
31076 run_test 902 "test short write doesn't hang lustre"
31077
31078 # LU-14711
31079 test_903() {
31080         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31081         echo "blah" > $DIR/${tfile}-2
31082         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31083         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31084         $LCTL set_param fail_loc=0x417 fail_val=20
31085
31086         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31087         sleep 1 # To start the destroy
31088         wait_destroy_complete 150 || error "Destroy taking too long"
31089         cat $DIR/$tfile > /dev/null || error "Evicted"
31090 }
31091 run_test 903 "Test long page discard does not cause evictions"
31092
31093 test_904() {
31094         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31095         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31096                 grep -q project || skip "skip project quota not supported"
31097
31098         local testfile="$DIR/$tdir/$tfile"
31099         local xattr="trusted.projid"
31100         local projid
31101         local mdts=$(comma_list $(mdts_nodes))
31102         local saved=$(do_facet mds1 $LCTL get_param -n \
31103                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31104
31105         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31106         stack_trap "do_nodes $mdts $LCTL set_param \
31107                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31108
31109         mkdir -p $DIR/$tdir
31110         touch $testfile
31111         #hide projid xattr on server
31112         $LFS project -p 1 $testfile ||
31113                 error "set $testfile project id failed"
31114         getfattr -m - $testfile | grep $xattr &&
31115                 error "do not show trusted.projid when disabled on server"
31116         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31117         #should be hidden when projid is 0
31118         $LFS project -p 0 $testfile ||
31119                 error "set $testfile project id failed"
31120         getfattr -m - $testfile | grep $xattr &&
31121                 error "do not show trusted.projid with project ID 0"
31122
31123         #still can getxattr explicitly
31124         projid=$(getfattr -n $xattr $testfile |
31125                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31126         [ $projid == "0" ] ||
31127                 error "projid expected 0 not $projid"
31128
31129         #set the projid via setxattr
31130         setfattr -n $xattr -v "1000" $testfile ||
31131                 error "setattr failed with $?"
31132         projid=($($LFS project $testfile))
31133         [ ${projid[0]} == "1000" ] ||
31134                 error "projid expected 1000 not $projid"
31135
31136         #check the new projid via getxattr
31137         $LFS project -p 1001 $testfile ||
31138                 error "set $testfile project id failed"
31139         getfattr -m - $testfile | grep $xattr ||
31140                 error "should show trusted.projid when project ID != 0"
31141         projid=$(getfattr -n $xattr $testfile |
31142                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31143         [ $projid == "1001" ] ||
31144                 error "projid expected 1001 not $projid"
31145
31146         #try to set invalid projid
31147         setfattr -n $xattr -v "4294967295" $testfile &&
31148                 error "set invalid projid should fail"
31149
31150         #remove the xattr means setting projid to 0
31151         setfattr -x $xattr $testfile ||
31152                 error "setfattr failed with $?"
31153         projid=($($LFS project $testfile))
31154         [ ${projid[0]} == "0" ] ||
31155                 error "projid expected 0 not $projid"
31156
31157         #should be hidden when parent has inherit flag and same projid
31158         $LFS project -srp 1002 $DIR/$tdir ||
31159                 error "set $tdir project id failed"
31160         getfattr -m - $testfile | grep $xattr &&
31161                 error "do not show trusted.projid with inherit flag"
31162
31163         #still can getxattr explicitly
31164         projid=$(getfattr -n $xattr $testfile |
31165                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31166         [ $projid == "1002" ] ||
31167                 error "projid expected 1002 not $projid"
31168 }
31169 run_test 904 "virtual project ID xattr"
31170
31171 # LU-8582
31172 test_905() {
31173         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31174                 skip "need OST version >= 2.15.50.220 for fail_loc"
31175
31176         remote_ost_nodsh && skip "remote OST with nodsh"
31177         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31178
31179         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31180
31181         #define OBD_FAIL_OST_OPCODE 0x253
31182         # OST_LADVISE = 21
31183         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31184         $LFS ladvise -a willread $DIR/$tfile &&
31185                 error "unexpected success of ladvise with fault injection"
31186         $LFS ladvise -a willread $DIR/$tfile |&
31187                 grep -q "Operation not supported"
31188         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31189 }
31190 run_test 905 "bad or new opcode should not stuck client"
31191
31192 test_906() {
31193         grep -q io_uring_setup /proc/kallsyms ||
31194                 skip "Client OS does not support io_uring I/O engine"
31195         io_uring_probe || skip "kernel does not support io_uring fully"
31196         which fio || skip_env "no fio installed"
31197         fio --enghelp | grep -q io_uring ||
31198                 skip_env "fio does not support io_uring I/O engine"
31199
31200         local file=$DIR/$tfile
31201         local ioengine="io_uring"
31202         local numjobs=2
31203         local size=50M
31204
31205         fio --name=seqwrite --ioengine=$ioengine        \
31206                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31207                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31208                 error "fio seqwrite $file failed"
31209
31210         fio --name=seqread --ioengine=$ioengine \
31211                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31212                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31213                 error "fio seqread $file failed"
31214
31215         rm -f $file || error "rm -f $file failed"
31216 }
31217 run_test 906 "Simple test for io_uring I/O engine via fio"
31218
31219 test_907() {
31220         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31221
31222         # set stripe size to max rpc size
31223         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31224         $LFS getstripe $DIR/$tfile
31225 #define OBD_FAIL_OST_EROFS               0x216
31226         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31227
31228         local bs=$((max_pages * PAGE_SIZE / 16))
31229
31230         # write full one stripe and one block
31231         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31232
31233         rm $DIR/$tfile || error "rm failed"
31234 }
31235 run_test 907 "write rpc error during unlink"
31236
31237 complete_test $SECONDS
31238 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31239 check_and_cleanup_lustre
31240 if [ "$I_MOUNTED" != "yes" ]; then
31241         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31242 fi
31243 exit_status