Whamcloud - gitweb
LU-16762 statahead: wait until statahead thread quit
[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         local ahost=$(facet_active_host ost1)
5267         saved_adiff=$(do_facet ost1 \
5268                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5269         stack_trap "do_facet ost1 \
5270                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5271
5272         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5273
5274         $LFS setstripe -i 0 $DIR/$tfile
5275         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5276                 error "can't write initial file"
5277         cancel_lru_locks osc
5278
5279         # exceed atime_diff and access file
5280         sleep 10
5281         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5282                 error "can't udpate atime"
5283
5284         # atime_cli value is in decimal
5285         local atime_cli=$(stat -c %X $DIR/$tfile)
5286         echo "client atime: $atime_cli"
5287
5288         local ostdev=$(ostdevname 1)
5289         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5290         local seq=${fid[3]#0x}
5291         local oid=${fid[1]}
5292         local oid_hex
5293
5294         if [ $seq == 0 ]; then
5295                 oid_hex=${fid[1]}
5296         else
5297                 oid_hex=${fid[2]#0x}
5298         fi
5299         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5300         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5301
5302         # allow atime update to be written to device
5303         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5304         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5305
5306         # Give enough time for server to get updated. Until then
5307         # the value read is defaulted to "0x00000000:00000000"
5308         # Wait until atime read via debugfs is not equal to zero.
5309         # Max limit to wait is 30 seconds.
5310         wait_update_cond $ahost                                         \
5311                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5312                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5313         # atime_ost value is in hex
5314         local atime_ost=$(do_facet ost1 "$cmd" |&
5315                           awk -F'[: ]' '/atime:/ { print $4 }')
5316         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5317         # convert Hex to decimal before comparing
5318         local atime_ost_dec=$((atime_ost))
5319
5320         # The test pass criteria is that the client time and server should
5321         # be same (2s gap accepted). This gap could arise due to VFS updating
5322         # the atime after the read(dd), stat and the updated time from the
5323         # inode
5324         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5325                 error "atime on client $atime_cli != ost $atime_ost_dec"
5326 }
5327 run_test 39r "lazy atime update on OST"
5328
5329 test_39q() { # LU-8041
5330         local testdir=$DIR/$tdir
5331         mkdir -p $testdir
5332         multiop_bg_pause $testdir D_c || error "multiop failed"
5333         local multipid=$!
5334         cancel_lru_locks mdc
5335         kill -USR1 $multipid
5336         local atime=$(stat -c %X $testdir)
5337         [ "$atime" -ne 0 ] || error "atime is zero"
5338 }
5339 run_test 39q "close won't zero out atime"
5340
5341 test_39s() {
5342         local atime0
5343         local atime1
5344         local atime2
5345         local atime3
5346         local atime4
5347
5348         umount_client $MOUNT
5349         mount_client $MOUNT relatime
5350
5351         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5352         atime0=$(stat -c %X $DIR/$tfile)
5353
5354         # First read updates atime
5355         sleep 1
5356         cat $DIR/$tfile >/dev/null
5357         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5358
5359         # Next reads do not update atime
5360         sleep 1
5361         cat $DIR/$tfile >/dev/null
5362         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5363
5364         # If mtime is greater than atime, atime is updated
5365         sleep 1
5366         touch -m $DIR/$tfile # (mtime = now)
5367         sleep 1
5368         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5369         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5370
5371         # Next reads do not update atime
5372         sleep 1
5373         cat $DIR/$tfile >/dev/null
5374         atime4=$(stat -c %X $DIR/$tfile)
5375
5376         # Remount the client to clear 'relatime' option
5377         remount_client $MOUNT
5378
5379         (( atime0 < atime1 )) ||
5380                 error "atime $atime0 should be smaller than $atime1"
5381         (( atime1 == atime2 )) ||
5382                 error "atime $atime1 was updated to $atime2"
5383         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5384         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5385 }
5386 run_test 39s "relatime is supported"
5387
5388 test_40() {
5389         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5390         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5391                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5392         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5393                 error "$tfile is not 4096 bytes in size"
5394 }
5395 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5396
5397 test_41() {
5398         # bug 1553
5399         small_write $DIR/f41 18
5400 }
5401 run_test 41 "test small file write + fstat ====================="
5402
5403 count_ost_writes() {
5404         lctl get_param -n ${OSC}.*.stats |
5405                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5406                         END { printf("%0.0f", writes) }'
5407 }
5408
5409 # decent default
5410 WRITEBACK_SAVE=500
5411 DIRTY_RATIO_SAVE=40
5412 MAX_DIRTY_RATIO=50
5413 BG_DIRTY_RATIO_SAVE=10
5414 MAX_BG_DIRTY_RATIO=25
5415
5416 start_writeback() {
5417         trap 0
5418         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5419         # dirty_ratio, dirty_background_ratio
5420         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5421                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5422                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5423                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5424         else
5425                 # if file not here, we are a 2.4 kernel
5426                 kill -CONT `pidof kupdated`
5427         fi
5428 }
5429
5430 stop_writeback() {
5431         # setup the trap first, so someone cannot exit the test at the
5432         # exact wrong time and mess up a machine
5433         trap start_writeback EXIT
5434         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5435         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5436                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5437                 sysctl -w vm.dirty_writeback_centisecs=0
5438                 sysctl -w vm.dirty_writeback_centisecs=0
5439                 # save and increase /proc/sys/vm/dirty_ratio
5440                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5441                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5442                 # save and increase /proc/sys/vm/dirty_background_ratio
5443                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5444                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5445         else
5446                 # if file not here, we are a 2.4 kernel
5447                 kill -STOP `pidof kupdated`
5448         fi
5449 }
5450
5451 # ensure that all stripes have some grant before we test client-side cache
5452 setup_test42() {
5453         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5454                 dd if=/dev/zero of=$i bs=4k count=1
5455                 rm $i
5456         done
5457 }
5458
5459 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5460 # file truncation, and file removal.
5461 test_42a() {
5462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5463
5464         setup_test42
5465         cancel_lru_locks $OSC
5466         stop_writeback
5467         sync; sleep 1; sync # just to be safe
5468         BEFOREWRITES=`count_ost_writes`
5469         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5470         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5471         AFTERWRITES=`count_ost_writes`
5472         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5473                 error "$BEFOREWRITES < $AFTERWRITES"
5474         start_writeback
5475 }
5476 run_test 42a "ensure that we don't flush on close"
5477
5478 test_42b() {
5479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5480
5481         setup_test42
5482         cancel_lru_locks $OSC
5483         stop_writeback
5484         sync
5485         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5486         BEFOREWRITES=$(count_ost_writes)
5487         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5488         AFTERWRITES=$(count_ost_writes)
5489         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5490                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5491         fi
5492         BEFOREWRITES=$(count_ost_writes)
5493         sync || error "sync: $?"
5494         AFTERWRITES=$(count_ost_writes)
5495         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5496                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5497         fi
5498         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5499         start_writeback
5500         return 0
5501 }
5502 run_test 42b "test destroy of file with cached dirty data ======"
5503
5504 # if these tests just want to test the effect of truncation,
5505 # they have to be very careful.  consider:
5506 # - the first open gets a {0,EOF}PR lock
5507 # - the first write conflicts and gets a {0, count-1}PW
5508 # - the rest of the writes are under {count,EOF}PW
5509 # - the open for truncate tries to match a {0,EOF}PR
5510 #   for the filesize and cancels the PWs.
5511 # any number of fixes (don't get {0,EOF} on open, match
5512 # composite locks, do smarter file size management) fix
5513 # this, but for now we want these tests to verify that
5514 # the cancellation with truncate intent works, so we
5515 # start the file with a full-file pw lock to match against
5516 # until the truncate.
5517 trunc_test() {
5518         test=$1
5519         file=$DIR/$test
5520         offset=$2
5521         cancel_lru_locks $OSC
5522         stop_writeback
5523         # prime the file with 0,EOF PW to match
5524         touch $file
5525         $TRUNCATE $file 0
5526         sync; sync
5527         # now the real test..
5528         dd if=/dev/zero of=$file bs=1024 count=100
5529         BEFOREWRITES=`count_ost_writes`
5530         $TRUNCATE $file $offset
5531         cancel_lru_locks $OSC
5532         AFTERWRITES=`count_ost_writes`
5533         start_writeback
5534 }
5535
5536 test_42c() {
5537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5538
5539         trunc_test 42c 1024
5540         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5541                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5542         rm $file
5543 }
5544 run_test 42c "test partial truncate of file with cached dirty data"
5545
5546 test_42d() {
5547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5548
5549         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5550         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5551         $LCTL set_param debug=+cache
5552
5553         trunc_test 42d 0
5554         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5555                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5556         rm $file
5557 }
5558 run_test 42d "test complete truncate of file with cached dirty data"
5559
5560 test_42e() { # bug22074
5561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5562
5563         local TDIR=$DIR/${tdir}e
5564         local pages=16 # hardcoded 16 pages, don't change it.
5565         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5566         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5567         local max_dirty_mb
5568         local warmup_files
5569
5570         test_mkdir $DIR/${tdir}e
5571         $LFS setstripe -c 1 $TDIR
5572         createmany -o $TDIR/f $files
5573
5574         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5575
5576         # we assume that with $OSTCOUNT files, at least one of them will
5577         # be allocated on OST0.
5578         warmup_files=$((OSTCOUNT * max_dirty_mb))
5579         createmany -o $TDIR/w $warmup_files
5580
5581         # write a large amount of data into one file and sync, to get good
5582         # avail_grant number from OST.
5583         for ((i=0; i<$warmup_files; i++)); do
5584                 idx=$($LFS getstripe -i $TDIR/w$i)
5585                 [ $idx -ne 0 ] && continue
5586                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5587                 break
5588         done
5589         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5590         sync
5591         $LCTL get_param $proc_osc0/cur_dirty_bytes
5592         $LCTL get_param $proc_osc0/cur_grant_bytes
5593
5594         # create as much dirty pages as we can while not to trigger the actual
5595         # RPCs directly. but depends on the env, VFS may trigger flush during this
5596         # period, hopefully we are good.
5597         for ((i=0; i<$warmup_files; i++)); do
5598                 idx=$($LFS getstripe -i $TDIR/w$i)
5599                 [ $idx -ne 0 ] && continue
5600                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5601         done
5602         $LCTL get_param $proc_osc0/cur_dirty_bytes
5603         $LCTL get_param $proc_osc0/cur_grant_bytes
5604
5605         # perform the real test
5606         $LCTL set_param $proc_osc0/rpc_stats 0
5607         for ((;i<$files; i++)); do
5608                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5609                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5610         done
5611         sync
5612         $LCTL get_param $proc_osc0/rpc_stats
5613
5614         local percent=0
5615         local have_ppr=false
5616         $LCTL get_param $proc_osc0/rpc_stats |
5617                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5618                         # skip lines until we are at the RPC histogram data
5619                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5620                         $have_ppr || continue
5621
5622                         # we only want the percent stat for < 16 pages
5623                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5624
5625                         percent=$((percent + WPCT))
5626                         if [[ $percent -gt 15 ]]; then
5627                                 error "less than 16-pages write RPCs" \
5628                                       "$percent% > 15%"
5629                                 break
5630                         fi
5631                 done
5632         rm -rf $TDIR
5633 }
5634 run_test 42e "verify sub-RPC writes are not done synchronously"
5635
5636 test_43A() { # was test_43
5637         test_mkdir $DIR/$tdir
5638         cp -p /bin/ls $DIR/$tdir/$tfile
5639         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5640         pid=$!
5641         # give multiop a chance to open
5642         sleep 1
5643
5644         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5645         kill -USR1 $pid
5646         # Wait for multiop to exit
5647         wait $pid
5648 }
5649 run_test 43A "execution of file opened for write should return -ETXTBSY"
5650
5651 test_43a() {
5652         test_mkdir $DIR/$tdir
5653         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5654         $DIR/$tdir/sleep 60 &
5655         SLEEP_PID=$!
5656         # Make sure exec of $tdir/sleep wins race with truncate
5657         sleep 1
5658         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5659         kill $SLEEP_PID
5660 }
5661 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5662
5663 test_43b() {
5664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5665
5666         test_mkdir $DIR/$tdir
5667         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5668         $DIR/$tdir/sleep 60 &
5669         SLEEP_PID=$!
5670         # Make sure exec of $tdir/sleep wins race with truncate
5671         sleep 1
5672         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5673         kill $SLEEP_PID
5674 }
5675 run_test 43b "truncate of file being executed should return -ETXTBSY"
5676
5677 test_43c() {
5678         local testdir="$DIR/$tdir"
5679         test_mkdir $testdir
5680         cp $SHELL $testdir/
5681         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5682                 ( cd $testdir && md5sum -c )
5683 }
5684 run_test 43c "md5sum of copy into lustre"
5685
5686 test_44A() { # was test_44
5687         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5688
5689         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5690         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5691 }
5692 run_test 44A "zero length read from a sparse stripe"
5693
5694 test_44a() {
5695         local nstripe=$($LFS getstripe -c -d $DIR)
5696         [ -z "$nstripe" ] && skip "can't get stripe info"
5697         [[ $nstripe -gt $OSTCOUNT ]] &&
5698                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5699
5700         local stride=$($LFS getstripe -S -d $DIR)
5701         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5702                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5703         fi
5704
5705         OFFSETS="0 $((stride/2)) $((stride-1))"
5706         for offset in $OFFSETS; do
5707                 for i in $(seq 0 $((nstripe-1))); do
5708                         local GLOBALOFFSETS=""
5709                         # size in Bytes
5710                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5711                         local myfn=$DIR/d44a-$size
5712                         echo "--------writing $myfn at $size"
5713                         ll_sparseness_write $myfn $size ||
5714                                 error "ll_sparseness_write"
5715                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5716                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5717                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5718
5719                         for j in $(seq 0 $((nstripe-1))); do
5720                                 # size in Bytes
5721                                 size=$((((j + $nstripe )*$stride + $offset)))
5722                                 ll_sparseness_write $myfn $size ||
5723                                         error "ll_sparseness_write"
5724                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5725                         done
5726                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5727                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5728                         rm -f $myfn
5729                 done
5730         done
5731 }
5732 run_test 44a "test sparse pwrite ==============================="
5733
5734 dirty_osc_total() {
5735         tot=0
5736         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5737                 tot=$(($tot + $d))
5738         done
5739         echo $tot
5740 }
5741 do_dirty_record() {
5742         before=`dirty_osc_total`
5743         echo executing "\"$*\""
5744         eval $*
5745         after=`dirty_osc_total`
5746         echo before $before, after $after
5747 }
5748 test_45() {
5749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5750
5751         f="$DIR/f45"
5752         # Obtain grants from OST if it supports it
5753         echo blah > ${f}_grant
5754         stop_writeback
5755         sync
5756         do_dirty_record "echo blah > $f"
5757         [[ $before -eq $after ]] && error "write wasn't cached"
5758         do_dirty_record "> $f"
5759         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5760         do_dirty_record "echo blah > $f"
5761         [[ $before -eq $after ]] && error "write wasn't cached"
5762         do_dirty_record "sync"
5763         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5764         do_dirty_record "echo blah > $f"
5765         [[ $before -eq $after ]] && error "write wasn't cached"
5766         do_dirty_record "cancel_lru_locks osc"
5767         [[ $before -gt $after ]] ||
5768                 error "lock cancellation didn't lower dirty count"
5769         start_writeback
5770 }
5771 run_test 45 "osc io page accounting ============================"
5772
5773 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5774 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5775 # objects offset and an assert hit when an rpc was built with 1023's mapped
5776 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5777 test_46() {
5778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5779
5780         f="$DIR/f46"
5781         stop_writeback
5782         sync
5783         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5784         sync
5785         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5786         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5787         sync
5788         start_writeback
5789 }
5790 run_test 46 "dirtying a previously written page ================"
5791
5792 # test_47 is removed "Device nodes check" is moved to test_28
5793
5794 test_48a() { # bug 2399
5795         [ "$mds1_FSTYPE" = "zfs" ] &&
5796         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5797                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5798
5799         test_mkdir $DIR/$tdir
5800         cd $DIR/$tdir
5801         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5802         test_mkdir $DIR/$tdir
5803         touch foo || error "'touch foo' failed after recreating cwd"
5804         test_mkdir bar
5805         touch .foo || error "'touch .foo' failed after recreating cwd"
5806         test_mkdir .bar
5807         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5808         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5809         cd . || error "'cd .' failed after recreating cwd"
5810         mkdir . && error "'mkdir .' worked after recreating cwd"
5811         rmdir . && error "'rmdir .' worked after recreating cwd"
5812         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5813         cd .. || error "'cd ..' failed after recreating cwd"
5814 }
5815 run_test 48a "Access renamed working dir (should return errors)="
5816
5817 test_48b() { # bug 2399
5818         rm -rf $DIR/$tdir
5819         test_mkdir $DIR/$tdir
5820         cd $DIR/$tdir
5821         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5822         touch foo && error "'touch foo' worked after removing cwd"
5823         mkdir foo && error "'mkdir foo' worked after removing cwd"
5824         touch .foo && error "'touch .foo' worked after removing cwd"
5825         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5826         ls . > /dev/null && error "'ls .' worked after removing cwd"
5827         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5828         mkdir . && error "'mkdir .' worked after removing cwd"
5829         rmdir . && error "'rmdir .' worked after removing cwd"
5830         ln -s . foo && error "'ln -s .' worked after removing cwd"
5831         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5832 }
5833 run_test 48b "Access removed working dir (should return errors)="
5834
5835 test_48c() { # bug 2350
5836         #lctl set_param debug=-1
5837         #set -vx
5838         rm -rf $DIR/$tdir
5839         test_mkdir -p $DIR/$tdir/dir
5840         cd $DIR/$tdir/dir
5841         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5842         $TRACE touch foo && error "touch foo worked after removing cwd"
5843         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5844         touch .foo && error "touch .foo worked after removing cwd"
5845         mkdir .foo && error "mkdir .foo worked after removing cwd"
5846         $TRACE ls . && error "'ls .' worked after removing cwd"
5847         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5848         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5849         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5850         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5851         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5852 }
5853 run_test 48c "Access removed working subdir (should return errors)"
5854
5855 test_48d() { # bug 2350
5856         #lctl set_param debug=-1
5857         #set -vx
5858         rm -rf $DIR/$tdir
5859         test_mkdir -p $DIR/$tdir/dir
5860         cd $DIR/$tdir/dir
5861         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5862         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5863         $TRACE touch foo && error "'touch foo' worked after removing parent"
5864         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5865         touch .foo && error "'touch .foo' worked after removing parent"
5866         mkdir .foo && error "mkdir .foo worked after removing parent"
5867         $TRACE ls . && error "'ls .' worked after removing parent"
5868         $TRACE ls .. && error "'ls ..' worked after removing parent"
5869         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5870         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5871         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5872         true
5873 }
5874 run_test 48d "Access removed parent subdir (should return errors)"
5875
5876 test_48e() { # bug 4134
5877         #lctl set_param debug=-1
5878         #set -vx
5879         rm -rf $DIR/$tdir
5880         test_mkdir -p $DIR/$tdir/dir
5881         cd $DIR/$tdir/dir
5882         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5883         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5884         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5885         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5886         # On a buggy kernel addition of "touch foo" after cd .. will
5887         # produce kernel oops in lookup_hash_it
5888         touch ../foo && error "'cd ..' worked after recreate parent"
5889         cd $DIR
5890         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5891 }
5892 run_test 48e "Access to recreated parent subdir (should return errors)"
5893
5894 test_48f() {
5895         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5896                 skip "need MDS >= 2.13.55"
5897         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5898         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5899                 skip "needs different host for mdt1 mdt2"
5900         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5901
5902         $LFS mkdir -i0 $DIR/$tdir
5903         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5904
5905         for d in sub1 sub2 sub3; do
5906                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5907                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5908                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5909         done
5910
5911         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5912 }
5913 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5914
5915 test_49() { # LU-1030
5916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5917         remote_ost_nodsh && skip "remote OST with nodsh"
5918
5919         # get ost1 size - $FSNAME-OST0000
5920         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5921                 awk '{ print $4 }')
5922         # write 800M at maximum
5923         [[ $ost1_size -lt 2 ]] && ost1_size=2
5924         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5925
5926         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5927         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5928         local dd_pid=$!
5929
5930         # change max_pages_per_rpc while writing the file
5931         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5932         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5933         # loop until dd process exits
5934         while ps ax -opid | grep -wq $dd_pid; do
5935                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5936                 sleep $((RANDOM % 5 + 1))
5937         done
5938         # restore original max_pages_per_rpc
5939         $LCTL set_param $osc1_mppc=$orig_mppc
5940         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5941 }
5942 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5943
5944 test_50() {
5945         # bug 1485
5946         test_mkdir $DIR/$tdir
5947         cd $DIR/$tdir
5948         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5949 }
5950 run_test 50 "special situations: /proc symlinks  ==============="
5951
5952 test_51a() {    # was test_51
5953         # bug 1516 - create an empty entry right after ".." then split dir
5954         test_mkdir -c1 $DIR/$tdir
5955         touch $DIR/$tdir/foo
5956         $MCREATE $DIR/$tdir/bar
5957         rm $DIR/$tdir/foo
5958         createmany -m $DIR/$tdir/longfile 201
5959         FNUM=202
5960         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5961                 $MCREATE $DIR/$tdir/longfile$FNUM
5962                 FNUM=$(($FNUM + 1))
5963                 echo -n "+"
5964         done
5965         echo
5966         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5967 }
5968 run_test 51a "special situations: split htree with empty entry =="
5969
5970 cleanup_print_lfs_df () {
5971         trap 0
5972         $LFS df
5973         $LFS df -i
5974 }
5975
5976 test_51b() {
5977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5978
5979         local dir=$DIR/$tdir
5980         local nrdirs=$((65536 + 100))
5981
5982         # cleanup the directory
5983         rm -fr $dir
5984
5985         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5986
5987         $LFS df
5988         $LFS df -i
5989         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5990         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5991         [[ $numfree -lt $nrdirs ]] &&
5992                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5993
5994         # need to check free space for the directories as well
5995         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5996         numfree=$(( blkfree / $(fs_inode_ksize) ))
5997         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5998
5999         trap cleanup_print_lfs_df EXIT
6000
6001         # create files
6002         createmany -d $dir/d $nrdirs || {
6003                 unlinkmany $dir/d $nrdirs
6004                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6005         }
6006
6007         # really created :
6008         nrdirs=$(ls -U $dir | wc -l)
6009
6010         # unlink all but 100 subdirectories, then check it still works
6011         local left=100
6012         local delete=$((nrdirs - left))
6013
6014         $LFS df
6015         $LFS df -i
6016
6017         # for ldiskfs the nlink count should be 1, but this is OSD specific
6018         # and so this is listed for informational purposes only
6019         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6020         unlinkmany -d $dir/d $delete ||
6021                 error "unlink of first $delete subdirs failed"
6022
6023         echo "nlink between: $(stat -c %h $dir)"
6024         local found=$(ls -U $dir | wc -l)
6025         [ $found -ne $left ] &&
6026                 error "can't find subdirs: found only $found, expected $left"
6027
6028         unlinkmany -d $dir/d $delete $left ||
6029                 error "unlink of second $left subdirs failed"
6030         # regardless of whether the backing filesystem tracks nlink accurately
6031         # or not, the nlink count shouldn't be more than "." and ".." here
6032         local after=$(stat -c %h $dir)
6033         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6034                 echo "nlink after: $after"
6035
6036         cleanup_print_lfs_df
6037 }
6038 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6039
6040 test_51d_sub() {
6041         local stripecount=$1
6042         local nfiles=$2
6043
6044         log "create files with stripecount=$stripecount"
6045         $LFS setstripe -C $stripecount $DIR/$tdir
6046         createmany -o $DIR/$tdir/t- $nfiles
6047         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6048         for ((n = 0; n < $OSTCOUNT; n++)); do
6049                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6050                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6051                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6052                             '($1 == '$n') { objs += 1 } \
6053                             END { printf("%0.0f", objs) }')
6054                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6055         done
6056         unlinkmany $DIR/$tdir/t- $nfiles
6057         rm  -f $TMP/$tfile
6058
6059         local nlast
6060         local min=4
6061         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6062
6063         # For some combinations of stripecount and OSTCOUNT current code
6064         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6065         # than others. Rather than skipping this test entirely, check that
6066         # and keep testing to ensure imbalance does not get worse. LU-15282
6067         (( (OSTCOUNT == 6 && stripecount == 4) ||
6068            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6069            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6070         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6071                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6072                         { $LFS df && $LFS df -i &&
6073                         error "stripecount=$stripecount: " \
6074                               "OST $n has fewer objects vs. OST $nlast " \
6075                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6076                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6077                         { $LFS df && $LFS df -i &&
6078                         error "stripecount=$stripecount: " \
6079                               "OST $n has more objects vs. OST $nlast " \
6080                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6081
6082                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6083                         { $LFS df && $LFS df -i &&
6084                         error "stripecount=$stripecount: " \
6085                               "OST $n has fewer #0 objects vs. OST $nlast " \
6086                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6087                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6088                         { $LFS df && $LFS df -i &&
6089                         error "stripecount=$stripecount: " \
6090                               "OST $n has more #0 objects vs. OST $nlast " \
6091                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6092         done
6093 }
6094
6095 test_51d() {
6096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6097         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6098
6099         local stripecount
6100         local per_ost=100
6101         local nfiles=$((per_ost * OSTCOUNT))
6102         local mdts=$(comma_list $(mdts_nodes))
6103         local param="osp.*.create_count"
6104         local qos_old=$(do_facet mds1 \
6105                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6106
6107         do_nodes $mdts \
6108                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6109         stack_trap "do_nodes $mdts \
6110                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6111
6112         test_mkdir $DIR/$tdir
6113         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6114         (( dirstripes > 0 )) || dirstripes=1
6115
6116         # Ensure enough OST objects precreated for tests to pass without
6117         # running out of objects.  This is an LOV r-r OST algorithm test,
6118         # not an OST object precreation test.
6119         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6120         (( old >= nfiles )) ||
6121         {
6122                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6123
6124                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6125                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6126
6127                 # trigger precreation from all MDTs for all OSTs
6128                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6129                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6130                 done
6131         }
6132
6133         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6134                 sleep 8  # allow object precreation to catch up
6135                 test_51d_sub $stripecount $nfiles
6136         done
6137 }
6138 run_test 51d "check LOV round-robin OST object distribution"
6139
6140 test_51e() {
6141         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6142                 skip_env "ldiskfs only test"
6143         fi
6144
6145         test_mkdir -c1 $DIR/$tdir
6146         test_mkdir -c1 $DIR/$tdir/d0
6147
6148         touch $DIR/$tdir/d0/foo
6149         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6150                 error "file exceed 65000 nlink limit!"
6151         unlinkmany $DIR/$tdir/d0/f- 65001
6152         return 0
6153 }
6154 run_test 51e "check file nlink limit"
6155
6156 test_51f() {
6157         test_mkdir $DIR/$tdir
6158
6159         local max=100000
6160         local ulimit_old=$(ulimit -n)
6161         local spare=20 # number of spare fd's for scripts/libraries, etc.
6162         local mdt=$($LFS getstripe -m $DIR/$tdir)
6163         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6164
6165         echo "MDT$mdt numfree=$numfree, max=$max"
6166         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6167         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6168                 while ! ulimit -n $((numfree + spare)); do
6169                         numfree=$((numfree * 3 / 4))
6170                 done
6171                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6172         else
6173                 echo "left ulimit at $ulimit_old"
6174         fi
6175
6176         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6177                 unlinkmany $DIR/$tdir/f $numfree
6178                 error "create+open $numfree files in $DIR/$tdir failed"
6179         }
6180         ulimit -n $ulimit_old
6181
6182         # if createmany exits at 120s there will be fewer than $numfree files
6183         unlinkmany $DIR/$tdir/f $numfree || true
6184 }
6185 run_test 51f "check many open files limit"
6186
6187 test_52a() {
6188         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6189         test_mkdir $DIR/$tdir
6190         touch $DIR/$tdir/foo
6191         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6192         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6193         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6194         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6195         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6196                                         error "link worked"
6197         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6198         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6199         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6200                                                      error "lsattr"
6201         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6202         cp -r $DIR/$tdir $TMP/
6203         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6204 }
6205 run_test 52a "append-only flag test (should return errors)"
6206
6207 test_52b() {
6208         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6209         test_mkdir $DIR/$tdir
6210         touch $DIR/$tdir/foo
6211         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6212         cat test > $DIR/$tdir/foo && error "cat test worked"
6213         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6214         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6215         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6216                                         error "link worked"
6217         echo foo >> $DIR/$tdir/foo && error "echo worked"
6218         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6219         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6220         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6221         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6222                                                         error "lsattr"
6223         chattr -i $DIR/$tdir/foo || error "chattr failed"
6224
6225         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6226 }
6227 run_test 52b "immutable flag test (should return errors) ======="
6228
6229 test_53() {
6230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6231         remote_mds_nodsh && skip "remote MDS with nodsh"
6232         remote_ost_nodsh && skip "remote OST with nodsh"
6233
6234         local param
6235         local param_seq
6236         local ostname
6237         local mds_last
6238         local mds_last_seq
6239         local ost_last
6240         local ost_last_seq
6241         local ost_last_id
6242         local ostnum
6243         local node
6244         local found=false
6245         local support_last_seq=true
6246
6247         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6248                 support_last_seq=false
6249
6250         # only test MDT0000
6251         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6252         local value
6253         for value in $(do_facet $SINGLEMDS \
6254                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6255                 param=$(echo ${value[0]} | cut -d "=" -f1)
6256                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6257
6258                 if $support_last_seq; then
6259                         param_seq=$(echo $param |
6260                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6261                         mds_last_seq=$(do_facet $SINGLEMDS \
6262                                        $LCTL get_param -n $param_seq)
6263                 fi
6264                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6265
6266                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6267                 node=$(facet_active_host ost$((ostnum+1)))
6268                 param="obdfilter.$ostname.last_id"
6269                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6270                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6271                         ost_last_id=$ost_last
6272
6273                         if $support_last_seq; then
6274                                 ost_last_id=$(echo $ost_last |
6275                                               awk -F':' '{print $2}' |
6276                                               sed -e "s/^0x//g")
6277                                 ost_last_seq=$(echo $ost_last |
6278                                                awk -F':' '{print $1}')
6279                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6280                         fi
6281
6282                         if [[ $ost_last_id != $mds_last ]]; then
6283                                 error "$ost_last_id != $mds_last"
6284                         else
6285                                 found=true
6286                                 break
6287                         fi
6288                 done
6289         done
6290         $found || error "can not match last_seq/last_id for $mdtosc"
6291         return 0
6292 }
6293 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6294
6295 test_54a() {
6296         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6297
6298         LANG=C $SOCKETSERVER $DIR/socket ||
6299                 error "$SOCKETSERVER $DIR/socket failed: $?"
6300         LANG=C $SOCKETCLIENT $DIR/socket ||
6301                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6302         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6303 }
6304 run_test 54a "unix domain socket test =========================="
6305
6306 test_54b() {
6307         f="$DIR/f54b"
6308         mknod $f c 1 3
6309         chmod 0666 $f
6310         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6311 }
6312 run_test 54b "char device works in lustre ======================"
6313
6314 find_loop_dev() {
6315         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6316         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6317         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6318
6319         for i in $(seq 3 7); do
6320                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6321                 LOOPDEV=$LOOPBASE$i
6322                 LOOPNUM=$i
6323                 break
6324         done
6325 }
6326
6327 cleanup_54c() {
6328         local rc=0
6329         loopdev="$DIR/loop54c"
6330
6331         trap 0
6332         $UMOUNT $DIR/$tdir || rc=$?
6333         losetup -d $loopdev || true
6334         losetup -d $LOOPDEV || true
6335         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6336         return $rc
6337 }
6338
6339 test_54c() {
6340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6341
6342         loopdev="$DIR/loop54c"
6343
6344         find_loop_dev
6345         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6346         trap cleanup_54c EXIT
6347         mknod $loopdev b 7 $LOOPNUM
6348         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6349         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6350         losetup $loopdev $DIR/$tfile ||
6351                 error "can't set up $loopdev for $DIR/$tfile"
6352         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6353         test_mkdir $DIR/$tdir
6354         mount -t ext2 $loopdev $DIR/$tdir ||
6355                 error "error mounting $loopdev on $DIR/$tdir"
6356         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6357                 error "dd write"
6358         df $DIR/$tdir
6359         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6360                 error "dd read"
6361         cleanup_54c
6362 }
6363 run_test 54c "block device works in lustre ====================="
6364
6365 test_54d() {
6366         local pipe="$DIR/$tfile.pipe"
6367         local string="aaaaaa"
6368
6369         mknod $pipe p
6370         echo -n "$string" > $pipe &
6371         local result=$(cat $pipe)
6372         [[ "$result" == "$string" ]] || error "$result != $string"
6373 }
6374 run_test 54d "fifo device works in lustre ======================"
6375
6376 test_54e() {
6377         f="$DIR/f54e"
6378         string="aaaaaa"
6379         cp -aL /dev/console $f
6380         echo $string > $f || error "echo $string to $f failed"
6381 }
6382 run_test 54e "console/tty device works in lustre ======================"
6383
6384 test_55a() {
6385         local dev_path="/sys/kernel/debug/lustre/devices"
6386
6387         load_module obdclass/obd_test verbose=2 || error "load_module failed"
6388
6389         # This must be run in iteractive mode, since attach and setup
6390         # are stateful
6391         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6392                 attach obd_test obd_name obd_uuid
6393                 setup obd_test
6394         EOF"
6395
6396         echo "Devices:"
6397         cat "$dev_path" | tail -n 10
6398
6399         $LCTL --device "obd_name" cleanup
6400         $LCTL --device "obd_name" detach
6401
6402         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6403                 error "OBD unit test failed"
6404
6405         rmmod -v obd_test ||
6406                 error "rmmod failed (may trigger a failure in a later test)"
6407 }
6408 run_test 55a "OBD device life cycle unit tests"
6409
6410 test_55b() {
6411         local dev_path="/sys/kernel/debug/lustre/devices"
6412         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6413
6414         # Set up a large number of devices, using the number
6415         # that can be set up in about a minute (based on prior
6416         # testing). We don't want to run this test forever.
6417         local num_dev_to_create="$(( 24000 - $dev_count))"
6418
6419         load_module obdclass/obd_test || error "load_module failed"
6420
6421         local start=$SECONDS
6422
6423         # This must be run in iteractive mode, since attach and setup
6424         # are stateful
6425         for ((i = 1; i <= num_dev_to_create; i++)); do
6426                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6427                 echo "setup obd_test_$i"
6428         done | $LCTL || error "OBD device creation failed"
6429
6430         echo "Load time: $((SECONDS - start))"
6431         echo "Devices:"
6432         cat "$dev_path" | tail -n 10
6433
6434         for ((i = 1; i <= num_dev_to_create; i++)); do
6435                 echo "--device obd_name_$i cleanup"
6436                 echo "--device obd_name_$i detach"
6437         done | $LCTL || error "OBD device cleanup failed"
6438
6439         echo "Unload time: $((SECONDS - start))"
6440
6441         rmmod -v obd_test ||
6442                 error "rmmod failed (may trigger a failure in a later test)"
6443 }
6444 run_test 55b "Load and unload max OBD devices"
6445
6446 test_56a() {
6447         local numfiles=3
6448         local numdirs=2
6449         local dir=$DIR/$tdir
6450
6451         rm -rf $dir
6452         test_mkdir -p $dir/dir
6453         for i in $(seq $numfiles); do
6454                 touch $dir/file$i
6455                 touch $dir/dir/file$i
6456         done
6457
6458         local numcomp=$($LFS getstripe --component-count $dir)
6459
6460         [[ $numcomp == 0 ]] && numcomp=1
6461
6462         # test lfs getstripe with --recursive
6463         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6464
6465         [[ $filenum -eq $((numfiles * 2)) ]] ||
6466                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6467         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6468         [[ $filenum -eq $numfiles ]] ||
6469                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6470         echo "$LFS getstripe showed obdidx or l_ost_idx"
6471
6472         # test lfs getstripe with file instead of dir
6473         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6474         [[ $filenum -eq 1 ]] ||
6475                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6476         echo "$LFS getstripe file1 passed"
6477
6478         #test lfs getstripe with --verbose
6479         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6480         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6481                 error "$LFS getstripe --verbose $dir: "\
6482                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6483         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6484                 error "$LFS getstripe $dir: showed lmm_magic"
6485
6486         #test lfs getstripe with -v prints lmm_fid
6487         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6488         local countfids=$((numdirs + numfiles * numcomp))
6489         [[ $filenum -eq $countfids ]] ||
6490                 error "$LFS getstripe -v $dir: "\
6491                       "got $filenum want $countfids lmm_fid"
6492         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6493                 error "$LFS getstripe $dir: showed lmm_fid by default"
6494         echo "$LFS getstripe --verbose passed"
6495
6496         #check for FID information
6497         local fid1=$($LFS getstripe --fid $dir/file1)
6498         local fid2=$($LFS getstripe --verbose $dir/file1 |
6499                      awk '/lmm_fid: / { print $2; exit; }')
6500         local fid3=$($LFS path2fid $dir/file1)
6501
6502         [ "$fid1" != "$fid2" ] &&
6503                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6504         [ "$fid1" != "$fid3" ] &&
6505                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6506         echo "$LFS getstripe --fid passed"
6507
6508         #test lfs getstripe with --obd
6509         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6510                 error "$LFS getstripe --obd wrong_uuid: should return error"
6511
6512         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6513
6514         local ostidx=1
6515         local obduuid=$(ostuuid_from_index $ostidx)
6516         local found=$($LFS getstripe -r --obd $obduuid $dir |
6517                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6518
6519         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6520         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6521                 ((filenum--))
6522         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6523                 ((filenum--))
6524
6525         [[ $found -eq $filenum ]] ||
6526                 error "$LFS getstripe --obd: found $found expect $filenum"
6527         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6528                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6529                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6530                 error "$LFS getstripe --obd: should not show file on other obd"
6531         echo "$LFS getstripe --obd passed"
6532 }
6533 run_test 56a "check $LFS getstripe"
6534
6535 test_56b() {
6536         local dir=$DIR/$tdir
6537         local numdirs=3
6538
6539         test_mkdir $dir
6540         for i in $(seq $numdirs); do
6541                 test_mkdir $dir/dir$i
6542         done
6543
6544         # test lfs getdirstripe default mode is non-recursion, which is
6545         # different from lfs getstripe
6546         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6547
6548         [[ $dircnt -eq 1 ]] ||
6549                 error "$LFS getdirstripe: found $dircnt, not 1"
6550         dircnt=$($LFS getdirstripe --recursive $dir |
6551                 grep -c lmv_stripe_count)
6552         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6553                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6554 }
6555 run_test 56b "check $LFS getdirstripe"
6556
6557 test_56bb() {
6558         verify_yaml_available || skip_env "YAML verification not installed"
6559         local output_file=$DIR/$tfile.out
6560
6561         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6562
6563         cat $output_file
6564         cat $output_file | verify_yaml || error "layout is not valid YAML"
6565 }
6566 run_test 56bb "check $LFS getdirstripe layout is YAML"
6567
6568 test_56c() {
6569         remote_ost_nodsh && skip "remote OST with nodsh"
6570
6571         local ost_idx=0
6572         local ost_name=$(ostname_from_index $ost_idx)
6573         local old_status=$(ost_dev_status $ost_idx)
6574         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6575
6576         [[ -z "$old_status" ]] ||
6577                 skip_env "OST $ost_name is in $old_status status"
6578
6579         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6580         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6581                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6582         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6583                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6584                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6585         fi
6586
6587         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6588                 error "$LFS df -v showing inactive devices"
6589         sleep_maxage
6590
6591         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6592
6593         [[ "$new_status" =~ "D" ]] ||
6594                 error "$ost_name status is '$new_status', missing 'D'"
6595         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6596                 [[ "$new_status" =~ "N" ]] ||
6597                         error "$ost_name status is '$new_status', missing 'N'"
6598         fi
6599         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6600                 [[ "$new_status" =~ "f" ]] ||
6601                         error "$ost_name status is '$new_status', missing 'f'"
6602         fi
6603
6604         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6605         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6606                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6607         [[ -z "$p" ]] && restore_lustre_params < $p || true
6608         sleep_maxage
6609
6610         new_status=$(ost_dev_status $ost_idx)
6611         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6612                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6613         # can't check 'f' as devices may actually be on flash
6614 }
6615 run_test 56c "check 'lfs df' showing device status"
6616
6617 test_56d() {
6618         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6619         local osts=$($LFS df -v $MOUNT | grep -c OST)
6620
6621         $LFS df $MOUNT
6622
6623         (( mdts == MDSCOUNT )) ||
6624                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6625         (( osts == OSTCOUNT )) ||
6626                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6627 }
6628 run_test 56d "'lfs df -v' prints only configured devices"
6629
6630 test_56e() {
6631         err_enoent=2 # No such file or directory
6632         err_eopnotsupp=95 # Operation not supported
6633
6634         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6635         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6636
6637         # Check for handling of path not exists
6638         output=$($LFS df $enoent_mnt 2>&1)
6639         ret=$?
6640
6641         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6642         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6643                 error "expect failure $err_enoent, not $ret"
6644
6645         # Check for handling of non-Lustre FS
6646         output=$($LFS df $notsup_mnt)
6647         ret=$?
6648
6649         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6650         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6651                 error "expect success $err_eopnotsupp, not $ret"
6652
6653         # Check for multiple LustreFS argument
6654         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6655         ret=$?
6656
6657         [[ $output -eq 3 && $ret -eq 0 ]] ||
6658                 error "expect success 3, not $output, rc = $ret"
6659
6660         # Check for correct non-Lustre FS handling among multiple
6661         # LustreFS argument
6662         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6663                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6664         ret=$?
6665
6666         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6667                 error "expect success 2, not $output, rc = $ret"
6668 }
6669 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6670
6671 NUMFILES=3
6672 NUMDIRS=3
6673 setup_56() {
6674         local local_tdir="$1"
6675         local local_numfiles="$2"
6676         local local_numdirs="$3"
6677         local dir_params="$4"
6678         local dir_stripe_params="$5"
6679
6680         if [ ! -d "$local_tdir" ] ; then
6681                 test_mkdir -p $dir_stripe_params $local_tdir
6682                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6683                 for i in $(seq $local_numfiles) ; do
6684                         touch $local_tdir/file$i
6685                 done
6686                 for i in $(seq $local_numdirs) ; do
6687                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6688                         for j in $(seq $local_numfiles) ; do
6689                                 touch $local_tdir/dir$i/file$j
6690                         done
6691                 done
6692         fi
6693 }
6694
6695 setup_56_special() {
6696         local local_tdir=$1
6697         local local_numfiles=$2
6698         local local_numdirs=$3
6699
6700         setup_56 $local_tdir $local_numfiles $local_numdirs
6701
6702         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6703                 for i in $(seq $local_numfiles) ; do
6704                         mknod $local_tdir/loop${i}b b 7 $i
6705                         mknod $local_tdir/null${i}c c 1 3
6706                         ln -s $local_tdir/file1 $local_tdir/link${i}
6707                 done
6708                 for i in $(seq $local_numdirs) ; do
6709                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6710                         mknod $local_tdir/dir$i/null${i}c c 1 3
6711                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6712                 done
6713         fi
6714 }
6715
6716 test_56g() {
6717         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6718         local expected=$(($NUMDIRS + 2))
6719
6720         setup_56 $dir $NUMFILES $NUMDIRS
6721
6722         # test lfs find with -name
6723         for i in $(seq $NUMFILES) ; do
6724                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6725
6726                 [ $nums -eq $expected ] ||
6727                         error "lfs find -name '*$i' $dir wrong: "\
6728                               "found $nums, expected $expected"
6729         done
6730 }
6731 run_test 56g "check lfs find -name"
6732
6733 test_56h() {
6734         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6735         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6736
6737         setup_56 $dir $NUMFILES $NUMDIRS
6738
6739         # test lfs find with ! -name
6740         for i in $(seq $NUMFILES) ; do
6741                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6742
6743                 [ $nums -eq $expected ] ||
6744                         error "lfs find ! -name '*$i' $dir wrong: "\
6745                               "found $nums, expected $expected"
6746         done
6747 }
6748 run_test 56h "check lfs find ! -name"
6749
6750 test_56i() {
6751         local dir=$DIR/$tdir
6752
6753         test_mkdir $dir
6754
6755         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6756         local out=$($cmd)
6757
6758         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6759 }
6760 run_test 56i "check 'lfs find -ost UUID' skips directories"
6761
6762 test_56j() {
6763         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6764
6765         setup_56_special $dir $NUMFILES $NUMDIRS
6766
6767         local expected=$((NUMDIRS + 1))
6768         local cmd="$LFS find -type d $dir"
6769         local nums=$($cmd | wc -l)
6770
6771         [ $nums -eq $expected ] ||
6772                 error "'$cmd' wrong: found $nums, expected $expected"
6773 }
6774 run_test 56j "check lfs find -type d"
6775
6776 test_56k() {
6777         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6778
6779         setup_56_special $dir $NUMFILES $NUMDIRS
6780
6781         local expected=$(((NUMDIRS + 1) * NUMFILES))
6782         local cmd="$LFS find -type f $dir"
6783         local nums=$($cmd | wc -l)
6784
6785         [ $nums -eq $expected ] ||
6786                 error "'$cmd' wrong: found $nums, expected $expected"
6787 }
6788 run_test 56k "check lfs find -type f"
6789
6790 test_56l() {
6791         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6792
6793         setup_56_special $dir $NUMFILES $NUMDIRS
6794
6795         local expected=$((NUMDIRS + NUMFILES))
6796         local cmd="$LFS find -type b $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801 }
6802 run_test 56l "check lfs find -type b"
6803
6804 test_56m() {
6805         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6806
6807         setup_56_special $dir $NUMFILES $NUMDIRS
6808
6809         local expected=$((NUMDIRS + NUMFILES))
6810         local cmd="$LFS find -type c $dir"
6811         local nums=$($cmd | wc -l)
6812         [ $nums -eq $expected ] ||
6813                 error "'$cmd' wrong: found $nums, expected $expected"
6814 }
6815 run_test 56m "check lfs find -type c"
6816
6817 test_56n() {
6818         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6819         setup_56_special $dir $NUMFILES $NUMDIRS
6820
6821         local expected=$((NUMDIRS + NUMFILES))
6822         local cmd="$LFS find -type l $dir"
6823         local nums=$($cmd | wc -l)
6824
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827 }
6828 run_test 56n "check lfs find -type l"
6829
6830 test_56o() {
6831         local dir=$DIR/$tdir
6832
6833         setup_56 $dir $NUMFILES $NUMDIRS
6834         utime $dir/file1 > /dev/null || error "utime (1)"
6835         utime $dir/file2 > /dev/null || error "utime (2)"
6836         utime $dir/dir1 > /dev/null || error "utime (3)"
6837         utime $dir/dir2 > /dev/null || error "utime (4)"
6838         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6839         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6840
6841         local expected=4
6842         local nums=$($LFS find -mtime +0 $dir | wc -l)
6843
6844         [ $nums -eq $expected ] ||
6845                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6846
6847         expected=12
6848         cmd="$LFS find -mtime 0 $dir"
6849         nums=$($cmd | wc -l)
6850         [ $nums -eq $expected ] ||
6851                 error "'$cmd' wrong: found $nums, expected $expected"
6852 }
6853 run_test 56o "check lfs find -mtime for old files"
6854
6855 test_56ob() {
6856         local dir=$DIR/$tdir
6857         local expected=1
6858         local count=0
6859
6860         # just to make sure there is something that won't be found
6861         test_mkdir $dir
6862         touch $dir/$tfile.now
6863
6864         for age in year week day hour min; do
6865                 count=$((count + 1))
6866
6867                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6868                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6869                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6870
6871                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6872                 local nums=$($cmd | wc -l)
6873                 [ $nums -eq $expected ] ||
6874                         error "'$cmd' wrong: found $nums, expected $expected"
6875
6876                 cmd="$LFS find $dir -atime $count${age:0:1}"
6877                 nums=$($cmd | wc -l)
6878                 [ $nums -eq $expected ] ||
6879                         error "'$cmd' wrong: found $nums, expected $expected"
6880         done
6881
6882         sleep 2
6883         cmd="$LFS find $dir -ctime +1s -type f"
6884         nums=$($cmd | wc -l)
6885         (( $nums == $count * 2 + 1)) ||
6886                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6887 }
6888 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6889
6890 test_newerXY_base() {
6891         local x=$1
6892         local y=$2
6893         local dir=$DIR/$tdir
6894         local ref
6895         local negref
6896
6897         if [ $y == "t" ]; then
6898                 if [ $x == "b" ]; then
6899                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6900                 else
6901                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6902                 fi
6903         else
6904                 ref=$DIR/$tfile.newer.$x$y
6905                 touch $ref || error "touch $ref failed"
6906         fi
6907
6908         echo "before = $ref"
6909         sleep 2
6910         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6911         sleep 2
6912         if [ $y == "t" ]; then
6913                 if [ $x == "b" ]; then
6914                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6915                 else
6916                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6917                 fi
6918         else
6919                 negref=$DIR/$tfile.negnewer.$x$y
6920                 touch $negref || error "touch $negref failed"
6921         fi
6922
6923         echo "after = $negref"
6924         local cmd="$LFS find $dir -newer$x$y $ref"
6925         local nums=$(eval $cmd | wc -l)
6926         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6927
6928         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6929                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6930
6931         cmd="$LFS find $dir ! -newer$x$y $negref"
6932         nums=$(eval $cmd | wc -l)
6933         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6934                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6935
6936         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6937         nums=$(eval $cmd | wc -l)
6938         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6939                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6940
6941         rm -rf $DIR/*
6942 }
6943
6944 test_56oc() {
6945         test_newerXY_base "a" "a"
6946         test_newerXY_base "a" "m"
6947         test_newerXY_base "a" "c"
6948         test_newerXY_base "m" "a"
6949         test_newerXY_base "m" "m"
6950         test_newerXY_base "m" "c"
6951         test_newerXY_base "c" "a"
6952         test_newerXY_base "c" "m"
6953         test_newerXY_base "c" "c"
6954
6955         test_newerXY_base "a" "t"
6956         test_newerXY_base "m" "t"
6957         test_newerXY_base "c" "t"
6958
6959         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6960            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6961                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6962
6963         test_newerXY_base "b" "b"
6964         test_newerXY_base "b" "t"
6965 }
6966 run_test 56oc "check lfs find -newerXY work"
6967
6968 test_56od() {
6969         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6970                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6971
6972         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6973                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
6974
6975         local dir=$DIR/$tdir
6976         local ref=$DIR/$tfile.ref
6977         local negref=$DIR/$tfile.negref
6978
6979         mkdir $dir || error "mkdir $dir failed"
6980         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6981         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6982         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6983         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6984         touch $ref || error "touch $ref failed"
6985         # sleep 3 seconds at least
6986         sleep 3
6987
6988         local before=$(do_facet mds1 date +%s)
6989         local skew=$(($(date +%s) - before + 1))
6990
6991         if (( skew < 0 && skew > -5 )); then
6992                 sleep $((0 - skew + 1))
6993                 skew=0
6994         fi
6995
6996         # Set the dir stripe params to limit files all on MDT0,
6997         # otherwise we need to calc the max clock skew between
6998         # the client and MDTs.
6999         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7000         sleep 2
7001         touch $negref || error "touch $negref failed"
7002
7003         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7004         local nums=$($cmd | wc -l)
7005         local expected=$(((NUMFILES + 1) * NUMDIRS))
7006
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009
7010         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7011         nums=$($cmd | wc -l)
7012         expected=$((NUMFILES + 1))
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015
7016         [ $skew -lt 0 ] && return
7017
7018         local after=$(do_facet mds1 date +%s)
7019         local age=$((after - before + 1 + skew))
7020
7021         cmd="$LFS find $dir -btime -${age}s -type f"
7022         nums=$($cmd | wc -l)
7023         expected=$(((NUMFILES + 1) * NUMDIRS))
7024
7025         echo "Clock skew between client and server: $skew, age:$age"
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028
7029         expected=$(($NUMDIRS + 1))
7030         cmd="$LFS find $dir -btime -${age}s -type d"
7031         nums=$($cmd | wc -l)
7032         [ $nums -eq $expected ] ||
7033                 error "'$cmd' wrong: found $nums, expected $expected"
7034         rm -f $ref $negref || error "Failed to remove $ref $negref"
7035 }
7036 run_test 56od "check lfs find -btime with units"
7037
7038 test_56p() {
7039         [ $RUNAS_ID -eq $UID ] &&
7040                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7041
7042         local dir=$DIR/$tdir
7043
7044         setup_56 $dir $NUMFILES $NUMDIRS
7045         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7046
7047         local expected=$NUMFILES
7048         local cmd="$LFS find -uid $RUNAS_ID $dir"
7049         local nums=$($cmd | wc -l)
7050
7051         [ $nums -eq $expected ] ||
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053
7054         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7055         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059 }
7060 run_test 56p "check lfs find -uid and ! -uid"
7061
7062 test_56q() {
7063         [ $RUNAS_ID -eq $UID ] &&
7064                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7065
7066         local dir=$DIR/$tdir
7067
7068         setup_56 $dir $NUMFILES $NUMDIRS
7069         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7070
7071         local expected=$NUMFILES
7072         local cmd="$LFS find -gid $RUNAS_GID $dir"
7073         local nums=$($cmd | wc -l)
7074
7075         [ $nums -eq $expected ] ||
7076                 error "'$cmd' wrong: found $nums, expected $expected"
7077
7078         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7079         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7080         nums=$($cmd | wc -l)
7081         [ $nums -eq $expected ] ||
7082                 error "'$cmd' wrong: found $nums, expected $expected"
7083 }
7084 run_test 56q "check lfs find -gid and ! -gid"
7085
7086 test_56r() {
7087         local dir=$DIR/$tdir
7088
7089         setup_56 $dir $NUMFILES $NUMDIRS
7090
7091         local expected=12
7092         local cmd="$LFS find -size 0 -type f -lazy $dir"
7093         local nums=$($cmd | wc -l)
7094
7095         [ $nums -eq $expected ] ||
7096                 error "'$cmd' wrong: found $nums, expected $expected"
7097         cmd="$LFS find -size 0 -type f $dir"
7098         nums=$($cmd | wc -l)
7099         [ $nums -eq $expected ] ||
7100                 error "'$cmd' wrong: found $nums, expected $expected"
7101
7102         expected=0
7103         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7104         nums=$($cmd | wc -l)
7105         [ $nums -eq $expected ] ||
7106                 error "'$cmd' wrong: found $nums, expected $expected"
7107         cmd="$LFS find ! -size 0 -type f $dir"
7108         nums=$($cmd | wc -l)
7109         [ $nums -eq $expected ] ||
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111
7112         echo "test" > $dir/$tfile
7113         echo "test2" > $dir/$tfile.2 && sync
7114         expected=1
7115         cmd="$LFS find -size 5 -type f -lazy $dir"
7116         nums=$($cmd | wc -l)
7117         [ $nums -eq $expected ] ||
7118                 error "'$cmd' wrong: found $nums, expected $expected"
7119         cmd="$LFS find -size 5 -type f $dir"
7120         nums=$($cmd | wc -l)
7121         [ $nums -eq $expected ] ||
7122                 error "'$cmd' wrong: found $nums, expected $expected"
7123
7124         expected=1
7125         cmd="$LFS find -size +5 -type f -lazy $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129         cmd="$LFS find -size +5 -type f $dir"
7130         nums=$($cmd | wc -l)
7131         [ $nums -eq $expected ] ||
7132                 error "'$cmd' wrong: found $nums, expected $expected"
7133
7134         expected=2
7135         cmd="$LFS find -size +0 -type f -lazy $dir"
7136         nums=$($cmd | wc -l)
7137         [ $nums -eq $expected ] ||
7138                 error "'$cmd' wrong: found $nums, expected $expected"
7139         cmd="$LFS find -size +0 -type f $dir"
7140         nums=$($cmd | wc -l)
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143
7144         expected=2
7145         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7146         nums=$($cmd | wc -l)
7147         [ $nums -eq $expected ] ||
7148                 error "'$cmd' wrong: found $nums, expected $expected"
7149         cmd="$LFS find ! -size -5 -type f $dir"
7150         nums=$($cmd | wc -l)
7151         [ $nums -eq $expected ] ||
7152                 error "'$cmd' wrong: found $nums, expected $expected"
7153
7154         expected=12
7155         cmd="$LFS find -size -5 -type f -lazy $dir"
7156         nums=$($cmd | wc -l)
7157         [ $nums -eq $expected ] ||
7158                 error "'$cmd' wrong: found $nums, expected $expected"
7159         cmd="$LFS find -size -5 -type f $dir"
7160         nums=$($cmd | wc -l)
7161         [ $nums -eq $expected ] ||
7162                 error "'$cmd' wrong: found $nums, expected $expected"
7163 }
7164 run_test 56r "check lfs find -size works"
7165
7166 test_56ra_sub() {
7167         local expected=$1
7168         local glimpses=$2
7169         local cmd="$3"
7170
7171         cancel_lru_locks $OSC
7172
7173         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7174         local nums=$($cmd | wc -l)
7175
7176         [ $nums -eq $expected ] ||
7177                 error "'$cmd' wrong: found $nums, expected $expected"
7178
7179         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7180
7181         if (( rpcs_before + glimpses != rpcs_after )); then
7182                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7183                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7184
7185                 if [[ $glimpses == 0 ]]; then
7186                         error "'$cmd' should not send glimpse RPCs to OST"
7187                 else
7188                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7189                 fi
7190         fi
7191 }
7192
7193 test_56ra() {
7194         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7195                 skip "MDS < 2.12.58 doesn't return LSOM data"
7196         local dir=$DIR/$tdir
7197         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7198
7199         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7200
7201         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7202         $LCTL set_param -n llite.*.statahead_agl=0
7203         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7204
7205         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7206         # open and close all files to ensure LSOM is updated
7207         cancel_lru_locks $OSC
7208         find $dir -type f | xargs cat > /dev/null
7209
7210         #   expect_found  glimpse_rpcs  command_to_run
7211         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7212         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7213         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7214         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7215
7216         echo "test" > $dir/$tfile
7217         echo "test2" > $dir/$tfile.2 && sync
7218         cancel_lru_locks $OSC
7219         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7220
7221         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7222         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7223         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7224         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7225
7226         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7227         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7228         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7229         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7230         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7231         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7232 }
7233 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7234
7235 test_56rb() {
7236         local dir=$DIR/$tdir
7237         local tmp=$TMP/$tfile.log
7238         local mdt_idx;
7239
7240         test_mkdir -p $dir || error "failed to mkdir $dir"
7241         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7242                 error "failed to setstripe $dir/$tfile"
7243         mdt_idx=$($LFS getdirstripe -i $dir)
7244         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7245
7246         stack_trap "rm -f $tmp" EXIT
7247         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7248         ! grep -q obd_uuid $tmp ||
7249                 error "failed to find --size +100K --ost 0 $dir"
7250         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7251         ! grep -q obd_uuid $tmp ||
7252                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7253 }
7254 run_test 56rb "check lfs find --size --ost/--mdt works"
7255
7256 test_56rc() {
7257         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7258         local dir=$DIR/$tdir
7259         local found
7260
7261         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7262         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7263         (( $MDSCOUNT > 2 )) &&
7264                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7265         mkdir $dir/$tdir-{1..10}
7266         touch $dir/$tfile-{1..10}
7267
7268         found=$($LFS find $dir --mdt-count 2 | wc -l)
7269         expect=11
7270         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7271
7272         found=$($LFS find $dir -T +1 | wc -l)
7273         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7274         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7275
7276         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7277         expect=11
7278         (( $found == $expect )) || error "found $found all_char, expect $expect"
7279
7280         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7281         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7282         (( $found == $expect )) || error "found $found all_char, expect $expect"
7283 }
7284 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7285
7286 test_56rd() {
7287         local dir=$DIR/$tdir
7288
7289         test_mkdir $dir
7290         rm -f $dir/*
7291
7292         mkfifo $dir/fifo || error "failed to create fifo file"
7293         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7294                 error "should not fail even cannot get projid from pipe file"
7295         found=$($LFS find $dir -t p --printf "%y")
7296         [[ "p" == $found ]] || error "found $found, expect p"
7297
7298         mknod $dir/chardev c 1 5 ||
7299                 error "failed to create character device file"
7300         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7301                 error "should not fail even cannot get projid from chardev file"
7302         found=$($LFS find $dir -t c --printf "%y")
7303         [[ "c" == $found ]] || error "found $found, expect c"
7304
7305         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7306         (( found == 2 )) || error "unable to list all files"
7307 }
7308 run_test 56rd "check lfs find --printf special files"
7309
7310 test_56s() { # LU-611 #LU-9369
7311         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7312
7313         local dir=$DIR/$tdir
7314         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7315
7316         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7317         for i in $(seq $NUMDIRS); do
7318                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7319         done
7320
7321         local expected=$NUMDIRS
7322         local cmd="$LFS find -c $OSTCOUNT $dir"
7323         local nums=$($cmd | wc -l)
7324
7325         [ $nums -eq $expected ] || {
7326                 $LFS getstripe -R $dir
7327                 error "'$cmd' wrong: found $nums, expected $expected"
7328         }
7329
7330         expected=$((NUMDIRS + onestripe))
7331         cmd="$LFS find -stripe-count +0 -type f $dir"
7332         nums=$($cmd | wc -l)
7333         [ $nums -eq $expected ] || {
7334                 $LFS getstripe -R $dir
7335                 error "'$cmd' wrong: found $nums, expected $expected"
7336         }
7337
7338         expected=$onestripe
7339         cmd="$LFS find -stripe-count 1 -type f $dir"
7340         nums=$($cmd | wc -l)
7341         [ $nums -eq $expected ] || {
7342                 $LFS getstripe -R $dir
7343                 error "'$cmd' wrong: found $nums, expected $expected"
7344         }
7345
7346         cmd="$LFS find -stripe-count -2 -type f $dir"
7347         nums=$($cmd | wc -l)
7348         [ $nums -eq $expected ] || {
7349                 $LFS getstripe -R $dir
7350                 error "'$cmd' wrong: found $nums, expected $expected"
7351         }
7352
7353         expected=0
7354         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7355         nums=$($cmd | wc -l)
7356         [ $nums -eq $expected ] || {
7357                 $LFS getstripe -R $dir
7358                 error "'$cmd' wrong: found $nums, expected $expected"
7359         }
7360 }
7361 run_test 56s "check lfs find -stripe-count works"
7362
7363 test_56t() { # LU-611 #LU-9369
7364         local dir=$DIR/$tdir
7365
7366         setup_56 $dir 0 $NUMDIRS
7367         for i in $(seq $NUMDIRS); do
7368                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7369         done
7370
7371         local expected=$NUMDIRS
7372         local cmd="$LFS find -S 8M $dir"
7373         local nums=$($cmd | wc -l)
7374
7375         [ $nums -eq $expected ] || {
7376                 $LFS getstripe -R $dir
7377                 error "'$cmd' wrong: found $nums, expected $expected"
7378         }
7379         rm -rf $dir
7380
7381         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7382
7383         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7384
7385         expected=$(((NUMDIRS + 1) * NUMFILES))
7386         cmd="$LFS find -stripe-size 512k -type f $dir"
7387         nums=$($cmd | wc -l)
7388         [ $nums -eq $expected ] ||
7389                 error "'$cmd' wrong: found $nums, expected $expected"
7390
7391         cmd="$LFS find -stripe-size +320k -type f $dir"
7392         nums=$($cmd | wc -l)
7393         [ $nums -eq $expected ] ||
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395
7396         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7397         cmd="$LFS find -stripe-size +200k -type f $dir"
7398         nums=$($cmd | wc -l)
7399         [ $nums -eq $expected ] ||
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401
7402         cmd="$LFS find -stripe-size -640k -type f $dir"
7403         nums=$($cmd | wc -l)
7404         [ $nums -eq $expected ] ||
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406
7407         expected=4
7408         cmd="$LFS find -stripe-size 256k -type f $dir"
7409         nums=$($cmd | wc -l)
7410         [ $nums -eq $expected ] ||
7411                 error "'$cmd' wrong: found $nums, expected $expected"
7412
7413         cmd="$LFS find -stripe-size -320k -type f $dir"
7414         nums=$($cmd | wc -l)
7415         [ $nums -eq $expected ] ||
7416                 error "'$cmd' wrong: found $nums, expected $expected"
7417
7418         expected=0
7419         cmd="$LFS find -stripe-size 1024k -type f $dir"
7420         nums=$($cmd | wc -l)
7421         [ $nums -eq $expected ] ||
7422                 error "'$cmd' wrong: found $nums, expected $expected"
7423 }
7424 run_test 56t "check lfs find -stripe-size works"
7425
7426 test_56u() { # LU-611
7427         local dir=$DIR/$tdir
7428
7429         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7430
7431         if [[ $OSTCOUNT -gt 1 ]]; then
7432                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7433                 onestripe=4
7434         else
7435                 onestripe=0
7436         fi
7437
7438         local expected=$(((NUMDIRS + 1) * NUMFILES))
7439         local cmd="$LFS find -stripe-index 0 -type f $dir"
7440         local nums=$($cmd | wc -l)
7441
7442         [ $nums -eq $expected ] ||
7443                 error "'$cmd' wrong: found $nums, expected $expected"
7444
7445         expected=$onestripe
7446         cmd="$LFS find -stripe-index 1 -type f $dir"
7447         nums=$($cmd | wc -l)
7448         [ $nums -eq $expected ] ||
7449                 error "'$cmd' wrong: found $nums, expected $expected"
7450
7451         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7452         nums=$($cmd | wc -l)
7453         [ $nums -eq $expected ] ||
7454                 error "'$cmd' wrong: found $nums, expected $expected"
7455
7456         expected=0
7457         # This should produce an error and not return any files
7458         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7459         nums=$($cmd 2>/dev/null | wc -l)
7460         [ $nums -eq $expected ] ||
7461                 error "'$cmd' wrong: found $nums, expected $expected"
7462
7463         if [[ $OSTCOUNT -gt 1 ]]; then
7464                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7465                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7466                 nums=$($cmd | wc -l)
7467                 [ $nums -eq $expected ] ||
7468                         error "'$cmd' wrong: found $nums, expected $expected"
7469         fi
7470 }
7471 run_test 56u "check lfs find -stripe-index works"
7472
7473 test_56v() {
7474         local mdt_idx=0
7475         local dir=$DIR/$tdir
7476
7477         setup_56 $dir $NUMFILES $NUMDIRS
7478
7479         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7480         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7481
7482         for file in $($LFS find -m $UUID $dir); do
7483                 file_midx=$($LFS getstripe -m $file)
7484                 [ $file_midx -eq $mdt_idx ] ||
7485                         error "lfs find -m $UUID != getstripe -m $file_midx"
7486         done
7487 }
7488 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7489
7490 test_56wa() {
7491         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7493
7494         local dir=$DIR/$tdir
7495
7496         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7497         stack_trap "rm -rf $dir"
7498
7499         local stripe_size=$($LFS getstripe -S -d $dir) ||
7500                 error "$LFS getstripe -S -d $dir failed"
7501         stripe_size=${stripe_size%% *}
7502
7503         local file_size=$((stripe_size * OSTCOUNT))
7504         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7505         local required_space=$((file_num * file_size))
7506         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7507                            head -n1)
7508         (( free_space >= required_space / 1024 )) ||
7509                 skip_env "need $required_space, have $free_space kbytes"
7510
7511         local dd_bs=65536
7512         local dd_count=$((file_size / dd_bs))
7513
7514         # write data into the files
7515         local i
7516         local j
7517         local file
7518
7519         for ((i = 1; i <= NUMFILES; i++ )); do
7520                 file=$dir/file$i
7521                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7522                         error "write data into $file failed"
7523         done
7524         for ((i = 1; i <= NUMDIRS; i++ )); do
7525                 for ((j = 1; j <= NUMFILES; j++ )); do
7526                         file=$dir/dir$i/file$j
7527                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7528                                 error "write data into $file failed"
7529                 done
7530         done
7531
7532         # $LFS_MIGRATE will fail if hard link migration is unsupported
7533         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7534                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7535                         error "creating links to $dir/dir1/file1 failed"
7536         fi
7537
7538         local expected=-1
7539
7540         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7541
7542         # lfs_migrate file
7543         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7544
7545         echo "$cmd"
7546         eval $cmd || error "$cmd failed"
7547
7548         check_stripe_count $dir/file1 $expected
7549
7550         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7551                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7552                 # OST 1 if it is on OST 0. This file is small enough to
7553                 # be on only one stripe.
7554                 file=$dir/migr_1_ost
7555                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7556                         error "write data into $file failed"
7557                 local obdidx=$($LFS getstripe -i $file)
7558                 local oldmd5=$(md5sum $file)
7559                 local newobdidx=0
7560
7561                 (( obdidx != 0 )) || newobdidx=1
7562                 cmd="$LFS migrate -i $newobdidx $file"
7563                 echo $cmd
7564                 eval $cmd || error "$cmd failed"
7565
7566                 local realobdix=$($LFS getstripe -i $file)
7567                 local newmd5=$(md5sum $file)
7568
7569                 (( $newobdidx == $realobdix )) ||
7570                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7571                 [[ "$oldmd5" == "$newmd5" ]] ||
7572                         error "md5sum differ: $oldmd5, $newmd5"
7573         fi
7574
7575         # lfs_migrate dir
7576         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7577         echo "$cmd"
7578         eval $cmd || error "$cmd failed"
7579
7580         for (( j = 1; j <= NUMFILES; j++ )); do
7581                 check_stripe_count $dir/dir1/file$j $expected
7582         done
7583
7584         # lfs_migrate works with lfs find
7585         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7586              $LFS_MIGRATE -y -c $expected"
7587         echo "$cmd"
7588         eval $cmd || error "$cmd failed"
7589
7590         for (( i = 2; i <= NUMFILES; i++ )); do
7591                 check_stripe_count $dir/file$i $expected
7592         done
7593         for (( i = 2; i <= NUMDIRS; i++ )); do
7594                 for (( j = 1; j <= NUMFILES; j++ )); do
7595                         check_stripe_count $dir/dir$i/file$j $expected
7596                 done
7597         done
7598 }
7599 run_test 56wa "check lfs_migrate -c stripe_count works"
7600
7601 test_56wb() {
7602         local file1=$DIR/$tdir/file1
7603         local create_pool=false
7604         local initial_pool=$($LFS getstripe -p $DIR)
7605         local pool_list=()
7606         local pool=""
7607
7608         echo -n "Creating test dir..."
7609         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7610         echo "done."
7611
7612         echo -n "Creating test file..."
7613         touch $file1 || error "cannot create file"
7614         echo "done."
7615
7616         echo -n "Detecting existing pools..."
7617         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7618
7619         if [ ${#pool_list[@]} -gt 0 ]; then
7620                 echo "${pool_list[@]}"
7621                 for thispool in "${pool_list[@]}"; do
7622                         if [[ -z "$initial_pool" ||
7623                               "$initial_pool" != "$thispool" ]]; then
7624                                 pool="$thispool"
7625                                 echo "Using existing pool '$pool'"
7626                                 break
7627                         fi
7628                 done
7629         else
7630                 echo "none detected."
7631         fi
7632         if [ -z "$pool" ]; then
7633                 pool=${POOL:-testpool}
7634                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7635                 echo -n "Creating pool '$pool'..."
7636                 create_pool=true
7637                 pool_add $pool &> /dev/null ||
7638                         error "pool_add failed"
7639                 echo "done."
7640
7641                 echo -n "Adding target to pool..."
7642                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7643                         error "pool_add_targets failed"
7644                 echo "done."
7645         fi
7646
7647         echo -n "Setting pool using -p option..."
7648         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7649                 error "migrate failed rc = $?"
7650         echo "done."
7651
7652         echo -n "Verifying test file is in pool after migrating..."
7653         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7654                 error "file was not migrated to pool $pool"
7655         echo "done."
7656
7657         echo -n "Removing test file from pool '$pool'..."
7658         # "lfs migrate $file" won't remove the file from the pool
7659         # until some striping information is changed.
7660         $LFS migrate -c 1 $file1 &> /dev/null ||
7661                 error "cannot remove from pool"
7662         [ "$($LFS getstripe -p $file1)" ] &&
7663                 error "pool still set"
7664         echo "done."
7665
7666         echo -n "Setting pool using --pool option..."
7667         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7668                 error "migrate failed rc = $?"
7669         echo "done."
7670
7671         # Clean up
7672         rm -f $file1
7673         if $create_pool; then
7674                 destroy_test_pools 2> /dev/null ||
7675                         error "destroy test pools failed"
7676         fi
7677 }
7678 run_test 56wb "check lfs_migrate pool support"
7679
7680 test_56wc() {
7681         local file1="$DIR/$tdir/$tfile"
7682         local md5
7683         local parent_ssize
7684         local parent_scount
7685         local cur_ssize
7686         local cur_scount
7687         local orig_ssize
7688         local new_scount
7689         local cur_comp
7690
7691         echo -n "Creating test dir..."
7692         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7693         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7694                 error "cannot set stripe by '-S 1M -c 1'"
7695         echo "done"
7696
7697         echo -n "Setting initial stripe for test file..."
7698         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7699                 error "cannot set stripe"
7700         cur_ssize=$($LFS getstripe -S "$file1")
7701         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7702         echo "done."
7703
7704         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7705         stack_trap "rm -f $file1"
7706         md5="$(md5sum $file1)"
7707
7708         # File currently set to -S 512K -c 1
7709
7710         # Ensure -c and -S options are rejected when -R is set
7711         echo -n "Verifying incompatible options are detected..."
7712         $LFS_MIGRATE -R -c 1 "$file1" &&
7713                 error "incompatible -R and -c options not detected"
7714         $LFS_MIGRATE -R -S 1M "$file1" &&
7715                 error "incompatible -R and -S options not detected"
7716         $LFS_MIGRATE -R -p pool "$file1" &&
7717                 error "incompatible -R and -p options not detected"
7718         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7719                 error "incompatible -R and -E options not detected"
7720         $LFS_MIGRATE -R -A "$file1" &&
7721                 error "incompatible -R and -A options not detected"
7722         $LFS_MIGRATE -A -c 1 "$file1" &&
7723                 error "incompatible -A and -c options not detected"
7724         $LFS_MIGRATE -A -S 1M "$file1" &&
7725                 error "incompatible -A and -S options not detected"
7726         $LFS_MIGRATE -A -p pool "$file1" &&
7727                 error "incompatible -A and -p options not detected"
7728         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7729                 error "incompatible -A and -E options not detected"
7730         echo "done."
7731
7732         # Ensure unrecognized options are passed through to 'lfs migrate'
7733         echo -n "Verifying -S option is passed through to lfs migrate..."
7734         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7735         cur_ssize=$($LFS getstripe -S "$file1")
7736         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7737         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7738         echo "done."
7739
7740         # File currently set to -S 1M -c 1
7741
7742         # Ensure long options are supported
7743         echo -n "Verifying long options supported..."
7744         $LFS_MIGRATE --non-block "$file1" ||
7745                 error "long option without argument not supported"
7746         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7747                 error "long option with argument not supported"
7748         cur_ssize=$($LFS getstripe -S "$file1")
7749         (( cur_ssize == 524288 )) ||
7750                 error "migrate --stripe-size $cur_ssize != 524288"
7751         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7752         echo "done."
7753
7754         # File currently set to -S 512K -c 1
7755
7756         if (( OSTCOUNT > 1 )); then
7757                 echo -n "Verifying explicit stripe count can be set..."
7758                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7759                 cur_scount=$($LFS getstripe -c "$file1")
7760                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7761                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7762                         error "file data has changed (3)"
7763                 echo "done."
7764         fi
7765
7766         # File currently set to -S 512K -c 1 or -S 512K -c 2
7767
7768         # Ensure parent striping is used if -R is set, and no stripe
7769         # count or size is specified
7770         echo -n "Setting stripe for parent directory..."
7771         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7772                 error "cannot set stripe '-S 2M -c 1'"
7773         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7774         echo "done."
7775
7776         echo -n "Verifying restripe option uses parent stripe settings..."
7777         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7778         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7779         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7780         cur_ssize=$($LFS getstripe -S "$file1")
7781         (( cur_ssize == parent_ssize )) ||
7782                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7783         cur_scount=$($LFS getstripe -c "$file1")
7784         (( cur_scount == parent_scount )) ||
7785                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7786         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7787         echo "done."
7788
7789         # File currently set to -S 1M -c 1
7790
7791         # Ensure striping is preserved if -R is not set, and no stripe
7792         # count or size is specified
7793         echo -n "Verifying striping size preserved when not specified..."
7794         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7795         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7796                 error "cannot set stripe on parent directory"
7797         $LFS_MIGRATE "$file1" || error "migrate failed"
7798         cur_ssize=$($LFS getstripe -S "$file1")
7799         (( cur_ssize == orig_ssize )) ||
7800                 error "migrate by default $cur_ssize != $orig_ssize"
7801         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7802         echo "done."
7803
7804         # Ensure file name properly detected when final option has no argument
7805         echo -n "Verifying file name properly detected..."
7806         $LFS_MIGRATE "$file1" ||
7807                 error "file name interpreted as option argument"
7808         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7809         echo "done."
7810
7811         # Ensure PFL arguments are passed through properly
7812         echo -n "Verifying PFL options passed through..."
7813         new_scount=$(((OSTCOUNT + 1) / 2))
7814         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7815                 error "migrate PFL arguments failed"
7816         cur_comp=$($LFS getstripe --comp-count $file1)
7817         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7818         cur_scount=$($LFS getstripe --stripe-count $file1)
7819         (( cur_scount == new_scount)) ||
7820                 error "PFL stripe count $cur_scount != $new_scount"
7821         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7822         echo "done."
7823 }
7824 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7825
7826 test_56wd() {
7827         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7828
7829         local file1=$DIR/$tdir/$tfile
7830
7831         echo -n "Creating test dir..."
7832         test_mkdir $DIR/$tdir || error "cannot create dir"
7833         echo "done."
7834
7835         echo -n "Creating test file..."
7836         echo "$tfile" > $file1
7837         echo "done."
7838
7839         # Ensure 'lfs migrate' will fail by using a non-existent option,
7840         # and make sure rsync is not called to recover
7841         echo -n "Make sure --no-rsync option works..."
7842         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7843                 grep -q 'refusing to fall back to rsync' ||
7844                 error "rsync was called with --no-rsync set"
7845         echo "done."
7846
7847         # Ensure rsync is called without trying 'lfs migrate' first
7848         echo -n "Make sure --rsync option works..."
7849         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7850                 grep -q 'falling back to rsync' &&
7851                 error "lfs migrate was called with --rsync set"
7852         echo "done."
7853 }
7854 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7855
7856 test_56we() {
7857         local td=$DIR/$tdir
7858         local tf=$td/$tfile
7859
7860         test_mkdir $td || error "cannot create $td"
7861         touch $tf || error "cannot touch $tf"
7862
7863         echo -n "Make sure --non-direct|-D works..."
7864         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7865                 grep -q "lfs migrate --non-direct" ||
7866                 error "--non-direct option cannot work correctly"
7867         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7868                 grep -q "lfs migrate -D" ||
7869                 error "-D option cannot work correctly"
7870         echo "done."
7871 }
7872 run_test 56we "check lfs_migrate --non-direct|-D support"
7873
7874 test_56x() {
7875         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7876         check_swap_layouts_support
7877
7878         local dir=$DIR/$tdir
7879         local ref1=/etc/passwd
7880         local file1=$dir/file1
7881
7882         test_mkdir $dir || error "creating dir $dir"
7883         $LFS setstripe -c 2 $file1
7884         cp $ref1 $file1
7885         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7886         stripe=$($LFS getstripe -c $file1)
7887         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7888         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7889
7890         # clean up
7891         rm -f $file1
7892 }
7893 run_test 56x "lfs migration support"
7894
7895 test_56xa() {
7896         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7897         check_swap_layouts_support
7898
7899         local dir=$DIR/$tdir/$testnum
7900
7901         test_mkdir -p $dir
7902
7903         local ref1=/etc/passwd
7904         local file1=$dir/file1
7905
7906         $LFS setstripe -c 2 $file1
7907         cp $ref1 $file1
7908         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7909
7910         local stripe=$($LFS getstripe -c $file1)
7911
7912         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7913         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7914
7915         # clean up
7916         rm -f $file1
7917 }
7918 run_test 56xa "lfs migration --block support"
7919
7920 check_migrate_links() {
7921         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7922         local dir="$1"
7923         local file1="$dir/file1"
7924         local begin="$2"
7925         local count="$3"
7926         local runas="$4"
7927         local total_count=$(($begin + $count - 1))
7928         local symlink_count=10
7929         local uniq_count=10
7930
7931         if [ ! -f "$file1" ]; then
7932                 echo -n "creating initial file..."
7933                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7934                         error "cannot setstripe initial file"
7935                 echo "done"
7936
7937                 echo -n "creating symlinks..."
7938                 for s in $(seq 1 $symlink_count); do
7939                         ln -s "$file1" "$dir/slink$s" ||
7940                                 error "cannot create symlinks"
7941                 done
7942                 echo "done"
7943
7944                 echo -n "creating nonlinked files..."
7945                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7946                         error "cannot create nonlinked files"
7947                 echo "done"
7948         fi
7949
7950         # create hard links
7951         if [ ! -f "$dir/file$total_count" ]; then
7952                 echo -n "creating hard links $begin:$total_count..."
7953                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7954                         /dev/null || error "cannot create hard links"
7955                 echo "done"
7956         fi
7957
7958         echo -n "checking number of hard links listed in xattrs..."
7959         local fid=$($LFS getstripe -F "$file1")
7960         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7961
7962         echo "${#paths[*]}"
7963         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7964                         skip "hard link list has unexpected size, skipping test"
7965         fi
7966         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7967                         error "link names should exceed xattrs size"
7968         fi
7969
7970         echo -n "migrating files..."
7971         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7972         local rc=$?
7973         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7974         echo "done"
7975
7976         # make sure all links have been properly migrated
7977         echo -n "verifying files..."
7978         fid=$($LFS getstripe -F "$file1") ||
7979                 error "cannot get fid for file $file1"
7980         for i in $(seq 2 $total_count); do
7981                 local fid2=$($LFS getstripe -F $dir/file$i)
7982
7983                 [ "$fid2" == "$fid" ] ||
7984                         error "migrated hard link has mismatched FID"
7985         done
7986
7987         # make sure hard links were properly detected, and migration was
7988         # performed only once for the entire link set; nonlinked files should
7989         # also be migrated
7990         local actual=$(grep -c 'done' <<< "$migrate_out")
7991         local expected=$(($uniq_count + 1))
7992
7993         [ "$actual" -eq  "$expected" ] ||
7994                 error "hard links individually migrated ($actual != $expected)"
7995
7996         # make sure the correct number of hard links are present
7997         local hardlinks=$(stat -c '%h' "$file1")
7998
7999         [ $hardlinks -eq $total_count ] ||
8000                 error "num hard links $hardlinks != $total_count"
8001         echo "done"
8002
8003         return 0
8004 }
8005
8006 test_56xb() {
8007         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8008                 skip "Need MDS version at least 2.10.55"
8009
8010         local dir="$DIR/$tdir"
8011
8012         test_mkdir "$dir" || error "cannot create dir $dir"
8013
8014         echo "testing lfs migrate mode when all links fit within xattrs"
8015         check_migrate_links "$dir" 2 99
8016
8017         echo "testing rsync mode when all links fit within xattrs"
8018         check_migrate_links --rsync "$dir" 2 99
8019
8020         echo "testing lfs migrate mode when all links do not fit within xattrs"
8021         check_migrate_links "$dir" 101 100
8022
8023         echo "testing rsync mode when all links do not fit within xattrs"
8024         check_migrate_links --rsync "$dir" 101 100
8025
8026         chown -R $RUNAS_ID $dir
8027         echo "testing non-root lfs migrate mode when not all links are in xattr"
8028         check_migrate_links "$dir" 101 100 "$RUNAS"
8029
8030         # clean up
8031         rm -rf $dir
8032 }
8033 run_test 56xb "lfs migration hard link support"
8034
8035 test_56xc() {
8036         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8037
8038         local dir="$DIR/$tdir"
8039
8040         test_mkdir "$dir" || error "cannot create dir $dir"
8041
8042         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8043         echo -n "Setting initial stripe for 20MB test file..."
8044         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8045                 error "cannot setstripe 20MB file"
8046         echo "done"
8047         echo -n "Sizing 20MB test file..."
8048         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8049         echo "done"
8050         echo -n "Verifying small file autostripe count is 1..."
8051         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8052                 error "cannot migrate 20MB file"
8053         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8054                 error "cannot get stripe for $dir/20mb"
8055         [ $stripe_count -eq 1 ] ||
8056                 error "unexpected stripe count $stripe_count for 20MB file"
8057         rm -f "$dir/20mb"
8058         echo "done"
8059
8060         # Test 2: File is small enough to fit within the available space on
8061         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8062         # have at least an additional 1KB for each desired stripe for test 3
8063         echo -n "Setting stripe for 1GB test file..."
8064         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8065         echo "done"
8066         echo -n "Sizing 1GB test file..."
8067         # File size is 1GB + 3KB
8068         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8069         echo "done"
8070
8071         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8072         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8073         if (( avail > 524288 * OSTCOUNT )); then
8074                 echo -n "Migrating 1GB file..."
8075                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8076                         error "cannot migrate 1GB file"
8077                 echo "done"
8078                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8079                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8080                         error "cannot getstripe for 1GB file"
8081                 [ $stripe_count -eq 2 ] ||
8082                         error "unexpected stripe count $stripe_count != 2"
8083                 echo "done"
8084         fi
8085
8086         # Test 3: File is too large to fit within the available space on
8087         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8088         if [ $OSTCOUNT -ge 3 ]; then
8089                 # The required available space is calculated as
8090                 # file size (1GB + 3KB) / OST count (3).
8091                 local kb_per_ost=349526
8092
8093                 echo -n "Migrating 1GB file with limit..."
8094                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8095                         error "cannot migrate 1GB file with limit"
8096                 echo "done"
8097
8098                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8099                 echo -n "Verifying 1GB autostripe count with limited space..."
8100                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8101                         error "unexpected stripe count $stripe_count (min 3)"
8102                 echo "done"
8103         fi
8104
8105         # clean up
8106         rm -rf $dir
8107 }
8108 run_test 56xc "lfs migration autostripe"
8109
8110 test_56xd() {
8111         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8112
8113         local dir=$DIR/$tdir
8114         local f_mgrt=$dir/$tfile.mgrt
8115         local f_yaml=$dir/$tfile.yaml
8116         local f_copy=$dir/$tfile.copy
8117         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8118         local layout_copy="-c 2 -S 2M -i 1"
8119         local yamlfile=$dir/yamlfile
8120         local layout_before;
8121         local layout_after;
8122
8123         test_mkdir "$dir" || error "cannot create dir $dir"
8124         stack_trap "rm -rf $dir"
8125         $LFS setstripe $layout_yaml $f_yaml ||
8126                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8127         $LFS getstripe --yaml $f_yaml > $yamlfile
8128         $LFS setstripe $layout_copy $f_copy ||
8129                 error "cannot setstripe $f_copy with layout $layout_copy"
8130         touch $f_mgrt
8131         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8132
8133         # 1. test option --yaml
8134         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8135                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8136         layout_before=$(get_layout_param $f_yaml)
8137         layout_after=$(get_layout_param $f_mgrt)
8138         [ "$layout_after" == "$layout_before" ] ||
8139                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8140
8141         # 2. test option --copy
8142         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8143                 error "cannot migrate $f_mgrt with --copy $f_copy"
8144         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8145         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8146         [ "$layout_after" == "$layout_before" ] ||
8147                 error "lfs_migrate --copy: $layout_after != $layout_before"
8148 }
8149 run_test 56xd "check lfs_migrate --yaml and --copy support"
8150
8151 test_56xe() {
8152         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8153
8154         local dir=$DIR/$tdir
8155         local f_comp=$dir/$tfile
8156         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8157         local layout_before=""
8158         local layout_after=""
8159
8160         test_mkdir "$dir" || error "cannot create dir $dir"
8161         stack_trap "rm -rf $dir"
8162         $LFS setstripe $layout $f_comp ||
8163                 error "cannot setstripe $f_comp with layout $layout"
8164         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8165         dd if=/dev/zero of=$f_comp bs=1M count=4
8166
8167         # 1. migrate a comp layout file by lfs_migrate
8168         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8169         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8170         [ "$layout_before" == "$layout_after" ] ||
8171                 error "lfs_migrate: $layout_before != $layout_after"
8172
8173         # 2. migrate a comp layout file by lfs migrate
8174         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8175         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8176         [ "$layout_before" == "$layout_after" ] ||
8177                 error "lfs migrate: $layout_before != $layout_after"
8178 }
8179 run_test 56xe "migrate a composite layout file"
8180
8181 test_56xf() {
8182         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8183
8184         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8185                 skip "Need server version at least 2.13.53"
8186
8187         local dir=$DIR/$tdir
8188         local f_comp=$dir/$tfile
8189         local layout="-E 1M -c1 -E -1 -c2"
8190         local fid_before=""
8191         local fid_after=""
8192
8193         test_mkdir "$dir" || error "cannot create dir $dir"
8194         stack_trap "rm -rf $dir"
8195         $LFS setstripe $layout $f_comp ||
8196                 error "cannot setstripe $f_comp with layout $layout"
8197         fid_before=$($LFS getstripe --fid $f_comp)
8198         dd if=/dev/zero of=$f_comp bs=1M count=4
8199
8200         # 1. migrate a comp layout file to a comp layout
8201         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8202         fid_after=$($LFS getstripe --fid $f_comp)
8203         [ "$fid_before" == "$fid_after" ] ||
8204                 error "comp-to-comp migrate: $fid_before != $fid_after"
8205
8206         # 2. migrate a comp layout file to a plain layout
8207         $LFS migrate -c2 $f_comp ||
8208                 error "cannot migrate $f_comp by lfs migrate"
8209         fid_after=$($LFS getstripe --fid $f_comp)
8210         [ "$fid_before" == "$fid_after" ] ||
8211                 error "comp-to-plain migrate: $fid_before != $fid_after"
8212
8213         # 3. migrate a plain layout file to a comp layout
8214         $LFS migrate $layout $f_comp ||
8215                 error "cannot migrate $f_comp by lfs migrate"
8216         fid_after=$($LFS getstripe --fid $f_comp)
8217         [ "$fid_before" == "$fid_after" ] ||
8218                 error "plain-to-comp migrate: $fid_before != $fid_after"
8219 }
8220 run_test 56xf "FID is not lost during migration of a composite layout file"
8221
8222 check_file_ost_range() {
8223         local file="$1"
8224         shift
8225         local range="$*"
8226         local -a file_range
8227         local idx
8228
8229         file_range=($($LFS getstripe -y "$file" |
8230                 awk '/l_ost_idx:/ { print $NF }'))
8231
8232         if [[ "${#file_range[@]}" = 0 ]]; then
8233                 echo "No osts found for $file"
8234                 return 1
8235         fi
8236
8237         for idx in "${file_range[@]}"; do
8238                 [[ " $range " =~ " $idx " ]] ||
8239                         return 1
8240         done
8241
8242         return 0
8243 }
8244
8245 sub_test_56xg() {
8246         local stripe_opt="$1"
8247         local pool="$2"
8248         shift 2
8249         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8250
8251         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8252                 error "Fail to migrate $tfile on $pool"
8253         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8254                 error "$tfile is not in pool $pool"
8255         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8256                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8257 }
8258
8259 test_56xg() {
8260         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8261         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8262         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8263                 skip "Need MDS version newer than 2.14.52"
8264
8265         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8266         local -a pool_ranges=("0 0" "1 1" "0 1")
8267
8268         # init pools
8269         for i in "${!pool_names[@]}"; do
8270                 pool_add ${pool_names[$i]} ||
8271                         error "pool_add failed (pool: ${pool_names[$i]})"
8272                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8273                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8274         done
8275
8276         # init the file to migrate
8277         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8278                 error "Unable to create $tfile on OST1"
8279         stack_trap "rm -f $DIR/$tfile"
8280         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8281                 error "Unable to write on $tfile"
8282
8283         echo "1. migrate $tfile on pool ${pool_names[0]}"
8284         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8285
8286         echo "2. migrate $tfile on pool ${pool_names[2]}"
8287         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8288
8289         echo "3. migrate $tfile on pool ${pool_names[1]}"
8290         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8291
8292         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8293         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8294         echo
8295
8296         # Clean pools
8297         destroy_test_pools ||
8298                 error "pool_destroy failed"
8299 }
8300 run_test 56xg "lfs migrate pool support"
8301
8302 test_56xh() {
8303         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8304
8305         local size_mb=25
8306         local file1=$DIR/$tfile
8307         local tmp1=$TMP/$tfile.tmp
8308
8309         $LFS setstripe -c 2 $file1
8310
8311         stack_trap "rm -f $file1 $tmp1"
8312         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8313                         error "error creating $tmp1"
8314         ls -lsh $tmp1
8315         cp $tmp1 $file1
8316
8317         local start=$SECONDS
8318
8319         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8320                 error "migrate failed rc = $?"
8321
8322         local elapsed=$((SECONDS - start))
8323
8324         # with 1MB/s, elapsed should equal size_mb
8325         (( elapsed >= size_mb * 95 / 100 )) ||
8326                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8327
8328         (( elapsed <= size_mb * 120 / 100 )) ||
8329                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8330
8331         (( elapsed <= size_mb * 350 / 100 )) ||
8332                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8333
8334         stripe=$($LFS getstripe -c $file1)
8335         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8336         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8337
8338         # Clean up file (since it is multiple MB)
8339         rm -f $file1 $tmp1
8340 }
8341 run_test 56xh "lfs migrate bandwidth limitation support"
8342
8343 test_56xi() {
8344         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8345         verify_yaml_available || skip_env "YAML verification not installed"
8346
8347         local size_mb=5
8348         local file1=$DIR/$tfile.1
8349         local file2=$DIR/$tfile.2
8350         local file3=$DIR/$tfile.3
8351         local output_file=$DIR/$tfile.out
8352         local tmp1=$TMP/$tfile.tmp
8353
8354         $LFS setstripe -c 2 $file1
8355         $LFS setstripe -c 2 $file2
8356         $LFS setstripe -c 2 $file3
8357
8358         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8359         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8360                         error "error creating $tmp1"
8361         ls -lsh $tmp1
8362         cp $tmp1 $file1
8363         cp $tmp1 $file2
8364         cp $tmp1 $file3
8365
8366         $LFS migrate --stats --stats-interval=1 \
8367                 -c 1 $file1 $file2 $file3 1> $output_file ||
8368                 error "migrate failed rc = $?"
8369
8370         cat $output_file
8371         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8372
8373         # Clean up file (since it is multiple MB)
8374         rm -f $file1 $file2 $file3 $tmp1 $output_file
8375 }
8376 run_test 56xi "lfs migrate stats support"
8377
8378 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8379         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8380
8381         local file=$DIR/$tfile
8382         local linkdir=$DIR/$tdir
8383
8384         test_mkdir $linkdir || error "fail to create $linkdir"
8385         $LFS setstripe -i 0 -c 1 -S1M $file
8386         stack_trap "rm -rf $file $linkdir"
8387         dd if=/dev/urandom of=$file bs=1M count=10 ||
8388                 error "fail to create $file"
8389
8390         # Create file links
8391         local cpts
8392         local threads_max
8393         local nlinks
8394
8395         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8396         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8397         (( nlinks = thread_max * 3 / 2 / cpts))
8398
8399         echo "create $nlinks hard links of $file"
8400         createmany -l $file $linkdir/link $nlinks
8401
8402         # Parallel migrates (should not block)
8403         local i
8404         for ((i = 0; i < nlinks; i++)); do
8405                 echo $linkdir/link$i
8406         done | xargs -n1 -P $nlinks $LFS migrate -c2
8407
8408         local stripe_count
8409         stripe_count=$($LFS getstripe -c $file) ||
8410                 error "fail to get stripe count on $file"
8411
8412         ((stripe_count == 2)) ||
8413                 error "fail to migrate $file (stripe_count = $stripe_count)"
8414 }
8415 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8416
8417 test_56xk() {
8418         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8419
8420         local size_mb=5
8421         local file1=$DIR/$tfile
8422
8423         stack_trap "rm -f $file1"
8424         $LFS setstripe -c 1 $file1
8425         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8426                 error "error creating $file1"
8427         $LFS mirror extend -N $file1 || error "can't mirror"
8428         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8429                 error "can't dd"
8430         $LFS getstripe $file1 | grep stale ||
8431                 error "one component must be stale"
8432
8433         local start=$SECONDS
8434         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8435                 error "migrate failed rc = $?"
8436         local elapsed=$((SECONDS - start))
8437         $LFS getstripe $file1 | grep stale &&
8438                 error "all components must be sync"
8439
8440         # with 1MB/s, elapsed should equal size_mb
8441         (( elapsed >= size_mb * 95 / 100 )) ||
8442                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8443
8444         (( elapsed <= size_mb * 120 / 100 )) ||
8445                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8446
8447         (( elapsed <= size_mb * 350 / 100 )) ||
8448                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8449 }
8450 run_test 56xk "lfs mirror resync bandwidth limitation support"
8451
8452 test_56xl() {
8453         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8454         verify_yaml_available || skip_env "YAML verification not installed"
8455
8456         local size_mb=5
8457         local file1=$DIR/$tfile.1
8458         local output_file=$DIR/$tfile.out
8459
8460         stack_trap "rm -f $file1"
8461         $LFS setstripe -c 1 $file1
8462         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8463                 error "error creating $file1"
8464         $LFS mirror extend -N $file1 || error "can't mirror"
8465         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8466                 error "can't dd"
8467         $LFS getstripe $file1 | grep stale ||
8468                 error "one component must be stale"
8469         $LFS getstripe $file1
8470
8471         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8472                 error "resync failed rc = $?"
8473         $LFS getstripe $file1 | grep stale &&
8474                 error "all components must be sync"
8475
8476         cat $output_file
8477         cat $output_file | verify_yaml || error "stats is not valid YAML"
8478 }
8479 run_test 56xl "lfs mirror resync stats support"
8480
8481 test_56y() {
8482         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8483                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8484
8485         local res=""
8486         local dir=$DIR/$tdir
8487         local f1=$dir/file1
8488         local f2=$dir/file2
8489
8490         test_mkdir -p $dir || error "creating dir $dir"
8491         touch $f1 || error "creating std file $f1"
8492         $MULTIOP $f2 H2c || error "creating released file $f2"
8493
8494         # a directory can be raid0, so ask only for files
8495         res=$($LFS find $dir -L raid0 -type f | wc -l)
8496         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8497
8498         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8499         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8500
8501         # only files can be released, so no need to force file search
8502         res=$($LFS find $dir -L released)
8503         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8504
8505         res=$($LFS find $dir -type f \! -L released)
8506         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8507 }
8508 run_test 56y "lfs find -L raid0|released"
8509
8510 test_56z() { # LU-4824
8511         # This checks to make sure 'lfs find' continues after errors
8512         # There are two classes of errors that should be caught:
8513         # - If multiple paths are provided, all should be searched even if one
8514         #   errors out
8515         # - If errors are encountered during the search, it should not terminate
8516         #   early
8517         local dir=$DIR/$tdir
8518         local i
8519
8520         test_mkdir $dir
8521         for i in d{0..9}; do
8522                 test_mkdir $dir/$i
8523                 touch $dir/$i/$tfile
8524         done
8525         $LFS find $DIR/non_existent_dir $dir &&
8526                 error "$LFS find did not return an error"
8527         # Make a directory unsearchable. This should NOT be the last entry in
8528         # directory order.  Arbitrarily pick the 6th entry
8529         chmod 700 $($LFS find $dir -type d | sed '6!d')
8530
8531         $RUNAS $LFS find $DIR/non_existent $dir
8532         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8533
8534         # The user should be able to see 10 directories and 9 files
8535         (( count == 19 )) ||
8536                 error "$LFS find found $count != 19 entries after error"
8537 }
8538 run_test 56z "lfs find should continue after an error"
8539
8540 test_56aa() { # LU-5937
8541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8542
8543         local dir=$DIR/$tdir
8544
8545         mkdir $dir
8546         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8547
8548         createmany -o $dir/striped_dir/${tfile}- 1024
8549         local dirs=$($LFS find --size +8k $dir/)
8550
8551         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8552 }
8553 run_test 56aa "lfs find --size under striped dir"
8554
8555 test_56ab() { # LU-10705
8556         test_mkdir $DIR/$tdir
8557         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8558         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8559         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8560         # Flush writes to ensure valid blocks.  Need to be more thorough for
8561         # ZFS, since blocks are not allocated/returned to client immediately.
8562         sync_all_data
8563         wait_zfs_commit ost1 2
8564         cancel_lru_locks osc
8565         ls -ls $DIR/$tdir
8566
8567         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8568
8569         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8570
8571         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8572         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8573
8574         rm -f $DIR/$tdir/$tfile.[123]
8575 }
8576 run_test 56ab "lfs find --blocks"
8577
8578 # LU-11188
8579 test_56aca() {
8580         local dir="$DIR/$tdir"
8581         local perms=(001 002 003 004 005 006 007
8582                      010 020 030 040 050 060 070
8583                      100 200 300 400 500 600 700
8584                      111 222 333 444 555 666 777)
8585         local perm_minus=(8 8 4 8 4 4 2
8586                           8 8 4 8 4 4 2
8587                           8 8 4 8 4 4 2
8588                           4 4 2 4 2 2 1)
8589         local perm_slash=(8  8 12  8 12 12 14
8590                           8  8 12  8 12 12 14
8591                           8  8 12  8 12 12 14
8592                          16 16 24 16 24 24 28)
8593
8594         test_mkdir "$dir"
8595         for perm in ${perms[*]}; do
8596                 touch "$dir/$tfile.$perm"
8597                 chmod $perm "$dir/$tfile.$perm"
8598         done
8599
8600         for ((i = 0; i < ${#perms[*]}; i++)); do
8601                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8602                 (( $num == 1 )) ||
8603                         error "lfs find -perm ${perms[i]}:"\
8604                               "$num != 1"
8605
8606                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8607                 (( $num == ${perm_minus[i]} )) ||
8608                         error "lfs find -perm -${perms[i]}:"\
8609                               "$num != ${perm_minus[i]}"
8610
8611                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8612                 (( $num == ${perm_slash[i]} )) ||
8613                         error "lfs find -perm /${perms[i]}:"\
8614                               "$num != ${perm_slash[i]}"
8615         done
8616 }
8617 run_test 56aca "check lfs find -perm with octal representation"
8618
8619 test_56acb() {
8620         local dir=$DIR/$tdir
8621         # p is the permission of write and execute for user, group and other
8622         # without the umask. It is used to test +wx.
8623         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8624         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8625         local symbolic=(+t  a+t u+t g+t o+t
8626                         g+s u+s o+s +s o+sr
8627                         o=r,ug+o,u+w
8628                         u+ g+ o+ a+ ugo+
8629                         u- g- o- a- ugo-
8630                         u= g= o= a= ugo=
8631                         o=r,ug+o,u+w u=r,a+u,u+w
8632                         g=r,ugo=g,u+w u+x,+X +X
8633                         u+x,u+X u+X u+x,g+X o+r,+X
8634                         u+x,go+X +wx +rwx)
8635
8636         test_mkdir $dir
8637         for perm in ${perms[*]}; do
8638                 touch "$dir/$tfile.$perm"
8639                 chmod $perm "$dir/$tfile.$perm"
8640         done
8641
8642         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8643                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8644
8645                 (( $num == 1 )) ||
8646                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8647         done
8648 }
8649 run_test 56acb "check lfs find -perm with symbolic representation"
8650
8651 test_56acc() {
8652         local dir=$DIR/$tdir
8653         local tests="17777 787 789 abcd
8654                 ug=uu ug=a ug=gu uo=ou urw
8655                 u+xg+x a=r,u+x,"
8656
8657         test_mkdir $dir
8658         for err in $tests; do
8659                 if $LFS find $dir -perm $err 2>/dev/null; then
8660                         error "lfs find -perm $err: parsing should have failed"
8661                 fi
8662         done
8663 }
8664 run_test 56acc "check parsing error for lfs find -perm"
8665
8666 test_56ba() {
8667         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8668                 skip "Need MDS version at least 2.10.50"
8669
8670         # Create composite files with one component
8671         local dir=$DIR/$tdir
8672
8673         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8674         # Create composite files with three components
8675         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8676         # LU-16904 Create plain layout files
8677         lfs setstripe -c 1 $dir/$tfile-{1..10}
8678
8679         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8680
8681         [[ $nfiles == 10 ]] ||
8682                 error "lfs find -E 1M found $nfiles != 10 files"
8683
8684         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8685         [[ $nfiles == 25 ]] ||
8686                 error "lfs find ! -E 1M found $nfiles != 25 files"
8687
8688         # All files have a component that starts at 0
8689         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8690         [[ $nfiles == 35 ]] ||
8691                 error "lfs find --component-start 0 - $nfiles != 35 files"
8692
8693         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8694         [[ $nfiles == 15 ]] ||
8695                 error "lfs find --component-start 2M - $nfiles != 15 files"
8696
8697         # All files created here have a componenet that does not starts at 2M
8698         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8699         [[ $nfiles == 35 ]] ||
8700                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8701
8702         # Find files with a specified number of components
8703         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8704         [[ $nfiles == 15 ]] ||
8705                 error "lfs find --component-count 3 - $nfiles != 15 files"
8706
8707         # Remember non-composite files have a component count of zero
8708         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8709         [[ $nfiles == 10 ]] ||
8710                 error "lfs find --component-count 0 - $nfiles != 10 files"
8711
8712         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8713         [[ $nfiles == 20 ]] ||
8714                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8715
8716         # All files have a flag called "init"
8717         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8718         [[ $nfiles == 35 ]] ||
8719                 error "lfs find --component-flags init - $nfiles != 35 files"
8720
8721         # Multi-component files will have a component not initialized
8722         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8723         [[ $nfiles == 15 ]] ||
8724                 error "lfs find !--component-flags init - $nfiles != 15 files"
8725
8726         rm -rf $dir
8727
8728 }
8729 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8730
8731 test_56ca() {
8732         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8733                 skip "Need MDS version at least 2.10.57"
8734
8735         local td=$DIR/$tdir
8736         local tf=$td/$tfile
8737         local dir
8738         local nfiles
8739         local cmd
8740         local i
8741         local j
8742
8743         # create mirrored directories and mirrored files
8744         mkdir $td || error "mkdir $td failed"
8745         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8746         createmany -o $tf- 10 || error "create $tf- failed"
8747
8748         for i in $(seq 2); do
8749                 dir=$td/dir$i
8750                 mkdir $dir || error "mkdir $dir failed"
8751                 $LFS mirror create -N$((3 + i)) $dir ||
8752                         error "create mirrored dir $dir failed"
8753                 createmany -o $dir/$tfile- 10 ||
8754                         error "create $dir/$tfile- failed"
8755         done
8756
8757         # change the states of some mirrored files
8758         echo foo > $tf-6
8759         for i in $(seq 2); do
8760                 dir=$td/dir$i
8761                 for j in $(seq 4 9); do
8762                         echo foo > $dir/$tfile-$j
8763                 done
8764         done
8765
8766         # find mirrored files with specific mirror count
8767         cmd="$LFS find --mirror-count 3 --type f $td"
8768         nfiles=$($cmd | wc -l)
8769         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8770
8771         cmd="$LFS find ! --mirror-count 3 --type f $td"
8772         nfiles=$($cmd | wc -l)
8773         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8774
8775         cmd="$LFS find --mirror-count +2 --type f $td"
8776         nfiles=$($cmd | wc -l)
8777         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8778
8779         cmd="$LFS find --mirror-count -6 --type f $td"
8780         nfiles=$($cmd | wc -l)
8781         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8782
8783         # find mirrored files with specific file state
8784         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8785         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8786
8787         cmd="$LFS find --mirror-state=ro --type f $td"
8788         nfiles=$($cmd | wc -l)
8789         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8790
8791         cmd="$LFS find ! --mirror-state=ro --type f $td"
8792         nfiles=$($cmd | wc -l)
8793         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8794
8795         cmd="$LFS find --mirror-state=wp --type f $td"
8796         nfiles=$($cmd | wc -l)
8797         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8798
8799         cmd="$LFS find ! --mirror-state=sp --type f $td"
8800         nfiles=$($cmd | wc -l)
8801         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8802 }
8803 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8804
8805 test_56da() { # LU-14179
8806         local path=$DIR/$tdir
8807
8808         test_mkdir $path
8809         cd $path
8810
8811         local longdir=$(str_repeat 'a' 255)
8812
8813         for i in {1..15}; do
8814                 path=$path/$longdir
8815                 test_mkdir $longdir
8816                 cd $longdir
8817         done
8818
8819         local len=${#path}
8820         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8821
8822         test_mkdir $lastdir
8823         cd $lastdir
8824         # PATH_MAX-1
8825         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8826
8827         # NAME_MAX
8828         touch $(str_repeat 'f' 255)
8829
8830         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8831                 error "lfs find reported an error"
8832
8833         rm -rf $DIR/$tdir
8834 }
8835 run_test 56da "test lfs find with long paths"
8836
8837 test_56ea() { #LU-10378
8838         local path=$DIR/$tdir
8839         local pool=$TESTNAME
8840
8841         # Create ost pool
8842         pool_add $pool || error "pool_add $pool failed"
8843         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8844                 error "adding targets to $pool failed"
8845
8846         # Set default pool on directory before creating file
8847         mkdir $path || error "mkdir $path failed"
8848         $LFS setstripe -p $pool $path ||
8849                 error "set OST pool on $pool failed"
8850         touch $path/$tfile || error "touch $path/$tfile failed"
8851
8852         # Compare basic file attributes from -printf and stat
8853         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8854         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8855
8856         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8857                 error "Attrs from lfs find and stat don't match"
8858
8859         # Compare Lustre attributes from lfs find and lfs getstripe
8860         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8861         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8862         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8863         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8864         local fpool=$($LFS getstripe --pool $path/$tfile)
8865         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8866
8867         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8868                 error "Attrs from lfs find and lfs getstripe don't match"
8869
8870         # Verify behavior for unknown escape/format sequences
8871         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8872
8873         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8874                 error "Escape/format codes don't match"
8875 }
8876 run_test 56ea "test lfs find -printf option"
8877
8878 test_56eb() {
8879         local dir=$DIR/$tdir
8880         local subdir_1=$dir/subdir_1
8881
8882         test_mkdir -p $subdir_1
8883         ln -s subdir_1 $dir/link_1
8884
8885         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8886                 error "symlink is not followed"
8887
8888         $LFS getstripe --no-follow $dir |
8889                 grep "^$dir/link_1 has no stripe info$" ||
8890                 error "symlink should not have stripe info"
8891
8892         touch $dir/testfile
8893         ln -s testfile $dir/file_link_2
8894
8895         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8896                 error "symlink is not followed"
8897
8898         $LFS getstripe --no-follow $dir |
8899                 grep "^$dir/file_link_2 has no stripe info$" ||
8900                 error "symlink should not have stripe info"
8901 }
8902 run_test 56eb "check lfs getstripe on symlink"
8903
8904 test_56ec() {
8905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8906         local dir=$DIR/$tdir
8907         local srcfile=$dir/srcfile
8908         local srcyaml=$dir/srcyaml
8909         local destfile=$dir/destfile
8910
8911         test_mkdir -p $dir
8912
8913         $LFS setstripe -i 1 $srcfile
8914         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8915         # if the setstripe yaml parsing fails for any reason, the command can
8916         # randomly assign the correct OST index, leading to an erroneous
8917         # success. but the chance of false success is low enough that a
8918         # regression should still be quickly caught.
8919         $LFS setstripe --yaml=$srcyaml $destfile
8920
8921         local srcindex=$($LFS getstripe -i $srcfile)
8922         local destindex=$($LFS getstripe -i $destfile)
8923
8924         if [[ ! $srcindex -eq $destindex ]]; then
8925                 error "setstripe did not set OST index correctly"
8926         fi
8927 }
8928 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8929
8930 test_56eda() {
8931         local dir=$DIR/$tdir
8932         local subdir=$dir/subdir
8933         local file1=$dir/$tfile
8934         local file2=$dir/$tfile\2
8935         local link=$dir/$tfile-link
8936         local nfiles
8937
8938         test_mkdir -p $dir
8939         $LFS setdirstripe -c1 $subdir
8940         touch $file1
8941         touch $file2
8942         ln $file2 $link
8943
8944         nfiles=$($LFS find --links 1 $dir | wc -l)
8945         (( $nfiles == 1 )) ||
8946                 error "lfs find --links expected 1 file, got $nfiles"
8947
8948         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8949         (( $nfiles == 2 )) ||
8950                 error "lfs find --links expected 2 files, got $nfiles"
8951
8952         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8953         (( $nfiles == 1 )) ||
8954                 error "lfs find --links expected 1 directory, got $nfiles"
8955 }
8956 run_test 56eda "check lfs find --links"
8957
8958 test_56edb() {
8959         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8960
8961         local dir=$DIR/$tdir
8962         local stripedir=$dir/stripedir
8963         local nfiles
8964
8965         test_mkdir -p $dir
8966
8967         $LFS setdirstripe -c2 $stripedir
8968
8969         $LFS getdirstripe $stripedir
8970
8971         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
8972         (( $nfiles == 1 )) ||
8973                 error "lfs find --links expected 1 directory, got $nfiles"
8974 }
8975 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
8976
8977 test_56ef() {
8978         local dir=$DIR/$tdir
8979         local dir1=$dir/d1
8980         local dir2=$dir/d2
8981         local nfiles
8982
8983         test_mkdir -p $dir
8984
8985         mkdir $dir1
8986         mkdir $dir2
8987
8988         touch $dir1/f
8989         touch $dir2/f
8990
8991         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
8992         (( $nfiles == 2 )) ||
8993                 error "(1) lfs find expected 2 files, got $nfiles"
8994
8995         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
8996         (( $nfiles == 2 )) ||
8997                 error "(2) lfs find expected 2 files, got $nfiles"
8998
8999         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9000         (( $nfiles == 2 )) ||
9001                 error "(3) lfs find expected 2 files, got $nfiles"
9002 }
9003 run_test 56ef "lfs find with multiple paths"
9004
9005 test_57a() {
9006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9007         # note test will not do anything if MDS is not local
9008         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9009                 skip_env "ldiskfs only test"
9010         fi
9011         remote_mds_nodsh && skip "remote MDS with nodsh"
9012
9013         local MNTDEV="osd*.*MDT*.mntdev"
9014         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9015         [ -z "$DEV" ] && error "can't access $MNTDEV"
9016         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9017                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9018                         error "can't access $DEV"
9019                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9020                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9021                 rm $TMP/t57a.dump
9022         done
9023 }
9024 run_test 57a "verify MDS filesystem created with large inodes =="
9025
9026 test_57b() {
9027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9028         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9029                 skip_env "ldiskfs only test"
9030         fi
9031         remote_mds_nodsh && skip "remote MDS with nodsh"
9032
9033         local dir=$DIR/$tdir
9034         local filecount=100
9035         local file1=$dir/f1
9036         local fileN=$dir/f$filecount
9037
9038         rm -rf $dir || error "removing $dir"
9039         test_mkdir -c1 $dir
9040         local mdtidx=$($LFS getstripe -m $dir)
9041         local mdtname=MDT$(printf %04x $mdtidx)
9042         local facet=mds$((mdtidx + 1))
9043
9044         echo "mcreating $filecount files"
9045         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9046
9047         # verify that files do not have EAs yet
9048         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9049                 error "$file1 has an EA"
9050         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9051                 error "$fileN has an EA"
9052
9053         sync
9054         sleep 1
9055         df $dir  #make sure we get new statfs data
9056         local mdsfree=$(do_facet $facet \
9057                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9058         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9059         local file
9060
9061         echo "opening files to create objects/EAs"
9062         for file in $(seq -f $dir/f%g 1 $filecount); do
9063                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9064                         error "opening $file"
9065         done
9066
9067         # verify that files have EAs now
9068         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9069                 error "$file1 missing EA"
9070         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9071                 error "$fileN missing EA"
9072
9073         sleep 1  #make sure we get new statfs data
9074         df $dir
9075         local mdsfree2=$(do_facet $facet \
9076                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9077         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9078
9079         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9080                 if [ "$mdsfree" != "$mdsfree2" ]; then
9081                         error "MDC before $mdcfree != after $mdcfree2"
9082                 else
9083                         echo "MDC before $mdcfree != after $mdcfree2"
9084                         echo "unable to confirm if MDS has large inodes"
9085                 fi
9086         fi
9087         rm -rf $dir
9088 }
9089 run_test 57b "default LOV EAs are stored inside large inodes ==="
9090
9091 test_58() {
9092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9093         [ -z "$(which wiretest 2>/dev/null)" ] &&
9094                         skip_env "could not find wiretest"
9095
9096         wiretest
9097 }
9098 run_test 58 "verify cross-platform wire constants =============="
9099
9100 test_59() {
9101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9102
9103         echo "touch 130 files"
9104         createmany -o $DIR/f59- 130
9105         echo "rm 130 files"
9106         unlinkmany $DIR/f59- 130
9107         sync
9108         # wait for commitment of removal
9109         wait_delete_completed
9110 }
9111 run_test 59 "verify cancellation of llog records async ========="
9112
9113 TEST60_HEAD="test_60 run $RANDOM"
9114 test_60a() {
9115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9116         remote_mgs_nodsh && skip "remote MGS with nodsh"
9117         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9118                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9119                         skip_env "missing subtest run-llog.sh"
9120
9121         log "$TEST60_HEAD - from kernel mode"
9122         do_facet mgs "$LCTL dk > /dev/null"
9123         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9124         do_facet mgs $LCTL dk > $TMP/$tfile
9125
9126         # LU-6388: test llog_reader
9127         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9128         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9129         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9130                         skip_env "missing llog_reader"
9131         local fstype=$(facet_fstype mgs)
9132         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9133                 skip_env "Only for ldiskfs or zfs type mgs"
9134
9135         local mntpt=$(facet_mntpt mgs)
9136         local mgsdev=$(mgsdevname 1)
9137         local fid_list
9138         local fid
9139         local rec_list
9140         local rec
9141         local rec_type
9142         local obj_file
9143         local path
9144         local seq
9145         local oid
9146         local pass=true
9147
9148         #get fid and record list
9149         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9150                 tail -n 4))
9151         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9152                 tail -n 4))
9153         #remount mgs as ldiskfs or zfs type
9154         stop mgs || error "stop mgs failed"
9155         mount_fstype mgs || error "remount mgs failed"
9156         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9157                 fid=${fid_list[i]}
9158                 rec=${rec_list[i]}
9159                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9160                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9161                 oid=$((16#$oid))
9162
9163                 case $fstype in
9164                         ldiskfs )
9165                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9166                         zfs )
9167                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9168                 esac
9169                 echo "obj_file is $obj_file"
9170                 do_facet mgs $llog_reader $obj_file
9171
9172                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9173                         awk '{ print $3 }' | sed -e "s/^type=//g")
9174                 if [ $rec_type != $rec ]; then
9175                         echo "FAILED test_60a wrong record type $rec_type," \
9176                               "should be $rec"
9177                         pass=false
9178                         break
9179                 fi
9180
9181                 #check obj path if record type is LLOG_LOGID_MAGIC
9182                 if [ "$rec" == "1064553b" ]; then
9183                         path=$(do_facet mgs $llog_reader $obj_file |
9184                                 grep "path=" | awk '{ print $NF }' |
9185                                 sed -e "s/^path=//g")
9186                         if [ $obj_file != $mntpt/$path ]; then
9187                                 echo "FAILED test_60a wrong obj path" \
9188                                       "$montpt/$path, should be $obj_file"
9189                                 pass=false
9190                                 break
9191                         fi
9192                 fi
9193         done
9194         rm -f $TMP/$tfile
9195         #restart mgs before "error", otherwise it will block the next test
9196         stop mgs || error "stop mgs failed"
9197         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9198         $pass || error "test failed, see FAILED test_60a messages for specifics"
9199 }
9200 run_test 60a "llog_test run from kernel module and test llog_reader"
9201
9202 test_60b() { # bug 6411
9203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9204
9205         dmesg > $DIR/$tfile
9206         LLOG_COUNT=$(do_facet mgs dmesg |
9207                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9208                           /llog_[a-z]*.c:[0-9]/ {
9209                                 if (marker)
9210                                         from_marker++
9211                                 from_begin++
9212                           }
9213                           END {
9214                                 if (marker)
9215                                         print from_marker
9216                                 else
9217                                         print from_begin
9218                           }")
9219
9220         [[ $LLOG_COUNT -gt 120 ]] &&
9221                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9222 }
9223 run_test 60b "limit repeated messages from CERROR/CWARN"
9224
9225 test_60c() {
9226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9227
9228         echo "create 5000 files"
9229         createmany -o $DIR/f60c- 5000
9230 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9231         lctl set_param fail_loc=0x80000137
9232         unlinkmany $DIR/f60c- 5000
9233         lctl set_param fail_loc=0
9234 }
9235 run_test 60c "unlink file when mds full"
9236
9237 test_60d() {
9238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9239
9240         SAVEPRINTK=$(lctl get_param -n printk)
9241         # verify "lctl mark" is even working"
9242         MESSAGE="test message ID $RANDOM $$"
9243         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9244         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9245
9246         lctl set_param printk=0 || error "set lnet.printk failed"
9247         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9248         MESSAGE="new test message ID $RANDOM $$"
9249         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9250         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9251         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9252
9253         lctl set_param -n printk="$SAVEPRINTK"
9254 }
9255 run_test 60d "test printk console message masking"
9256
9257 test_60e() {
9258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9259         remote_mds_nodsh && skip "remote MDS with nodsh"
9260
9261         touch $DIR/$tfile
9262 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9263         do_facet mds1 lctl set_param fail_loc=0x15b
9264         rm $DIR/$tfile
9265 }
9266 run_test 60e "no space while new llog is being created"
9267
9268 test_60f() {
9269         local old_path=$($LCTL get_param -n debug_path)
9270
9271         stack_trap "$LCTL set_param debug_path=$old_path"
9272         stack_trap "rm -f $TMP/$tfile*"
9273         rm -f $TMP/$tfile* 2> /dev/null
9274         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9275         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9276         test_mkdir $DIR/$tdir
9277         # retry in case the open is cached and not released
9278         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9279                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9280                 sleep 0.1
9281         done
9282         ls $TMP/$tfile*
9283         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9284 }
9285 run_test 60f "change debug_path works"
9286
9287 test_60g() {
9288         local pid
9289         local i
9290
9291         test_mkdir -c $MDSCOUNT $DIR/$tdir
9292
9293         (
9294                 local index=0
9295                 while true; do
9296                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9297                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9298                                 2>/dev/null
9299                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9300                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9301                         index=$((index + 1))
9302                 done
9303         ) &
9304
9305         pid=$!
9306
9307         for i in {0..100}; do
9308                 # define OBD_FAIL_OSD_TXN_START    0x19a
9309                 local index=$((i % MDSCOUNT + 1))
9310
9311                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9312                         > /dev/null
9313                 sleep 0.01
9314         done
9315
9316         kill -9 $pid
9317
9318         for i in $(seq $MDSCOUNT); do
9319                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9320         done
9321
9322         mkdir $DIR/$tdir/new || error "mkdir failed"
9323         rmdir $DIR/$tdir/new || error "rmdir failed"
9324
9325         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9326                 -t namespace
9327         for i in $(seq $MDSCOUNT); do
9328                 wait_update_facet mds$i "$LCTL get_param -n \
9329                         mdd.$(facet_svc mds$i).lfsck_namespace |
9330                         awk '/^status/ { print \\\$2 }'" "completed"
9331         done
9332
9333         ls -R $DIR/$tdir
9334         rm -rf $DIR/$tdir || error "rmdir failed"
9335 }
9336 run_test 60g "transaction abort won't cause MDT hung"
9337
9338 test_60h() {
9339         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9340                 skip "Need MDS version at least 2.12.52"
9341         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9342
9343         local f
9344
9345         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9346         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9347         for fail_loc in 0x80000188 0x80000189; do
9348                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9349                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9350                         error "mkdir $dir-$fail_loc failed"
9351                 for i in {0..10}; do
9352                         # create may fail on missing stripe
9353                         echo $i > $DIR/$tdir-$fail_loc/$i
9354                 done
9355                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9356                         error "getdirstripe $tdir-$fail_loc failed"
9357                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9358                         error "migrate $tdir-$fail_loc failed"
9359                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9360                         error "getdirstripe $tdir-$fail_loc failed"
9361                 pushd $DIR/$tdir-$fail_loc
9362                 for f in *; do
9363                         echo $f | cmp $f - || error "$f data mismatch"
9364                 done
9365                 popd
9366                 rm -rf $DIR/$tdir-$fail_loc
9367         done
9368 }
9369 run_test 60h "striped directory with missing stripes can be accessed"
9370
9371 function t60i_load() {
9372         mkdir $DIR/$tdir
9373         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9374         $LCTL set_param fail_loc=0x131c fail_val=1
9375         for ((i=0; i<5000; i++)); do
9376                 touch $DIR/$tdir/f$i
9377         done
9378 }
9379
9380 test_60i() {
9381         changelog_register || error "changelog_register failed"
9382         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9383         changelog_users $SINGLEMDS | grep -q $cl_user ||
9384                 error "User $cl_user not found in changelog_users"
9385         changelog_chmask "ALL"
9386         t60i_load &
9387         local PID=$!
9388         for((i=0; i<100; i++)); do
9389                 changelog_dump >/dev/null ||
9390                         error "can't read changelog"
9391         done
9392         kill $PID
9393         wait $PID
9394         changelog_deregister || error "changelog_deregister failed"
9395         $LCTL set_param fail_loc=0
9396 }
9397 run_test 60i "llog: new record vs reader race"
9398
9399 test_60j() {
9400         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9401                 skip "need MDS version at least 2.15.50"
9402         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9403         remote_mds_nodsh && skip "remote MDS with nodsh"
9404         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9405
9406         changelog_users $SINGLEMDS | grep "^cl" &&
9407                 skip "active changelog user"
9408
9409         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9410
9411         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9412                 skip_env "missing llog_reader"
9413
9414         mkdir_on_mdt0 $DIR/$tdir
9415
9416         local f=$DIR/$tdir/$tfile
9417         local mdt_dev
9418         local tmpfile
9419         local plain
9420
9421         changelog_register || error "cannot register changelog user"
9422
9423         # set changelog_mask to ALL
9424         changelog_chmask "ALL"
9425         changelog_clear
9426
9427         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9428         unlinkmany ${f}- 100 || error "unlinkmany failed"
9429
9430         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9431         mdt_dev=$(facet_device $SINGLEMDS)
9432
9433         do_facet $SINGLEMDS sync
9434         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9435                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9436                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9437
9438         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9439
9440         # if $tmpfile is not on EXT3 filesystem for some reason
9441         [[ ${plain:0:1} == 'O' ]] ||
9442                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9443
9444         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9445                 $mdt_dev; stat -c %s $tmpfile")
9446         echo "Truncate llog from $size to $((size - size % 8192))"
9447         size=$((size - size % 8192))
9448         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9449         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9450                 grep -c 'in bitmap only')
9451         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9452
9453         size=$((size - 9000))
9454         echo "Corrupt llog in the middle at $size"
9455         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9456                 count=333 conv=notrunc
9457         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9458                 grep -c 'next chunk')
9459         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9460 }
9461 run_test 60j "llog_reader reports corruptions"
9462
9463 test_61a() {
9464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9465
9466         f="$DIR/f61"
9467         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9468         cancel_lru_locks osc
9469         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9470         sync
9471 }
9472 run_test 61a "mmap() writes don't make sync hang ================"
9473
9474 test_61b() {
9475         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9476 }
9477 run_test 61b "mmap() of unstriped file is successful"
9478
9479 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9480 # Though this test is irrelevant anymore, it helped to reveal some
9481 # other grant bugs (LU-4482), let's keep it.
9482 test_63a() {   # was test_63
9483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9484
9485         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9486
9487         for i in `seq 10` ; do
9488                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9489                 sleep 5
9490                 kill $!
9491                 sleep 1
9492         done
9493
9494         rm -f $DIR/f63 || true
9495 }
9496 run_test 63a "Verify oig_wait interruption does not crash ======="
9497
9498 # bug 2248 - async write errors didn't return to application on sync
9499 # bug 3677 - async write errors left page locked
9500 test_63b() {
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502
9503         debugsave
9504         lctl set_param debug=-1
9505
9506         # ensure we have a grant to do async writes
9507         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9508         rm $DIR/$tfile
9509
9510         sync    # sync lest earlier test intercept the fail_loc
9511
9512         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9513         lctl set_param fail_loc=0x80000406
9514         $MULTIOP $DIR/$tfile Owy && \
9515                 error "sync didn't return ENOMEM"
9516         sync; sleep 2; sync     # do a real sync this time to flush page
9517         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9518                 error "locked page left in cache after async error" || true
9519         debugrestore
9520 }
9521 run_test 63b "async write errors should be returned to fsync ==="
9522
9523 test_64a () {
9524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9525
9526         lfs df $DIR
9527         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9528 }
9529 run_test 64a "verify filter grant calculations (in kernel) ====="
9530
9531 test_64b () {
9532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9533
9534         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9535 }
9536 run_test 64b "check out-of-space detection on client"
9537
9538 test_64c() {
9539         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9540 }
9541 run_test 64c "verify grant shrink"
9542
9543 import_param() {
9544         local tgt=$1
9545         local param=$2
9546
9547         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9548 }
9549
9550 # this does exactly what osc_request.c:osc_announce_cached() does in
9551 # order to calculate max amount of grants to ask from server
9552 want_grant() {
9553         local tgt=$1
9554
9555         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9556         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9557
9558         ((rpc_in_flight++));
9559         nrpages=$((nrpages * rpc_in_flight))
9560
9561         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9562
9563         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9564
9565         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9566         local undirty=$((nrpages * PAGE_SIZE))
9567
9568         local max_extent_pages
9569         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9570         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9571         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9572         local grant_extent_tax
9573         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9574
9575         undirty=$((undirty + nrextents * grant_extent_tax))
9576
9577         echo $undirty
9578 }
9579
9580 # this is size of unit for grant allocation. It should be equal to
9581 # what tgt_grant.c:tgt_grant_chunk() calculates
9582 grant_chunk() {
9583         local tgt=$1
9584         local max_brw_size
9585         local grant_extent_tax
9586
9587         max_brw_size=$(import_param $tgt max_brw_size)
9588
9589         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9590
9591         echo $(((max_brw_size + grant_extent_tax) * 2))
9592 }
9593
9594 test_64d() {
9595         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9596                 skip "OST < 2.10.55 doesn't limit grants enough"
9597
9598         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9599
9600         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9601                 skip "no grant_param connect flag"
9602
9603         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9604
9605         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9606         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9607
9608
9609         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9610         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9611
9612         $LFS setstripe $DIR/$tfile -i 0 -c 1
9613         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9614         ddpid=$!
9615
9616         while kill -0 $ddpid; do
9617                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9618
9619                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9620                         kill $ddpid
9621                         error "cur_grant $cur_grant > $max_cur_granted"
9622                 fi
9623
9624                 sleep 1
9625         done
9626 }
9627 run_test 64d "check grant limit exceed"
9628
9629 check_grants() {
9630         local tgt=$1
9631         local expected=$2
9632         local msg=$3
9633         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9634
9635         ((cur_grants == expected)) ||
9636                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9637 }
9638
9639 round_up_p2() {
9640         echo $((($1 + $2 - 1) & ~($2 - 1)))
9641 }
9642
9643 test_64e() {
9644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9645         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9646                 skip "Need OSS version at least 2.11.56"
9647
9648         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9649         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9650         $LCTL set_param debug=+cache
9651
9652         # Remount client to reset grant
9653         remount_client $MOUNT || error "failed to remount client"
9654         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9655
9656         local init_grants=$(import_param $osc_tgt initial_grant)
9657
9658         check_grants $osc_tgt $init_grants "init grants"
9659
9660         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9661         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9662         local gbs=$(import_param $osc_tgt grant_block_size)
9663
9664         # write random number of bytes from max_brw_size / 4 to max_brw_size
9665         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9666         # align for direct io
9667         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9668         # round to grant consumption unit
9669         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9670
9671         local grants=$((wb_round_up + extent_tax))
9672
9673         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9674         stack_trap "rm -f $DIR/$tfile"
9675
9676         # define OBD_FAIL_TGT_NO_GRANT 0x725
9677         # make the server not grant more back
9678         do_facet ost1 $LCTL set_param fail_loc=0x725
9679         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9680
9681         do_facet ost1 $LCTL set_param fail_loc=0
9682
9683         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9684
9685         rm -f $DIR/$tfile || error "rm failed"
9686
9687         # Remount client to reset grant
9688         remount_client $MOUNT || error "failed to remount client"
9689         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9690
9691         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9692
9693         # define OBD_FAIL_TGT_NO_GRANT 0x725
9694         # make the server not grant more back
9695         do_facet ost1 $LCTL set_param fail_loc=0x725
9696         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9697         do_facet ost1 $LCTL set_param fail_loc=0
9698
9699         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9700 }
9701 run_test 64e "check grant consumption (no grant allocation)"
9702
9703 test_64f() {
9704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9705
9706         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9707         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9708         $LCTL set_param debug=+cache
9709
9710         # Remount client to reset grant
9711         remount_client $MOUNT || error "failed to remount client"
9712         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9713
9714         local init_grants=$(import_param $osc_tgt initial_grant)
9715         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9716         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9717         local gbs=$(import_param $osc_tgt grant_block_size)
9718         local chunk=$(grant_chunk $osc_tgt)
9719
9720         # write random number of bytes from max_brw_size / 4 to max_brw_size
9721         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9722         # align for direct io
9723         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9724         # round to grant consumption unit
9725         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9726
9727         local grants=$((wb_round_up + extent_tax))
9728
9729         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9730         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9731                 error "error writing to $DIR/$tfile"
9732
9733         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9734                 "direct io with grant allocation"
9735
9736         rm -f $DIR/$tfile || error "rm failed"
9737
9738         # Remount client to reset grant
9739         remount_client $MOUNT || error "failed to remount client"
9740         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9741
9742         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9743
9744         # Testing that buffered IO consumes grant on the client
9745
9746         # Delay the RPC on the server so it's guaranteed to not complete even
9747         # if the RPC is sent from the client
9748         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9749         $LCTL set_param fail_loc=0x50a fail_val=3
9750         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9751                 error "error writing to $DIR/$tfile with buffered IO"
9752
9753         check_grants $osc_tgt $((init_grants - grants)) \
9754                 "buffered io, not write rpc"
9755
9756         # Clear the fail loc and do a sync on the client
9757         $LCTL set_param fail_loc=0 fail_val=0
9758         sync
9759
9760         # RPC is now known to have sent
9761         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9762                 "buffered io, one RPC"
9763 }
9764 run_test 64f "check grant consumption (with grant allocation)"
9765
9766 test_64g() {
9767         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9768                 skip "Need MDS version at least 2.14.56"
9769
9770         local mdts=$(comma_list $(mdts_nodes))
9771
9772         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9773                         tr '\n' ' ')
9774         stack_trap "$LCTL set_param $old"
9775
9776         # generate dirty pages and increase dirty granted on MDT
9777         stack_trap "rm -f $DIR/$tfile-*"
9778         for (( i = 0; i < 10; i++)); do
9779                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9780                         error "can't set stripe"
9781                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9782                         error "can't dd"
9783                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9784                         $LFS getstripe $DIR/$tfile-$i
9785                         error "not DoM file"
9786                 }
9787         done
9788
9789         # flush dirty pages
9790         sync
9791
9792         # wait until grant shrink reset grant dirty on MDTs
9793         for ((i = 0; i < 120; i++)); do
9794                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9795                         awk '{sum=sum+$1} END {print sum}')
9796                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9797                 echo "$grant_dirty grants, $vm_dirty pages"
9798                 (( grant_dirty + vm_dirty == 0 )) && break
9799                 (( i == 3 )) && sync &&
9800                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9801                 sleep 1
9802         done
9803
9804         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9805                 awk '{sum=sum+$1} END {print sum}')
9806         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9807 }
9808 run_test 64g "grant shrink on MDT"
9809
9810 test_64h() {
9811         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9812                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9813
9814         local instance=$($LFS getname -i $DIR)
9815         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9816         local num_exps=$(do_facet ost1 \
9817             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9818         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9819         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9820         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9821
9822         # 10MiB is for file to be written, max_brw_size * 16 *
9823         # num_exps is space reserve so that tgt_grant_shrink() decided
9824         # to not shrink
9825         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9826         (( avail * 1024 < expect )) &&
9827                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9828
9829         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9830         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9831         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9832         $LCTL set_param osc.*OST0000*.grant_shrink=1
9833         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9834
9835         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9836         stack_trap "rm -f $DIR/$tfile"
9837         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9838
9839         # drop cache so that coming read would do rpc
9840         cancel_lru_locks osc
9841
9842         # shrink interval is set to 10, pause for 7 seconds so that
9843         # grant thread did not wake up yet but coming read entered
9844         # shrink mode for rpc (osc_should_shrink_grant())
9845         sleep 7
9846
9847         declare -a cur_grant_bytes
9848         declare -a tot_granted
9849         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9850         tot_granted[0]=$(do_facet ost1 \
9851             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9852
9853         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9854
9855         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9856         tot_granted[1]=$(do_facet ost1 \
9857             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9858
9859         # grant change should be equal on both sides
9860         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9861                 tot_granted[0] - tot_granted[1])) ||
9862                 error "grant change mismatch, "                                \
9863                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9864                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9865 }
9866 run_test 64h "grant shrink on read"
9867
9868 test_64i() {
9869         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9870                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9871
9872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9873         remote_ost_nodsh && skip "remote OSTs with nodsh"
9874
9875         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9876         stack_trap "rm -f $DIR/$tfile"
9877
9878         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9879
9880         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9881         local instance=$($LFS getname -i $DIR)
9882
9883         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9884         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9885
9886         # shrink grants and simulate rpc loss
9887         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9888         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9889         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9890
9891         fail ost1
9892
9893         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9894
9895         local testid=$(echo $TESTNAME | tr '_' ' ')
9896
9897         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9898                 grep "GRANT, real grant" &&
9899                 error "client has more grants then it owns" || true
9900 }
9901 run_test 64i "shrink on reconnect"
9902
9903 # bug 1414 - set/get directories' stripe info
9904 test_65a() {
9905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9906
9907         test_mkdir $DIR/$tdir
9908         touch $DIR/$tdir/f1
9909         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9910 }
9911 run_test 65a "directory with no stripe info"
9912
9913 test_65b() {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915
9916         test_mkdir $DIR/$tdir
9917         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9918
9919         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9920                                                 error "setstripe"
9921         touch $DIR/$tdir/f2
9922         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9923 }
9924 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9925
9926 test_65c() {
9927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9928         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9929
9930         test_mkdir $DIR/$tdir
9931         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9932
9933         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9934                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9935         touch $DIR/$tdir/f3
9936         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9937 }
9938 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9939
9940 test_65d() {
9941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9942
9943         test_mkdir $DIR/$tdir
9944         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9945         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9946
9947         if [[ $STRIPECOUNT -le 0 ]]; then
9948                 sc=1
9949         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9950                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9951                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9952         else
9953                 sc=$(($STRIPECOUNT - 1))
9954         fi
9955         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9956         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9957         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9958                 error "lverify failed"
9959 }
9960 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9961
9962 test_65e() {
9963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9964
9965         # LU-16904 delete layout when root is set as PFL layout
9966         save_layout_restore_at_exit $MOUNT
9967         $LFS setstripe -d $MOUNT || error "setstripe failed"
9968
9969         test_mkdir $DIR/$tdir
9970
9971         $LFS setstripe $DIR/$tdir || error "setstripe"
9972         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9973                                         error "no stripe info failed"
9974         touch $DIR/$tdir/f6
9975         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9976 }
9977 run_test 65e "directory setstripe defaults"
9978
9979 test_65f() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981
9982         test_mkdir $DIR/${tdir}f
9983         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9984                 error "setstripe succeeded" || true
9985 }
9986 run_test 65f "dir setstripe permission (should return error) ==="
9987
9988 test_65g() {
9989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9990
9991         # LU-16904 delete layout when root is set as PFL layout
9992         save_layout_restore_at_exit $MOUNT
9993         $LFS setstripe -d $MOUNT || error "setstripe failed"
9994
9995         test_mkdir $DIR/$tdir
9996         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9997
9998         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9999                 error "setstripe -S failed"
10000         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10001         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10002                 error "delete default stripe failed"
10003 }
10004 run_test 65g "directory setstripe -d"
10005
10006 test_65h() {
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008
10009         test_mkdir $DIR/$tdir
10010         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10011
10012         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10013                 error "setstripe -S failed"
10014         test_mkdir $DIR/$tdir/dd1
10015         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10016                 error "stripe info inherit failed"
10017 }
10018 run_test 65h "directory stripe info inherit ===================="
10019
10020 test_65i() {
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022
10023         save_layout_restore_at_exit $MOUNT
10024
10025         # bug6367: set non-default striping on root directory
10026         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10027
10028         # bug12836: getstripe on -1 default directory striping
10029         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10030
10031         # bug12836: getstripe -v on -1 default directory striping
10032         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10033
10034         # bug12836: new find on -1 default directory striping
10035         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10036 }
10037 run_test 65i "various tests to set root directory striping"
10038
10039 test_65j() { # bug6367
10040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10041
10042         sync; sleep 1
10043
10044         # if we aren't already remounting for each test, do so for this test
10045         if [ "$I_MOUNTED" = "yes" ]; then
10046                 cleanup || error "failed to unmount"
10047                 setup
10048         fi
10049
10050         save_layout_restore_at_exit $MOUNT
10051
10052         $LFS setstripe -d $MOUNT || error "setstripe failed"
10053 }
10054 run_test 65j "set default striping on root directory (bug 6367)="
10055
10056 cleanup_65k() {
10057         rm -rf $DIR/$tdir
10058         wait_delete_completed
10059         do_facet $SINGLEMDS "lctl set_param -n \
10060                 osp.$ost*MDT0000.max_create_count=$max_count"
10061         do_facet $SINGLEMDS "lctl set_param -n \
10062                 osp.$ost*MDT0000.create_count=$count"
10063         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10064         echo $INACTIVE_OSC "is Activate"
10065
10066         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10067 }
10068
10069 test_65k() { # bug11679
10070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10071         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10072         remote_mds_nodsh && skip "remote MDS with nodsh"
10073
10074         local disable_precreate=true
10075         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10076                 disable_precreate=false
10077
10078         echo "Check OST status: "
10079         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10080                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10081
10082         for OSC in $MDS_OSCS; do
10083                 echo $OSC "is active"
10084                 do_facet $SINGLEMDS lctl --device %$OSC activate
10085         done
10086
10087         for INACTIVE_OSC in $MDS_OSCS; do
10088                 local ost=$(osc_to_ost $INACTIVE_OSC)
10089                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10090                                lov.*md*.target_obd |
10091                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10092
10093                 mkdir -p $DIR/$tdir
10094                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10095                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10096
10097                 echo "Deactivate: " $INACTIVE_OSC
10098                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10099
10100                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10101                               osp.$ost*MDT0000.create_count")
10102                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10103                                   osp.$ost*MDT0000.max_create_count")
10104                 $disable_precreate &&
10105                         do_facet $SINGLEMDS "lctl set_param -n \
10106                                 osp.$ost*MDT0000.max_create_count=0"
10107
10108                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10109                         [ -f $DIR/$tdir/$idx ] && continue
10110                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10111                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10112                                 { cleanup_65k;
10113                                   error "setstripe $idx should succeed"; }
10114                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10115                 done
10116                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10117                 rmdir $DIR/$tdir
10118
10119                 do_facet $SINGLEMDS "lctl set_param -n \
10120                         osp.$ost*MDT0000.max_create_count=$max_count"
10121                 do_facet $SINGLEMDS "lctl set_param -n \
10122                         osp.$ost*MDT0000.create_count=$count"
10123                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10124                 echo $INACTIVE_OSC "is Activate"
10125
10126                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10127         done
10128 }
10129 run_test 65k "validate manual striping works properly with deactivated OSCs"
10130
10131 test_65l() { # bug 12836
10132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10133
10134         test_mkdir -p $DIR/$tdir/test_dir
10135         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10136         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10137 }
10138 run_test 65l "lfs find on -1 stripe dir ========================"
10139
10140 test_65m() {
10141         local layout=$(save_layout $MOUNT)
10142         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10143                 restore_layout $MOUNT $layout
10144                 error "setstripe should fail by non-root users"
10145         }
10146         true
10147 }
10148 run_test 65m "normal user can't set filesystem default stripe"
10149
10150 test_65n() {
10151         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10152         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10153                 skip "Need MDS version at least 2.12.50"
10154         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10155
10156         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10157         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10158         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10159
10160         save_layout_restore_at_exit $MOUNT
10161
10162         # new subdirectory under root directory should not inherit
10163         # the default layout from root
10164         # LU-16904 check if the root is set as PFL layout
10165         local numcomp=$($LFS getstripe --component-count $MOUNT)
10166
10167         if [[ $numcomp -eq 0 ]]; then
10168                 local dir1=$MOUNT/$tdir-1
10169                 mkdir $dir1 || error "mkdir $dir1 failed"
10170                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10171                         error "$dir1 shouldn't have LOV EA"
10172         fi
10173
10174         # delete the default layout on root directory
10175         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10176
10177         local dir2=$MOUNT/$tdir-2
10178         mkdir $dir2 || error "mkdir $dir2 failed"
10179         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10180                 error "$dir2 shouldn't have LOV EA"
10181
10182         # set a new striping pattern on root directory
10183         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10184         local new_def_stripe_size=$((def_stripe_size * 2))
10185         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10186                 error "set stripe size on $MOUNT failed"
10187
10188         # new file created in $dir2 should inherit the new stripe size from
10189         # the filesystem default
10190         local file2=$dir2/$tfile-2
10191         touch $file2 || error "touch $file2 failed"
10192
10193         local file2_stripe_size=$($LFS getstripe -S $file2)
10194         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10195         {
10196                 echo "file2_stripe_size: '$file2_stripe_size'"
10197                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10198                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10199         }
10200
10201         local dir3=$MOUNT/$tdir-3
10202         mkdir $dir3 || error "mkdir $dir3 failed"
10203         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10204         # the root layout, which is the actual default layout that will be used
10205         # when new files are created in $dir3.
10206         local dir3_layout=$(get_layout_param $dir3)
10207         local root_dir_layout=$(get_layout_param $MOUNT)
10208         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10209         {
10210                 echo "dir3_layout: '$dir3_layout'"
10211                 echo "root_dir_layout: '$root_dir_layout'"
10212                 error "$dir3 should show the default layout from $MOUNT"
10213         }
10214
10215         # set OST pool on root directory
10216         local pool=$TESTNAME
10217         pool_add $pool || error "add $pool failed"
10218         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10219                 error "add targets to $pool failed"
10220
10221         $LFS setstripe -p $pool $MOUNT ||
10222                 error "set OST pool on $MOUNT failed"
10223
10224         # new file created in $dir3 should inherit the pool from
10225         # the filesystem default
10226         local file3=$dir3/$tfile-3
10227         touch $file3 || error "touch $file3 failed"
10228
10229         local file3_pool=$($LFS getstripe -p $file3)
10230         [[ "$file3_pool" = "$pool" ]] ||
10231                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10232
10233         local dir4=$MOUNT/$tdir-4
10234         mkdir $dir4 || error "mkdir $dir4 failed"
10235         local dir4_layout=$(get_layout_param $dir4)
10236         root_dir_layout=$(get_layout_param $MOUNT)
10237         echo "$LFS getstripe -d $dir4"
10238         $LFS getstripe -d $dir4
10239         echo "$LFS getstripe -d $MOUNT"
10240         $LFS getstripe -d $MOUNT
10241         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10242         {
10243                 echo "dir4_layout: '$dir4_layout'"
10244                 echo "root_dir_layout: '$root_dir_layout'"
10245                 error "$dir4 should show the default layout from $MOUNT"
10246         }
10247
10248         # new file created in $dir4 should inherit the pool from
10249         # the filesystem default
10250         local file4=$dir4/$tfile-4
10251         touch $file4 || error "touch $file4 failed"
10252
10253         local file4_pool=$($LFS getstripe -p $file4)
10254         [[ "$file4_pool" = "$pool" ]] ||
10255                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10256
10257         # new subdirectory under non-root directory should inherit
10258         # the default layout from its parent directory
10259         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10260                 error "set directory layout on $dir4 failed"
10261
10262         local dir5=$dir4/$tdir-5
10263         mkdir $dir5 || error "mkdir $dir5 failed"
10264
10265         dir4_layout=$(get_layout_param $dir4)
10266         local dir5_layout=$(get_layout_param $dir5)
10267         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10268         {
10269                 echo "dir4_layout: '$dir4_layout'"
10270                 echo "dir5_layout: '$dir5_layout'"
10271                 error "$dir5 should inherit the default layout from $dir4"
10272         }
10273
10274         # though subdir under ROOT doesn't inherit default layout, but
10275         # its sub dir/file should be created with default layout.
10276         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10277         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10278                 skip "Need MDS version at least 2.12.59"
10279
10280         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10281         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10282         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10283
10284         if [ $default_lmv_hash == "none" ]; then
10285                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10286         else
10287                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10288                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10289         fi
10290
10291         $LFS setdirstripe -D -c 2 $MOUNT ||
10292                 error "setdirstripe -D -c 2 failed"
10293         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10294         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10295         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10296
10297         # $dir4 layout includes pool
10298         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10299         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10300                 error "pool lost on setstripe"
10301         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10302         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10303                 error "pool lost on compound layout setstripe"
10304 }
10305 run_test 65n "don't inherit default layout from root for new subdirectories"
10306
10307 test_65o() {
10308         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10309                 skip "need MDS version at least 2.14.57"
10310
10311         # set OST pool on root directory
10312         local pool=$TESTNAME
10313
10314         pool_add $pool || error "add $pool failed"
10315         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10316                 error "add targets to $pool failed"
10317
10318         local dir1=$MOUNT/$tdir
10319
10320         mkdir $dir1 || error "mkdir $dir1 failed"
10321
10322         # set a new striping pattern on root directory
10323         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10324
10325         $LFS setstripe -p $pool $dir1 ||
10326                 error "set directory layout on $dir1 failed"
10327
10328         # $dir1 layout includes pool
10329         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10330         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10331                 error "pool lost on setstripe"
10332         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10333         $LFS getstripe $dir1
10334         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10335                 error "pool lost on compound layout setstripe"
10336
10337         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10338                 error "setdirstripe failed on sub-dir with inherited pool"
10339         $LFS getstripe $dir1/dir2
10340         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10341                 error "pool lost on compound layout setdirstripe"
10342
10343         $LFS setstripe -E -1 -c 1 $dir1
10344         $LFS getstripe -d $dir1
10345         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10346                 error "pool lost on setstripe"
10347 }
10348 run_test 65o "pool inheritance for mdt component"
10349
10350 test_65p () { # LU-16152
10351         local src_dir=$DIR/$tdir/src_dir
10352         local dst_dir=$DIR/$tdir/dst_dir
10353         local yaml_file=$DIR/$tdir/layout.yaml
10354         local border
10355
10356         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10357                 skip "Need at least version 2.15.51"
10358
10359         test_mkdir -p $src_dir
10360         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10361                 error "failed to setstripe"
10362         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10363                 error "failed to getstripe"
10364
10365         test_mkdir -p $dst_dir
10366         $LFS setstripe --yaml $yaml_file $dst_dir ||
10367                 error "failed to setstripe with yaml file"
10368         border=$($LFS getstripe -d $dst_dir |
10369                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10370                 error "failed to getstripe"
10371
10372         # 2048M is 0x80000000, or 2147483648
10373         (( $border == 2147483648 )) ||
10374                 error "failed to handle huge number in yaml layout"
10375 }
10376 run_test 65p "setstripe with yaml file and huge number"
10377
10378 test_65p () { # LU-16194
10379         local src_dir=$DIR/$tdir/src_dir
10380
10381         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10382                 skip "Need at least version 2.15.51"
10383
10384         test_mkdir -p $src_dir
10385         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10386         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10387                 error "should fail if extent start/end >=8E"
10388
10389         # EOF should work as before
10390         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10391                 error "failed to setstripe normally"
10392 }
10393 run_test 65p "setstripe with >=8E offset should fail"
10394
10395 # bug 2543 - update blocks count on client
10396 test_66() {
10397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10398
10399         local COUNT=${COUNT:-8}
10400         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10401         sync; sync_all_data; sync; sync_all_data
10402         cancel_lru_locks osc
10403         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10404         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10405 }
10406 run_test 66 "update inode blocks count on client ==============="
10407
10408 meminfo() {
10409         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10410 }
10411
10412 swap_used() {
10413         swapon -s | awk '($1 == "'$1'") { print $4 }'
10414 }
10415
10416 # bug5265, obdfilter oa2dentry return -ENOENT
10417 # #define OBD_FAIL_SRV_ENOENT 0x217
10418 test_69() {
10419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10420         remote_ost_nodsh && skip "remote OST with nodsh"
10421
10422         f="$DIR/$tfile"
10423         $LFS setstripe -c 1 -i 0 $f
10424         stack_trap "rm -f $f ${f}.2"
10425
10426         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10427
10428         do_facet ost1 lctl set_param fail_loc=0x217
10429         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10430         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10431
10432         do_facet ost1 lctl set_param fail_loc=0
10433         $DIRECTIO write $f 0 2 || error "write error"
10434
10435         cancel_lru_locks osc
10436         $DIRECTIO read $f 0 1 || error "read error"
10437
10438         do_facet ost1 lctl set_param fail_loc=0x217
10439         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10440
10441         do_facet ost1 lctl set_param fail_loc=0
10442 }
10443 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10444
10445 test_70a() {
10446         # Perform a really simple test of health write
10447         # and health check
10448
10449         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10450
10451         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10452
10453         # Test with health write off
10454         do_facet ost1 $LCTL set_param enable_health_write off ||
10455                 error "can't set enable_health_write off"
10456         do_facet ost1 $LCTL get_param enable_health_write ||
10457                 error "can't get enable_health_write"
10458
10459         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10460                 error "not healthy (1)"
10461
10462         # Test with health write on
10463         do_facet ost1 $LCTL set_param enable_health_write on ||
10464                 error "can't set enable_health_write on"
10465         do_facet ost1 $LCTL get_param enable_health_write ||
10466                 error "can't get enable_health_write"
10467
10468         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10469                 error "not healthy (2)"
10470 }
10471 run_test 70a "verify health_check, health_write don't explode (on OST)"
10472
10473 test_71() {
10474         test_mkdir $DIR/$tdir
10475         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10476         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10477 }
10478 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10479
10480 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         [ "$RUNAS_ID" = "$UID" ] &&
10483                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10484         # Check that testing environment is properly set up. Skip if not
10485         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10486                 skip_env "User $RUNAS_ID does not exist - skipping"
10487
10488         touch $DIR/$tfile
10489         chmod 777 $DIR/$tfile
10490         chmod ug+s $DIR/$tfile
10491         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10492                 error "$RUNAS dd $DIR/$tfile failed"
10493         # See if we are still setuid/sgid
10494         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10495                 error "S/gid is not dropped on write"
10496         # Now test that MDS is updated too
10497         cancel_lru_locks mdc
10498         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10499                 error "S/gid is not dropped on MDS"
10500         rm -f $DIR/$tfile
10501 }
10502 run_test 72a "Test that remove suid works properly (bug5695) ===="
10503
10504 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10505         local perm
10506
10507         [ "$RUNAS_ID" = "$UID" ] &&
10508                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10509         [ "$RUNAS_ID" -eq 0 ] &&
10510                 skip_env "RUNAS_ID = 0 -- skipping"
10511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10512         # Check that testing environment is properly set up. Skip if not
10513         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10514                 skip_env "User $RUNAS_ID does not exist - skipping"
10515
10516         touch $DIR/${tfile}-f{g,u}
10517         test_mkdir $DIR/${tfile}-dg
10518         test_mkdir $DIR/${tfile}-du
10519         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10520         chmod g+s $DIR/${tfile}-{f,d}g
10521         chmod u+s $DIR/${tfile}-{f,d}u
10522         for perm in 777 2777 4777; do
10523                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10524                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10525                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10526                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10527         done
10528         true
10529 }
10530 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10531
10532 # bug 3462 - multiple simultaneous MDC requests
10533 test_73() {
10534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10535
10536         test_mkdir $DIR/d73-1
10537         test_mkdir $DIR/d73-2
10538         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10539         pid1=$!
10540
10541         lctl set_param fail_loc=0x80000129
10542         $MULTIOP $DIR/d73-1/f73-2 Oc &
10543         sleep 1
10544         lctl set_param fail_loc=0
10545
10546         $MULTIOP $DIR/d73-2/f73-3 Oc &
10547         pid3=$!
10548
10549         kill -USR1 $pid1
10550         wait $pid1 || return 1
10551
10552         sleep 25
10553
10554         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10555         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10556         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10557
10558         rm -rf $DIR/d73-*
10559 }
10560 run_test 73 "multiple MDC requests (should not deadlock)"
10561
10562 test_74a() { # bug 6149, 6184
10563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10564
10565         touch $DIR/f74a
10566         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10567         #
10568         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10569         # will spin in a tight reconnection loop
10570         $LCTL set_param fail_loc=0x8000030e
10571         # get any lock that won't be difficult - lookup works.
10572         ls $DIR/f74a
10573         $LCTL set_param fail_loc=0
10574         rm -f $DIR/f74a
10575         true
10576 }
10577 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10578
10579 test_74b() { # bug 13310
10580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10581
10582         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10583         #
10584         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10585         # will spin in a tight reconnection loop
10586         $LCTL set_param fail_loc=0x8000030e
10587         # get a "difficult" lock
10588         touch $DIR/f74b
10589         $LCTL set_param fail_loc=0
10590         rm -f $DIR/f74b
10591         true
10592 }
10593 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10594
10595 test_74c() {
10596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10597
10598         #define OBD_FAIL_LDLM_NEW_LOCK
10599         $LCTL set_param fail_loc=0x319
10600         touch $DIR/$tfile && error "touch successful"
10601         $LCTL set_param fail_loc=0
10602         true
10603 }
10604 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10605
10606 slab_lic=/sys/kernel/slab/lustre_inode_cache
10607 num_objects() {
10608         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10609         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10610                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10611 }
10612
10613 test_76a() { # Now for b=20433, added originally in b=1443
10614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10615
10616         cancel_lru_locks osc
10617         # there may be some slab objects cached per core
10618         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10619         local before=$(num_objects)
10620         local count=$((512 * cpus))
10621         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10622         local margin=$((count / 10))
10623         if [[ -f $slab_lic/aliases ]]; then
10624                 local aliases=$(cat $slab_lic/aliases)
10625                 (( aliases > 0 )) && margin=$((margin * aliases))
10626         fi
10627
10628         echo "before slab objects: $before"
10629         for i in $(seq $count); do
10630                 touch $DIR/$tfile
10631                 rm -f $DIR/$tfile
10632         done
10633         cancel_lru_locks osc
10634         local after=$(num_objects)
10635         echo "created: $count, after slab objects: $after"
10636         # shared slab counts are not very accurate, allow significant margin
10637         # the main goal is that the cache growth is not permanently > $count
10638         while (( after > before + margin )); do
10639                 sleep 1
10640                 after=$(num_objects)
10641                 wait=$((wait + 1))
10642                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10643                 if (( wait > 60 )); then
10644                         error "inode slab grew from $before+$margin to $after"
10645                 fi
10646         done
10647 }
10648 run_test 76a "confirm clients recycle inodes properly ===="
10649
10650 test_76b() {
10651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10652         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10653
10654         local count=512
10655         local before=$(num_objects)
10656
10657         for i in $(seq $count); do
10658                 mkdir $DIR/$tdir
10659                 rmdir $DIR/$tdir
10660         done
10661
10662         local after=$(num_objects)
10663         local wait=0
10664
10665         while (( after > before )); do
10666                 sleep 1
10667                 after=$(num_objects)
10668                 wait=$((wait + 1))
10669                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10670                 if (( wait > 60 )); then
10671                         error "inode slab grew from $before to $after"
10672                 fi
10673         done
10674
10675         echo "slab objects before: $before, after: $after"
10676 }
10677 run_test 76b "confirm clients recycle directory inodes properly ===="
10678
10679 export ORIG_CSUM=""
10680 set_checksums()
10681 {
10682         # Note: in sptlrpc modes which enable its own bulk checksum, the
10683         # original crc32_le bulk checksum will be automatically disabled,
10684         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10685         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10686         # In this case set_checksums() will not be no-op, because sptlrpc
10687         # bulk checksum will be enabled all through the test.
10688
10689         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10690         lctl set_param -n osc.*.checksums $1
10691         return 0
10692 }
10693
10694 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10695                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10696 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10697                              tr -d [] | head -n1)}
10698 set_checksum_type()
10699 {
10700         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10701         rc=$?
10702         log "set checksum type to $1, rc = $rc"
10703         return $rc
10704 }
10705
10706 get_osc_checksum_type()
10707 {
10708         # arugment 1: OST name, like OST0000
10709         ost=$1
10710         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10711                         sed 's/.*\[\(.*\)\].*/\1/g')
10712         rc=$?
10713         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10714         echo $checksum_type
10715 }
10716
10717 F77_TMP=$TMP/f77-temp
10718 F77SZ=8
10719 setup_f77() {
10720         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10721                 error "error writing to $F77_TMP"
10722 }
10723
10724 test_77a() { # bug 10889
10725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10726         $GSS && skip_env "could not run with gss"
10727
10728         [ ! -f $F77_TMP ] && setup_f77
10729         set_checksums 1
10730         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10731         set_checksums 0
10732         rm -f $DIR/$tfile
10733 }
10734 run_test 77a "normal checksum read/write operation"
10735
10736 test_77b() { # bug 10889
10737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10738         $GSS && skip_env "could not run with gss"
10739
10740         [ ! -f $F77_TMP ] && setup_f77
10741         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10742         $LCTL set_param fail_loc=0x80000409
10743         set_checksums 1
10744
10745         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10746                 error "dd error: $?"
10747         $LCTL set_param fail_loc=0
10748
10749         for algo in $CKSUM_TYPES; do
10750                 cancel_lru_locks osc
10751                 set_checksum_type $algo
10752                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10753                 $LCTL set_param fail_loc=0x80000408
10754                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10755                 $LCTL set_param fail_loc=0
10756         done
10757         set_checksums 0
10758         set_checksum_type $ORIG_CSUM_TYPE
10759         rm -f $DIR/$tfile
10760 }
10761 run_test 77b "checksum error on client write, read"
10762
10763 cleanup_77c() {
10764         trap 0
10765         set_checksums 0
10766         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10767         $check_ost &&
10768                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10769         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10770         $check_ost && [ -n "$ost_file_prefix" ] &&
10771                 do_facet ost1 rm -f ${ost_file_prefix}\*
10772 }
10773
10774 test_77c() {
10775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10776         $GSS && skip_env "could not run with gss"
10777         remote_ost_nodsh && skip "remote OST with nodsh"
10778
10779         local bad1
10780         local osc_file_prefix
10781         local osc_file
10782         local check_ost=false
10783         local ost_file_prefix
10784         local ost_file
10785         local orig_cksum
10786         local dump_cksum
10787         local fid
10788
10789         # ensure corruption will occur on first OSS/OST
10790         $LFS setstripe -i 0 $DIR/$tfile
10791
10792         [ ! -f $F77_TMP ] && setup_f77
10793         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10794                 error "dd write error: $?"
10795         fid=$($LFS path2fid $DIR/$tfile)
10796
10797         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10798         then
10799                 check_ost=true
10800                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10801                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10802         else
10803                 echo "OSS do not support bulk pages dump upon error"
10804         fi
10805
10806         osc_file_prefix=$($LCTL get_param -n debug_path)
10807         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10808
10809         trap cleanup_77c EXIT
10810
10811         set_checksums 1
10812         # enable bulk pages dump upon error on Client
10813         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10814         # enable bulk pages dump upon error on OSS
10815         $check_ost &&
10816                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10817
10818         # flush Client cache to allow next read to reach OSS
10819         cancel_lru_locks osc
10820
10821         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10822         $LCTL set_param fail_loc=0x80000408
10823         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10824         $LCTL set_param fail_loc=0
10825
10826         rm -f $DIR/$tfile
10827
10828         # check cksum dump on Client
10829         osc_file=$(ls ${osc_file_prefix}*)
10830         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10831         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10832         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10833         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10834         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10835                      cksum)
10836         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10837         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10838                 error "dump content does not match on Client"
10839
10840         $check_ost || skip "No need to check cksum dump on OSS"
10841
10842         # check cksum dump on OSS
10843         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10844         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10845         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10846         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10847         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10848                 error "dump content does not match on OSS"
10849
10850         cleanup_77c
10851 }
10852 run_test 77c "checksum error on client read with debug"
10853
10854 test_77d() { # bug 10889
10855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10856         $GSS && skip_env "could not run with gss"
10857
10858         stack_trap "rm -f $DIR/$tfile"
10859         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10860         $LCTL set_param fail_loc=0x80000409
10861         set_checksums 1
10862         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10863                 error "direct write: rc=$?"
10864         $LCTL set_param fail_loc=0
10865         set_checksums 0
10866
10867         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10868         $LCTL set_param fail_loc=0x80000408
10869         set_checksums 1
10870         cancel_lru_locks osc
10871         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10872                 error "direct read: rc=$?"
10873         $LCTL set_param fail_loc=0
10874         set_checksums 0
10875 }
10876 run_test 77d "checksum error on OST direct write, read"
10877
10878 test_77f() { # bug 10889
10879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10880         $GSS && skip_env "could not run with gss"
10881
10882         set_checksums 1
10883         stack_trap "rm -f $DIR/$tfile"
10884         for algo in $CKSUM_TYPES; do
10885                 cancel_lru_locks osc
10886                 set_checksum_type $algo
10887                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10888                 $LCTL set_param fail_loc=0x409
10889                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10890                         error "direct write succeeded"
10891                 $LCTL set_param fail_loc=0
10892         done
10893         set_checksum_type $ORIG_CSUM_TYPE
10894         set_checksums 0
10895 }
10896 run_test 77f "repeat checksum error on write (expect error)"
10897
10898 test_77g() { # bug 10889
10899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10900         $GSS && skip_env "could not run with gss"
10901         remote_ost_nodsh && skip "remote OST with nodsh"
10902
10903         [ ! -f $F77_TMP ] && setup_f77
10904
10905         local file=$DIR/$tfile
10906         stack_trap "rm -f $file" EXIT
10907
10908         $LFS setstripe -c 1 -i 0 $file
10909         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10910         do_facet ost1 lctl set_param fail_loc=0x8000021a
10911         set_checksums 1
10912         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10913                 error "write error: rc=$?"
10914         do_facet ost1 lctl set_param fail_loc=0
10915         set_checksums 0
10916
10917         cancel_lru_locks osc
10918         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10919         do_facet ost1 lctl set_param fail_loc=0x8000021b
10920         set_checksums 1
10921         cmp $F77_TMP $file || error "file compare failed"
10922         do_facet ost1 lctl set_param fail_loc=0
10923         set_checksums 0
10924 }
10925 run_test 77g "checksum error on OST write, read"
10926
10927 test_77k() { # LU-10906
10928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10929         $GSS && skip_env "could not run with gss"
10930
10931         local cksum_param="osc.$FSNAME*.checksums"
10932         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10933         local checksum
10934         local i
10935
10936         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10937         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10938         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10939
10940         for i in 0 1; do
10941                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10942                         error "failed to set checksum=$i on MGS"
10943                 wait_update $HOSTNAME "$get_checksum" $i
10944                 #remount
10945                 echo "remount client, checksum should be $i"
10946                 remount_client $MOUNT || error "failed to remount client"
10947                 checksum=$(eval $get_checksum)
10948                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10949         done
10950         # remove persistent param to avoid races with checksum mountopt below
10951         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10952                 error "failed to delete checksum on MGS"
10953
10954         for opt in "checksum" "nochecksum"; do
10955                 #remount with mount option
10956                 echo "remount client with option $opt, checksum should be $i"
10957                 umount_client $MOUNT || error "failed to umount client"
10958                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10959                         error "failed to mount client with option '$opt'"
10960                 checksum=$(eval $get_checksum)
10961                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10962                 i=$((i - 1))
10963         done
10964
10965         remount_client $MOUNT || error "failed to remount client"
10966 }
10967 run_test 77k "enable/disable checksum correctly"
10968
10969 test_77l() {
10970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10971         $GSS && skip_env "could not run with gss"
10972
10973         set_checksums 1
10974         stack_trap "set_checksums $ORIG_CSUM" EXIT
10975         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10976
10977         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10978
10979         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10980         for algo in $CKSUM_TYPES; do
10981                 set_checksum_type $algo || error "fail to set checksum type $algo"
10982                 osc_algo=$(get_osc_checksum_type OST0000)
10983                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10984
10985                 # no locks, no reqs to let the connection idle
10986                 cancel_lru_locks osc
10987                 lru_resize_disable osc
10988                 wait_osc_import_state client ost1 IDLE
10989
10990                 # ensure ost1 is connected
10991                 stat $DIR/$tfile >/dev/null || error "can't stat"
10992                 wait_osc_import_state client ost1 FULL
10993
10994                 osc_algo=$(get_osc_checksum_type OST0000)
10995                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10996         done
10997         return 0
10998 }
10999 run_test 77l "preferred checksum type is remembered after reconnected"
11000
11001 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11002 rm -f $F77_TMP
11003 unset F77_TMP
11004
11005 test_77m() {
11006         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11007                 skip "Need at least version 2.14.52"
11008         local param=checksum_speed
11009
11010         $LCTL get_param $param || error "reading $param failed"
11011
11012         csum_speeds=$($LCTL get_param -n $param)
11013
11014         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11015                 error "known checksum types are missing"
11016 }
11017 run_test 77m "Verify checksum_speed is correctly read"
11018
11019 check_filefrag_77n() {
11020         local nr_ext=0
11021         local starts=()
11022         local ends=()
11023
11024         while read extidx a b start end rest; do
11025                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11026                         nr_ext=$(( $nr_ext + 1 ))
11027                         starts+=( ${start%..} )
11028                         ends+=( ${end%:} )
11029                 fi
11030         done < <( filefrag -sv $1 )
11031
11032         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11033         return 1
11034 }
11035
11036 test_77n() {
11037         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11038
11039         touch $DIR/$tfile
11040         $TRUNCATE $DIR/$tfile 0
11041         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11042         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11043         check_filefrag_77n $DIR/$tfile ||
11044                 skip "$tfile blocks not contiguous around hole"
11045
11046         set_checksums 1
11047         stack_trap "set_checksums $ORIG_CSUM" EXIT
11048         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11049         stack_trap "rm -f $DIR/$tfile"
11050
11051         for algo in $CKSUM_TYPES; do
11052                 if [[ "$algo" =~ ^t10 ]]; then
11053                         set_checksum_type $algo ||
11054                                 error "fail to set checksum type $algo"
11055                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11056                                 error "fail to read $tfile with $algo"
11057                 fi
11058         done
11059         rm -f $DIR/$tfile
11060         return 0
11061 }
11062 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11063
11064 test_77o() {
11065         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11066                 skip "Need MDS version at least 2.14.55"
11067         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11068                 skip "Need OST version at least 2.14.55"
11069         local ofd=obdfilter
11070         local mdt=mdt
11071
11072         # print OST checksum_type
11073         echo "$ofd.$FSNAME-*.checksum_type:"
11074         do_nodes $(comma_list $(osts_nodes)) \
11075                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11076
11077         # print MDT checksum_type
11078         echo "$mdt.$FSNAME-*.checksum_type:"
11079         do_nodes $(comma_list $(mdts_nodes)) \
11080                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11081
11082         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11083                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11084
11085         (( $o_count == $OSTCOUNT )) ||
11086                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11087
11088         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11089                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11090
11091         (( $m_count == $MDSCOUNT )) ||
11092                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11093 }
11094 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11095
11096 cleanup_test_78() {
11097         trap 0
11098         rm -f $DIR/$tfile
11099 }
11100
11101 test_78() { # bug 10901
11102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11103         remote_ost || skip_env "local OST"
11104
11105         NSEQ=5
11106         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11107         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11108         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11109         echo "MemTotal: $MEMTOTAL"
11110
11111         # reserve 256MB of memory for the kernel and other running processes,
11112         # and then take 1/2 of the remaining memory for the read/write buffers.
11113         if [ $MEMTOTAL -gt 512 ] ;then
11114                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11115         else
11116                 # for those poor memory-starved high-end clusters...
11117                 MEMTOTAL=$((MEMTOTAL / 2))
11118         fi
11119         echo "Mem to use for directio: $MEMTOTAL"
11120
11121         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11122         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11123         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11124         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11125                 head -n1)
11126         echo "Smallest OST: $SMALLESTOST"
11127         [[ $SMALLESTOST -lt 10240 ]] &&
11128                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11129
11130         trap cleanup_test_78 EXIT
11131
11132         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11133                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11134
11135         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11136         echo "File size: $F78SIZE"
11137         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11138         for i in $(seq 1 $NSEQ); do
11139                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11140                 echo directIO rdwr round $i of $NSEQ
11141                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11142         done
11143
11144         cleanup_test_78
11145 }
11146 run_test 78 "handle large O_DIRECT writes correctly ============"
11147
11148 test_79() { # bug 12743
11149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11150
11151         wait_delete_completed
11152
11153         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11154         BKFREE=$(calc_osc_kbytes kbytesfree)
11155         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11156
11157         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11158         DFTOTAL=`echo $STRING | cut -d, -f1`
11159         DFUSED=`echo $STRING  | cut -d, -f2`
11160         DFAVAIL=`echo $STRING | cut -d, -f3`
11161         DFFREE=$(($DFTOTAL - $DFUSED))
11162
11163         ALLOWANCE=$((64 * $OSTCOUNT))
11164
11165         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11166            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11167                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11168         fi
11169         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11170            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11171                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11172         fi
11173         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11174            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11175                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11176         fi
11177 }
11178 run_test 79 "df report consistency check ======================="
11179
11180 test_80() { # bug 10718
11181         remote_ost_nodsh && skip "remote OST with nodsh"
11182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11183
11184         # relax strong synchronous semantics for slow backends like ZFS
11185         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11186                 local soc="obdfilter.*.sync_lock_cancel"
11187                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11188
11189                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11190                 if [ -z "$save" ]; then
11191                         soc="obdfilter.*.sync_on_lock_cancel"
11192                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11193                 fi
11194
11195                 if [ "$save" != "never" ]; then
11196                         local hosts=$(comma_list $(osts_nodes))
11197
11198                         do_nodes $hosts $LCTL set_param $soc=never
11199                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11200                 fi
11201         fi
11202
11203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11204         sync; sleep 1; sync
11205         local before=$(date +%s)
11206         cancel_lru_locks osc
11207         local after=$(date +%s)
11208         local diff=$((after - before))
11209         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11210
11211         rm -f $DIR/$tfile
11212 }
11213 run_test 80 "Page eviction is equally fast at high offsets too"
11214
11215 test_81a() { # LU-456
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         remote_ost_nodsh && skip "remote OST with nodsh"
11218
11219         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11220         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11221         do_facet ost1 lctl set_param fail_loc=0x80000228
11222
11223         # write should trigger a retry and success
11224         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11226         RC=$?
11227         if [ $RC -ne 0 ] ; then
11228                 error "write should success, but failed for $RC"
11229         fi
11230 }
11231 run_test 81a "OST should retry write when get -ENOSPC ==============="
11232
11233 test_81b() { # LU-456
11234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11235         remote_ost_nodsh && skip "remote OST with nodsh"
11236
11237         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11238         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11239         do_facet ost1 lctl set_param fail_loc=0x228
11240
11241         # write should retry several times and return -ENOSPC finally
11242         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11244         RC=$?
11245         ENOSPC=28
11246         if [ $RC -ne $ENOSPC ] ; then
11247                 error "dd should fail for -ENOSPC, but succeed."
11248         fi
11249 }
11250 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11251
11252 test_99() {
11253         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11254
11255         test_mkdir $DIR/$tdir.cvsroot
11256         chown $RUNAS_ID $DIR/$tdir.cvsroot
11257
11258         cd $TMP
11259         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11260
11261         cd /etc/init.d
11262         # some versions of cvs import exit(1) when asked to import links or
11263         # files they can't read.  ignore those files.
11264         local toignore=$(find . -type l -printf '-I %f\n' -o \
11265                          ! -perm /4 -printf '-I %f\n')
11266         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11267                 $tdir.reposname vtag rtag
11268
11269         cd $DIR
11270         test_mkdir $DIR/$tdir.reposname
11271         chown $RUNAS_ID $DIR/$tdir.reposname
11272         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11273
11274         cd $DIR/$tdir.reposname
11275         $RUNAS touch foo99
11276         $RUNAS cvs add -m 'addmsg' foo99
11277         $RUNAS cvs update
11278         $RUNAS cvs commit -m 'nomsg' foo99
11279         rm -fr $DIR/$tdir.cvsroot
11280 }
11281 run_test 99 "cvs strange file/directory operations"
11282
11283 test_100() {
11284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11285         [[ "$NETTYPE" =~ tcp ]] ||
11286                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11287         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11288         remote_ost_nodsh && skip "remote OST with nodsh"
11289         remote_mds_nodsh && skip "remote MDS with nodsh"
11290         remote_servers || skip "useless for local single node setup"
11291
11292         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11293                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11294
11295                 rc=0
11296                 if (( ${LOCAL/*:/} >= 1024 )); then
11297                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11298                         ss -tna
11299                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11300                 fi
11301         done
11302         (( $rc == 0 )) || error "privileged port not found" )
11303 }
11304 run_test 100 "check local port using privileged port"
11305
11306 function get_named_value()
11307 {
11308     local tag=$1
11309
11310     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11311 }
11312
11313 test_101a() {
11314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11315
11316         local s
11317         local discard
11318         local nreads=10000
11319         local cache_limit=32
11320
11321         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11322         $LCTL set_param -n llite.*.read_ahead_stats=0
11323         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11324                               awk '/^max_cached_mb/ { print $2 }')
11325         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11326         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11327
11328         #
11329         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11330         #
11331         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11332         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11333
11334         discard=0
11335         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11336                    get_named_value 'read.but.discarded'); do
11337                         discard=$(($discard + $s))
11338         done
11339
11340         $LCTL get_param osc.*-osc*.rpc_stats
11341         $LCTL get_param llite.*.read_ahead_stats
11342
11343         # Discard is generally zero, but sometimes a few random reads line up
11344         # and trigger larger readahead, which is wasted & leads to discards.
11345         if [[ $(($discard)) -gt $nreads ]]; then
11346                 error "too many ($discard) discarded pages"
11347         fi
11348         rm -f $DIR/$tfile || true
11349 }
11350 run_test 101a "check read-ahead for random reads"
11351
11352 setup_test101bc() {
11353         test_mkdir $DIR/$tdir
11354         local ssize=$1
11355         local FILE_LENGTH=$2
11356         STRIPE_OFFSET=0
11357
11358         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11359
11360         local list=$(comma_list $(osts_nodes))
11361         set_osd_param $list '' read_cache_enable 0
11362         set_osd_param $list '' writethrough_cache_enable 0
11363
11364         trap cleanup_test101bc EXIT
11365         # prepare the read-ahead file
11366         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11367
11368         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11369                                 count=$FILE_SIZE_MB 2> /dev/null
11370
11371 }
11372
11373 cleanup_test101bc() {
11374         trap 0
11375         rm -rf $DIR/$tdir
11376         rm -f $DIR/$tfile
11377
11378         local list=$(comma_list $(osts_nodes))
11379         set_osd_param $list '' read_cache_enable 1
11380         set_osd_param $list '' writethrough_cache_enable 1
11381 }
11382
11383 ra_check_101() {
11384         local read_size=$1
11385         local stripe_size=$2
11386         local stride_length=$((stripe_size / read_size))
11387         local stride_width=$((stride_length * OSTCOUNT))
11388         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11389                                 (stride_width - stride_length) ))
11390         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11391                   get_named_value 'read.but.discarded' | calc_sum)
11392
11393         if [[ $discard -gt $discard_limit ]]; then
11394                 $LCTL get_param llite.*.read_ahead_stats
11395                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11396         else
11397                 echo "Read-ahead success for size ${read_size}"
11398         fi
11399 }
11400
11401 test_101b() {
11402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11403         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11404
11405         local STRIPE_SIZE=1048576
11406         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11407
11408         if [ $SLOW == "yes" ]; then
11409                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11410         else
11411                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11412         fi
11413
11414         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11415
11416         # prepare the read-ahead file
11417         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11418         cancel_lru_locks osc
11419         for BIDX in 2 4 8 16 32 64 128 256
11420         do
11421                 local BSIZE=$((BIDX*4096))
11422                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11423                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11424                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11425                 $LCTL set_param -n llite.*.read_ahead_stats=0
11426                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11427                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11428                 cancel_lru_locks osc
11429                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11430         done
11431         cleanup_test101bc
11432         true
11433 }
11434 run_test 101b "check stride-io mode read-ahead ================="
11435
11436 test_101c() {
11437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11438
11439         local STRIPE_SIZE=1048576
11440         local FILE_LENGTH=$((STRIPE_SIZE*100))
11441         local nreads=10000
11442         local rsize=65536
11443         local osc_rpc_stats
11444
11445         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11446
11447         cancel_lru_locks osc
11448         $LCTL set_param osc.*.rpc_stats=0
11449         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11450         $LCTL get_param osc.*.rpc_stats
11451         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11452                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11453                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11454                 local size
11455
11456                 if [ $lines -le 20 ]; then
11457                         echo "continue debug"
11458                         continue
11459                 fi
11460                 for size in 1 2 4 8; do
11461                         local rpc=$(echo "$stats" |
11462                                     awk '($1 == "'$size':") {print $2; exit; }')
11463                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11464                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11465                 done
11466                 echo "$osc_rpc_stats check passed!"
11467         done
11468         cleanup_test101bc
11469         true
11470 }
11471 run_test 101c "check stripe_size aligned read-ahead"
11472
11473 test_101d() {
11474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11475
11476         local file=$DIR/$tfile
11477         local sz_MB=${FILESIZE_101d:-80}
11478         local ra_MB=${READAHEAD_MB:-40}
11479
11480         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11481         [ $free_MB -lt $sz_MB ] &&
11482                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11483
11484         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11485         $LFS setstripe -c -1 $file || error "setstripe failed"
11486
11487         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11488         echo Cancel LRU locks on lustre client to flush the client cache
11489         cancel_lru_locks osc
11490
11491         echo Disable read-ahead
11492         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11493         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11494         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11495         $LCTL get_param -n llite.*.max_read_ahead_mb
11496
11497         echo "Reading the test file $file with read-ahead disabled"
11498         local sz_KB=$((sz_MB * 1024 / 4))
11499         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11500         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11501         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11502         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11503                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11504
11505         echo "Cancel LRU locks on lustre client to flush the client cache"
11506         cancel_lru_locks osc
11507         echo Enable read-ahead with ${ra_MB}MB
11508         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11509
11510         echo "Reading the test file $file with read-ahead enabled"
11511         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11512                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11513
11514         echo "read-ahead disabled time read '$raOFF'"
11515         echo "read-ahead enabled time read '$raON'"
11516
11517         rm -f $file
11518         wait_delete_completed
11519
11520         # use awk for this check instead of bash because it handles decimals
11521         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11522                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11523 }
11524 run_test 101d "file read with and without read-ahead enabled"
11525
11526 test_101e() {
11527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11528
11529         local file=$DIR/$tfile
11530         local size_KB=500  #KB
11531         local count=100
11532         local bsize=1024
11533
11534         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11535         local need_KB=$((count * size_KB))
11536         [[ $free_KB -le $need_KB ]] &&
11537                 skip_env "Need free space $need_KB, have $free_KB"
11538
11539         echo "Creating $count ${size_KB}K test files"
11540         for ((i = 0; i < $count; i++)); do
11541                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11542         done
11543
11544         echo "Cancel LRU locks on lustre client to flush the client cache"
11545         cancel_lru_locks $OSC
11546
11547         echo "Reset readahead stats"
11548         $LCTL set_param -n llite.*.read_ahead_stats=0
11549
11550         for ((i = 0; i < $count; i++)); do
11551                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11552         done
11553
11554         $LCTL get_param llite.*.max_cached_mb
11555         $LCTL get_param llite.*.read_ahead_stats
11556         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11557                      get_named_value 'misses' | calc_sum)
11558
11559         for ((i = 0; i < $count; i++)); do
11560                 rm -rf $file.$i 2>/dev/null
11561         done
11562
11563         #10000 means 20% reads are missing in readahead
11564         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11565 }
11566 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11567
11568 test_101f() {
11569         which iozone || skip_env "no iozone installed"
11570
11571         local old_debug=$($LCTL get_param debug)
11572         old_debug=${old_debug#*=}
11573         $LCTL set_param debug="reada mmap"
11574
11575         # create a test file
11576         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11577
11578         echo Cancel LRU locks on lustre client to flush the client cache
11579         cancel_lru_locks osc
11580
11581         echo Reset readahead stats
11582         $LCTL set_param -n llite.*.read_ahead_stats=0
11583
11584         echo mmap read the file with small block size
11585         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11586                 > /dev/null 2>&1
11587
11588         echo checking missing pages
11589         $LCTL get_param llite.*.read_ahead_stats
11590         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11591                         get_named_value 'misses' | calc_sum)
11592
11593         $LCTL set_param debug="$old_debug"
11594         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11595         rm -f $DIR/$tfile
11596 }
11597 run_test 101f "check mmap read performance"
11598
11599 test_101g_brw_size_test() {
11600         local mb=$1
11601         local pages=$((mb * 1048576 / PAGE_SIZE))
11602         local file=$DIR/$tfile
11603
11604         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11605                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11606         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11607                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11608                         return 2
11609         done
11610
11611         stack_trap "rm -f $file" EXIT
11612         $LCTL set_param -n osc.*.rpc_stats=0
11613
11614         # 10 RPCs should be enough for the test
11615         local count=10
11616         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11617                 { error "dd write ${mb} MB blocks failed"; return 3; }
11618         cancel_lru_locks osc
11619         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11620                 { error "dd write ${mb} MB blocks failed"; return 4; }
11621
11622         # calculate number of full-sized read and write RPCs
11623         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11624                 sed -n '/pages per rpc/,/^$/p' |
11625                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11626                 END { print reads,writes }'))
11627         # allow one extra full-sized read RPC for async readahead
11628         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11629                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11630         [[ ${rpcs[1]} == $count ]] ||
11631                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11632 }
11633
11634 test_101g() {
11635         remote_ost_nodsh && skip "remote OST with nodsh"
11636
11637         local rpcs
11638         local osts=$(get_facets OST)
11639         local list=$(comma_list $(osts_nodes))
11640         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11641         local brw_size="obdfilter.*.brw_size"
11642
11643         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11644
11645         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11646
11647         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11648                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11649                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11650            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11651                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11652                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11653
11654                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11655                         suffix="M"
11656
11657                 if [[ $orig_mb -lt 16 ]]; then
11658                         save_lustre_params $osts "$brw_size" > $p
11659                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11660                                 error "set 16MB RPC size failed"
11661
11662                         echo "remount client to enable new RPC size"
11663                         remount_client $MOUNT || error "remount_client failed"
11664                 fi
11665
11666                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11667                 # should be able to set brw_size=12, but no rpc_stats for that
11668                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11669         fi
11670
11671         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11672
11673         if [[ $orig_mb -lt 16 ]]; then
11674                 restore_lustre_params < $p
11675                 remount_client $MOUNT || error "remount_client restore failed"
11676         fi
11677
11678         rm -f $p $DIR/$tfile
11679 }
11680 run_test 101g "Big bulk(4/16 MiB) readahead"
11681
11682 test_101h() {
11683         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11684
11685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11686                 error "dd 70M file failed"
11687         echo Cancel LRU locks on lustre client to flush the client cache
11688         cancel_lru_locks osc
11689
11690         echo "Reset readahead stats"
11691         $LCTL set_param -n llite.*.read_ahead_stats 0
11692
11693         echo "Read 10M of data but cross 64M bundary"
11694         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11695         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11696                      get_named_value 'misses' | calc_sum)
11697         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11698         rm -f $p $DIR/$tfile
11699 }
11700 run_test 101h "Readahead should cover current read window"
11701
11702 test_101i() {
11703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11704                 error "dd 10M file failed"
11705
11706         local max_per_file_mb=$($LCTL get_param -n \
11707                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11708         cancel_lru_locks osc
11709         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11710         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11711                 error "set max_read_ahead_per_file_mb to 1 failed"
11712
11713         echo "Reset readahead stats"
11714         $LCTL set_param llite.*.read_ahead_stats=0
11715
11716         dd if=$DIR/$tfile of=/dev/null bs=2M
11717
11718         $LCTL get_param llite.*.read_ahead_stats
11719         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11720                      awk '/misses/ { print $2 }')
11721         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11722         rm -f $DIR/$tfile
11723 }
11724 run_test 101i "allow current readahead to exceed reservation"
11725
11726 test_101j() {
11727         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11728                 error "setstripe $DIR/$tfile failed"
11729         local file_size=$((1048576 * 16))
11730         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11731         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11732
11733         echo Disable read-ahead
11734         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11735
11736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11737         for blk in $PAGE_SIZE 1048576 $file_size; do
11738                 cancel_lru_locks osc
11739                 echo "Reset readahead stats"
11740                 $LCTL set_param -n llite.*.read_ahead_stats=0
11741                 local count=$(($file_size / $blk))
11742                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11743                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11744                              get_named_value 'failed.to.fast.read' | calc_sum)
11745                 $LCTL get_param -n llite.*.read_ahead_stats
11746                 [ $miss -eq $count ] || error "expected $count got $miss"
11747         done
11748
11749         rm -f $p $DIR/$tfile
11750 }
11751 run_test 101j "A complete read block should be submitted when no RA"
11752
11753 test_readahead_base() {
11754         local file=$DIR/$tfile
11755         local size=$1
11756         local iosz
11757         local ramax
11758         local ranum
11759
11760         $LCTL set_param -n llite.*.read_ahead_stats=0
11761         # The first page is not accounted into readahead
11762         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11763         iosz=$(((size + 1048575) / 1048576 * 1048576))
11764         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11765
11766         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11767         fallocate -l $size $file || error "failed to fallocate $file"
11768         cancel_lru_locks osc
11769         $MULTIOP $file or${iosz}c || error "failed to read $file"
11770         $LCTL get_param -n llite.*.read_ahead_stats
11771         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11772                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11773         (( $ranum <= $ramax )) ||
11774                 error "read-ahead pages is $ranum more than $ramax"
11775         rm -rf $file || error "failed to remove $file"
11776 }
11777
11778 test_101m()
11779 {
11780         local file=$DIR/$tfile
11781         local ramax
11782         local ranum
11783         local size
11784         local iosz
11785
11786         check_set_fallocate_or_skip
11787         stack_trap "rm -f $file" EXIT
11788
11789         test_readahead_base 4096
11790
11791         # file size: 16K = 16384
11792         test_readahead_base 16384
11793         test_readahead_base 16385
11794         test_readahead_base 16383
11795
11796         # file size: 1M + 1 = 1048576 + 1
11797         test_readahead_base 1048577
11798         # file size: 1M + 16K
11799         test_readahead_base $((1048576 + 16384))
11800
11801         # file size: stripe_size * (stripe_count - 1) + 16K
11802         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11803         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11804         # file size: stripe_size * stripe_count + 16K
11805         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11806         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11807         # file size: 2 * stripe_size * stripe_count + 16K
11808         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11809         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11810 }
11811 run_test 101m "read ahead for small file and last stripe of the file"
11812
11813 setup_test102() {
11814         test_mkdir $DIR/$tdir
11815         chown $RUNAS_ID $DIR/$tdir
11816         STRIPE_SIZE=65536
11817         STRIPE_OFFSET=1
11818         STRIPE_COUNT=$OSTCOUNT
11819         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11820
11821         trap cleanup_test102 EXIT
11822         cd $DIR
11823         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11824         cd $DIR/$tdir
11825         for num in 1 2 3 4; do
11826                 for count in $(seq 1 $STRIPE_COUNT); do
11827                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11828                                 local size=`expr $STRIPE_SIZE \* $num`
11829                                 local file=file"$num-$idx-$count"
11830                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11831                         done
11832                 done
11833         done
11834
11835         cd $DIR
11836         $1 tar cf $TMP/f102.tar $tdir --xattrs
11837 }
11838
11839 cleanup_test102() {
11840         trap 0
11841         rm -f $TMP/f102.tar
11842         rm -rf $DIR/d0.sanity/d102
11843 }
11844
11845 test_102a() {
11846         [ "$UID" != 0 ] && skip "must run as root"
11847         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11848                 skip_env "must have user_xattr"
11849
11850         [ -z "$(which setfattr 2>/dev/null)" ] &&
11851                 skip_env "could not find setfattr"
11852
11853         local testfile=$DIR/$tfile
11854
11855         touch $testfile
11856         echo "set/get xattr..."
11857         setfattr -n trusted.name1 -v value1 $testfile ||
11858                 error "setfattr -n trusted.name1=value1 $testfile failed"
11859         getfattr -n trusted.name1 $testfile 2> /dev/null |
11860           grep "trusted.name1=.value1" ||
11861                 error "$testfile missing trusted.name1=value1"
11862
11863         setfattr -n user.author1 -v author1 $testfile ||
11864                 error "setfattr -n user.author1=author1 $testfile failed"
11865         getfattr -n user.author1 $testfile 2> /dev/null |
11866           grep "user.author1=.author1" ||
11867                 error "$testfile missing trusted.author1=author1"
11868
11869         echo "listxattr..."
11870         setfattr -n trusted.name2 -v value2 $testfile ||
11871                 error "$testfile unable to set trusted.name2"
11872         setfattr -n trusted.name3 -v value3 $testfile ||
11873                 error "$testfile unable to set trusted.name3"
11874         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11875             grep "trusted.name" | wc -l) -eq 3 ] ||
11876                 error "$testfile missing 3 trusted.name xattrs"
11877
11878         setfattr -n user.author2 -v author2 $testfile ||
11879                 error "$testfile unable to set user.author2"
11880         setfattr -n user.author3 -v author3 $testfile ||
11881                 error "$testfile unable to set user.author3"
11882         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11883             grep "user.author" | wc -l) -eq 3 ] ||
11884                 error "$testfile missing 3 user.author xattrs"
11885
11886         echo "remove xattr..."
11887         setfattr -x trusted.name1 $testfile ||
11888                 error "$testfile error deleting trusted.name1"
11889         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11890                 error "$testfile did not delete trusted.name1 xattr"
11891
11892         setfattr -x user.author1 $testfile ||
11893                 error "$testfile error deleting user.author1"
11894         echo "set lustre special xattr ..."
11895         $LFS setstripe -c1 $testfile
11896         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11897                 awk -F "=" '/trusted.lov/ { print $2 }' )
11898         setfattr -n "trusted.lov" -v $lovea $testfile ||
11899                 error "$testfile doesn't ignore setting trusted.lov again"
11900         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11901                 error "$testfile allow setting invalid trusted.lov"
11902         rm -f $testfile
11903 }
11904 run_test 102a "user xattr test =================================="
11905
11906 check_102b_layout() {
11907         local layout="$*"
11908         local testfile=$DIR/$tfile
11909
11910         echo "test layout '$layout'"
11911         $LFS setstripe $layout $testfile || error "setstripe failed"
11912         $LFS getstripe -y $testfile
11913
11914         echo "get/set/list trusted.lov xattr ..." # b=10930
11915         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11916         [[ "$value" =~ "trusted.lov" ]] ||
11917                 error "can't get trusted.lov from $testfile"
11918         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11919                 error "getstripe failed"
11920
11921         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11922
11923         value=$(cut -d= -f2 <<<$value)
11924         # LU-13168: truncated xattr should fail if short lov_user_md header
11925         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11926                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11927         for len in $lens; do
11928                 echo "setfattr $len $testfile.2"
11929                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11930                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11931         done
11932         local stripe_size=$($LFS getstripe -S $testfile.2)
11933         local stripe_count=$($LFS getstripe -c $testfile.2)
11934         [[ $stripe_size -eq 65536 ]] ||
11935                 error "stripe size $stripe_size != 65536"
11936         [[ $stripe_count -eq $stripe_count_orig ]] ||
11937                 error "stripe count $stripe_count != $stripe_count_orig"
11938         rm $testfile $testfile.2
11939 }
11940
11941 test_102b() {
11942         [ -z "$(which setfattr 2>/dev/null)" ] &&
11943                 skip_env "could not find setfattr"
11944         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11945
11946         # check plain layout
11947         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11948
11949         # and also check composite layout
11950         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11951
11952 }
11953 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11954
11955 test_102c() {
11956         [ -z "$(which setfattr 2>/dev/null)" ] &&
11957                 skip_env "could not find setfattr"
11958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11959
11960         # b10930: get/set/list lustre.lov xattr
11961         echo "get/set/list lustre.lov xattr ..."
11962         test_mkdir $DIR/$tdir
11963         chown $RUNAS_ID $DIR/$tdir
11964         local testfile=$DIR/$tdir/$tfile
11965         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11966                 error "setstripe failed"
11967         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11968                 error "getstripe failed"
11969         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11970         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11971
11972         local testfile2=${testfile}2
11973         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11974                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11975
11976         $RUNAS $MCREATE $testfile2
11977         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11978         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11979         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11980         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11981         [ $stripe_count -eq $STRIPECOUNT ] ||
11982                 error "stripe count $stripe_count != $STRIPECOUNT"
11983 }
11984 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11985
11986 compare_stripe_info1() {
11987         local stripe_index_all_zero=true
11988
11989         for num in 1 2 3 4; do
11990                 for count in $(seq 1 $STRIPE_COUNT); do
11991                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11992                                 local size=$((STRIPE_SIZE * num))
11993                                 local file=file"$num-$offset-$count"
11994                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11995                                 [[ $stripe_size -ne $size ]] &&
11996                                     error "$file: size $stripe_size != $size"
11997                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11998                                 # allow fewer stripes to be created, ORI-601
11999                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12000                                     error "$file: count $stripe_count != $count"
12001                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12002                                 [[ $stripe_index -ne 0 ]] &&
12003                                         stripe_index_all_zero=false
12004                         done
12005                 done
12006         done
12007         $stripe_index_all_zero &&
12008                 error "all files are being extracted starting from OST index 0"
12009         return 0
12010 }
12011
12012 have_xattrs_include() {
12013         tar --help | grep -q xattrs-include &&
12014                 echo --xattrs-include="lustre.*"
12015 }
12016
12017 test_102d() {
12018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12020
12021         XINC=$(have_xattrs_include)
12022         setup_test102
12023         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12024         cd $DIR/$tdir/$tdir
12025         compare_stripe_info1
12026 }
12027 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12028
12029 test_102f() {
12030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12031         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12032
12033         XINC=$(have_xattrs_include)
12034         setup_test102
12035         test_mkdir $DIR/$tdir.restore
12036         cd $DIR
12037         tar cf - --xattrs $tdir | tar xf - \
12038                 -C $DIR/$tdir.restore --xattrs $XINC
12039         cd $DIR/$tdir.restore/$tdir
12040         compare_stripe_info1
12041 }
12042 run_test 102f "tar copy files, not keep osts"
12043
12044 grow_xattr() {
12045         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12046                 skip "must have user_xattr"
12047         [ -z "$(which setfattr 2>/dev/null)" ] &&
12048                 skip_env "could not find setfattr"
12049         [ -z "$(which getfattr 2>/dev/null)" ] &&
12050                 skip_env "could not find getfattr"
12051
12052         local xsize=${1:-1024}  # in bytes
12053         local file=$DIR/$tfile
12054         local value="$(generate_string $xsize)"
12055         local xbig=trusted.big
12056         local toobig=$2
12057
12058         touch $file
12059         log "save $xbig on $file"
12060         if [ -z "$toobig" ]
12061         then
12062                 setfattr -n $xbig -v $value $file ||
12063                         error "saving $xbig on $file failed"
12064         else
12065                 setfattr -n $xbig -v $value $file &&
12066                         error "saving $xbig on $file succeeded"
12067                 return 0
12068         fi
12069
12070         local orig=$(get_xattr_value $xbig $file)
12071         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12072
12073         local xsml=trusted.sml
12074         log "save $xsml on $file"
12075         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12076
12077         local new=$(get_xattr_value $xbig $file)
12078         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12079
12080         log "grow $xsml on $file"
12081         setfattr -n $xsml -v "$value" $file ||
12082                 error "growing $xsml on $file failed"
12083
12084         new=$(get_xattr_value $xbig $file)
12085         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12086         log "$xbig still valid after growing $xsml"
12087
12088         rm -f $file
12089 }
12090
12091 test_102h() { # bug 15777
12092         grow_xattr 1024
12093 }
12094 run_test 102h "grow xattr from inside inode to external block"
12095
12096 test_102ha() {
12097         large_xattr_enabled || skip_env "ea_inode feature disabled"
12098
12099         echo "setting xattr of max xattr size: $(max_xattr_size)"
12100         grow_xattr $(max_xattr_size)
12101
12102         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12103         echo "This should fail:"
12104         grow_xattr $(($(max_xattr_size) + 10)) 1
12105 }
12106 run_test 102ha "grow xattr from inside inode to external inode"
12107
12108 test_102i() { # bug 17038
12109         [ -z "$(which getfattr 2>/dev/null)" ] &&
12110                 skip "could not find getfattr"
12111
12112         touch $DIR/$tfile
12113         ln -s $DIR/$tfile $DIR/${tfile}link
12114         getfattr -n trusted.lov $DIR/$tfile ||
12115                 error "lgetxattr on $DIR/$tfile failed"
12116         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12117                 grep -i "no such attr" ||
12118                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12119         rm -f $DIR/$tfile $DIR/${tfile}link
12120 }
12121 run_test 102i "lgetxattr test on symbolic link ============"
12122
12123 test_102j() {
12124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12126
12127         XINC=$(have_xattrs_include)
12128         setup_test102 "$RUNAS"
12129         chown $RUNAS_ID $DIR/$tdir
12130         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12131         cd $DIR/$tdir/$tdir
12132         compare_stripe_info1 "$RUNAS"
12133 }
12134 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12135
12136 test_102k() {
12137         [ -z "$(which setfattr 2>/dev/null)" ] &&
12138                 skip "could not find setfattr"
12139
12140         touch $DIR/$tfile
12141         # b22187 just check that does not crash for regular file.
12142         setfattr -n trusted.lov $DIR/$tfile
12143         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12144         local test_kdir=$DIR/$tdir
12145         test_mkdir $test_kdir
12146         local default_size=$($LFS getstripe -S $test_kdir)
12147         local default_count=$($LFS getstripe -c $test_kdir)
12148         local default_offset=$($LFS getstripe -i $test_kdir)
12149         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12150                 error 'dir setstripe failed'
12151         setfattr -n trusted.lov $test_kdir
12152         local stripe_size=$($LFS getstripe -S $test_kdir)
12153         local stripe_count=$($LFS getstripe -c $test_kdir)
12154         local stripe_offset=$($LFS getstripe -i $test_kdir)
12155         [ $stripe_size -eq $default_size ] ||
12156                 error "stripe size $stripe_size != $default_size"
12157         [ $stripe_count -eq $default_count ] ||
12158                 error "stripe count $stripe_count != $default_count"
12159         [ $stripe_offset -eq $default_offset ] ||
12160                 error "stripe offset $stripe_offset != $default_offset"
12161         rm -rf $DIR/$tfile $test_kdir
12162 }
12163 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12164
12165 test_102l() {
12166         [ -z "$(which getfattr 2>/dev/null)" ] &&
12167                 skip "could not find getfattr"
12168
12169         # LU-532 trusted. xattr is invisible to non-root
12170         local testfile=$DIR/$tfile
12171
12172         touch $testfile
12173
12174         echo "listxattr as user..."
12175         chown $RUNAS_ID $testfile
12176         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12177             grep -q "trusted" &&
12178                 error "$testfile trusted xattrs are user visible"
12179
12180         return 0;
12181 }
12182 run_test 102l "listxattr size test =================================="
12183
12184 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12185         local path=$DIR/$tfile
12186         touch $path
12187
12188         listxattr_size_check $path || error "listattr_size_check $path failed"
12189 }
12190 run_test 102m "Ensure listxattr fails on small bufffer ========"
12191
12192 cleanup_test102
12193
12194 getxattr() { # getxattr path name
12195         # Return the base64 encoding of the value of xattr name on path.
12196         local path=$1
12197         local name=$2
12198
12199         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12200         # file: $path
12201         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12202         #
12203         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12204
12205         getfattr --absolute-names --encoding=base64 --name=$name $path |
12206                 awk -F= -v name=$name '$1 == name {
12207                         print substr($0, index($0, "=") + 1);
12208         }'
12209 }
12210
12211 test_102n() { # LU-4101 mdt: protect internal xattrs
12212         [ -z "$(which setfattr 2>/dev/null)" ] &&
12213                 skip "could not find setfattr"
12214         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12215         then
12216                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12217         fi
12218
12219         local file0=$DIR/$tfile.0
12220         local file1=$DIR/$tfile.1
12221         local xattr0=$TMP/$tfile.0
12222         local xattr1=$TMP/$tfile.1
12223         local namelist="lov lma lmv link fid version som hsm"
12224         local name
12225         local value
12226
12227         rm -rf $file0 $file1 $xattr0 $xattr1
12228         touch $file0 $file1
12229
12230         # Get 'before' xattrs of $file1.
12231         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12232
12233         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12234                 namelist+=" lfsck_namespace"
12235         for name in $namelist; do
12236                 # Try to copy xattr from $file0 to $file1.
12237                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12238
12239                 setfattr --name=trusted.$name --value="$value" $file1 ||
12240                         error "setxattr 'trusted.$name' failed"
12241
12242                 # Try to set a garbage xattr.
12243                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12244
12245                 if [[ x$name == "xlov" ]]; then
12246                         setfattr --name=trusted.lov --value="$value" $file1 &&
12247                         error "setxattr invalid 'trusted.lov' success"
12248                 else
12249                         setfattr --name=trusted.$name --value="$value" $file1 ||
12250                                 error "setxattr invalid 'trusted.$name' failed"
12251                 fi
12252
12253                 # Try to remove the xattr from $file1. We don't care if this
12254                 # appears to succeed or fail, we just don't want there to be
12255                 # any changes or crashes.
12256                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12257         done
12258
12259         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12260         then
12261                 name="lfsck_ns"
12262                 # Try to copy xattr from $file0 to $file1.
12263                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12264
12265                 setfattr --name=trusted.$name --value="$value" $file1 ||
12266                         error "setxattr 'trusted.$name' failed"
12267
12268                 # Try to set a garbage xattr.
12269                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12270
12271                 setfattr --name=trusted.$name --value="$value" $file1 ||
12272                         error "setxattr 'trusted.$name' failed"
12273
12274                 # Try to remove the xattr from $file1. We don't care if this
12275                 # appears to succeed or fail, we just don't want there to be
12276                 # any changes or crashes.
12277                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12278         fi
12279
12280         # Get 'after' xattrs of file1.
12281         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12282
12283         if ! diff $xattr0 $xattr1; then
12284                 error "before and after xattrs of '$file1' differ"
12285         fi
12286
12287         rm -rf $file0 $file1 $xattr0 $xattr1
12288
12289         return 0
12290 }
12291 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12292
12293 test_102p() { # LU-4703 setxattr did not check ownership
12294         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12295                 skip "MDS needs to be at least 2.5.56"
12296
12297         local testfile=$DIR/$tfile
12298
12299         touch $testfile
12300
12301         echo "setfacl as user..."
12302         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12303         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12304
12305         echo "setfattr as user..."
12306         setfacl -m "u:$RUNAS_ID:---" $testfile
12307         $RUNAS setfattr -x system.posix_acl_access $testfile
12308         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12309 }
12310 run_test 102p "check setxattr(2) correctly fails without permission"
12311
12312 test_102q() {
12313         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12314                 skip "MDS needs to be at least 2.6.92"
12315
12316         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12317 }
12318 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12319
12320 test_102r() {
12321         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12322                 skip "MDS needs to be at least 2.6.93"
12323
12324         touch $DIR/$tfile || error "touch"
12325         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12326         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12327         rm $DIR/$tfile || error "rm"
12328
12329         #normal directory
12330         mkdir -p $DIR/$tdir || error "mkdir"
12331         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12332         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12333         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12334                 error "$testfile error deleting user.author1"
12335         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12336                 grep "user.$(basename $tdir)" &&
12337                 error "$tdir did not delete user.$(basename $tdir)"
12338         rmdir $DIR/$tdir || error "rmdir"
12339
12340         #striped directory
12341         test_mkdir $DIR/$tdir
12342         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12343         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12344         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12345                 error "$testfile error deleting user.author1"
12346         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12347                 grep "user.$(basename $tdir)" &&
12348                 error "$tdir did not delete user.$(basename $tdir)"
12349         rmdir $DIR/$tdir || error "rm striped dir"
12350 }
12351 run_test 102r "set EAs with empty values"
12352
12353 test_102s() {
12354         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12355                 skip "MDS needs to be at least 2.11.52"
12356
12357         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12358
12359         save_lustre_params client "llite.*.xattr_cache" > $save
12360
12361         for cache in 0 1; do
12362                 lctl set_param llite.*.xattr_cache=$cache
12363
12364                 rm -f $DIR/$tfile
12365                 touch $DIR/$tfile || error "touch"
12366                 for prefix in lustre security system trusted user; do
12367                         # Note getxattr() may fail with 'Operation not
12368                         # supported' or 'No such attribute' depending
12369                         # on prefix and cache.
12370                         getfattr -n $prefix.n102s $DIR/$tfile &&
12371                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12372                 done
12373         done
12374
12375         restore_lustre_params < $save
12376 }
12377 run_test 102s "getting nonexistent xattrs should fail"
12378
12379 test_102t() {
12380         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12381                 skip "MDS needs to be at least 2.11.52"
12382
12383         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12384
12385         save_lustre_params client "llite.*.xattr_cache" > $save
12386
12387         for cache in 0 1; do
12388                 lctl set_param llite.*.xattr_cache=$cache
12389
12390                 for buf_size in 0 256; do
12391                         rm -f $DIR/$tfile
12392                         touch $DIR/$tfile || error "touch"
12393                         setfattr -n user.multiop $DIR/$tfile
12394                         $MULTIOP $DIR/$tfile oa$buf_size ||
12395                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12396                 done
12397         done
12398
12399         restore_lustre_params < $save
12400 }
12401 run_test 102t "zero length xattr values handled correctly"
12402
12403 run_acl_subtest()
12404 {
12405         local test=$LUSTRE/tests/acl/$1.test
12406         local tmp=$(mktemp -t $1-XXXXXX).test
12407         local bin=$2
12408         local dmn=$3
12409         local grp=$4
12410         local nbd=$5
12411         export LANG=C
12412
12413
12414         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12415         local sedgroups="-e s/:users/:$grp/g"
12416         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12417
12418         sed $sedusers $sedgroups < $test > $tmp
12419         stack_trap "rm -f $tmp"
12420         [[ -s $tmp ]] || error "sed failed to create test script"
12421
12422         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12423         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12424 }
12425
12426 test_103a() {
12427         [ "$UID" != 0 ] && skip "must run as root"
12428         $GSS && skip_env "could not run under gss"
12429         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12430                 skip_env "must have acl enabled"
12431         which setfacl || skip_env "could not find setfacl"
12432         remote_mds_nodsh && skip "remote MDS with nodsh"
12433
12434         local mdts=$(comma_list $(mdts_nodes))
12435         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12436
12437         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12438         stack_trap "[[ -z \"$saved\" ]] || \
12439                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12440
12441         ACLBIN=${ACLBIN:-"bin"}
12442         ACLDMN=${ACLDMN:-"daemon"}
12443         ACLGRP=${ACLGRP:-"users"}
12444         ACLNBD=${ACLNBD:-"nobody"}
12445
12446         if ! id $ACLBIN ||
12447            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12448                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12449                 ACLBIN=$USER0
12450                 if ! id $ACLBIN ; then
12451                         cat /etc/passwd
12452                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12453                 fi
12454         fi
12455         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12456            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12457                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12458                 ACLDMN=$USER1
12459                 if ! id $ACLDMN ; then
12460                         cat /etc/passwd
12461                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12462                 fi
12463         fi
12464         if ! getent group $ACLGRP; then
12465                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12466                 ACLGRP="$TSTUSR"
12467                 if ! getent group $ACLGRP; then
12468                         echo "cannot find group '$ACLGRP', adding it"
12469                         cat /etc/group
12470                         add_group 60000 $ACLGRP
12471                 fi
12472         fi
12473
12474         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12475         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12476         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12477
12478         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12479                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12480                 ACLGRP="$TSTUSR"
12481                 if ! getent group $ACLGRP; then
12482                         echo "cannot find group '$ACLGRP', adding it"
12483                         cat /etc/group
12484                         add_group 60000 $ACLGRP
12485                 fi
12486                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12487                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12488                         cat /etc/group
12489                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12490                 fi
12491         fi
12492
12493         gpasswd -a $ACLDMN $ACLBIN ||
12494                 error "setting client group failed"             # LU-5641
12495         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12496                 error "setting MDS group failed"                # LU-5641
12497
12498         declare -a identity_old
12499
12500         for ((num = 1; num <= $MDSCOUNT; num++)); do
12501                 switch_identity $num true || identity_old[$num]=$?
12502         done
12503
12504         SAVE_UMASK=$(umask)
12505         umask 0022
12506         mkdir -p $DIR/$tdir
12507         cd $DIR/$tdir
12508
12509         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12510         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12511         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12512         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12513         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12514         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12515         if ! id -u $ACLNBD ||
12516            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12517                 ACLNBD="nfsnobody"
12518                 if ! id -u $ACLNBD; then
12519                         ACLNBD=""
12520                 fi
12521         fi
12522         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12523                 add_group $(id -u $ACLNBD) $ACLNBD
12524                 if ! getent group $ACLNBD; then
12525                         ACLNBD=""
12526                 fi
12527         fi
12528         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12529            [[ -n "$ACLNBD" ]] && which setfattr; then
12530                 run_acl_subtest permissions_xattr \
12531                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12532         elif [[ -z "$ACLNBD" ]]; then
12533                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12534         else
12535                 echo "skip 'permission_xattr' test - missing setfattr command"
12536         fi
12537         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12538
12539         # inheritance test got from HP
12540         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12541         chmod +x make-tree || error "chmod +x failed"
12542         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12543         rm -f make-tree
12544
12545         echo "LU-974 ignore umask when acl is enabled..."
12546         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12547         if [ $MDSCOUNT -ge 2 ]; then
12548                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12549         fi
12550
12551         echo "LU-2561 newly created file is same size as directory..."
12552         if [ "$mds1_FSTYPE" != "zfs" ]; then
12553                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12554         else
12555                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12556         fi
12557
12558         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12559
12560         cd $SAVE_PWD
12561         umask $SAVE_UMASK
12562
12563         for ((num = 1; num <= $MDSCOUNT; num++)); do
12564                 if [[ "${identity_old[$num]}" == 1 ]]; then
12565                         switch_identity $num false || identity_old[$num]=$?
12566                 fi
12567         done
12568 }
12569 run_test 103a "acl test"
12570
12571 test_103b() {
12572         declare -a pids
12573         local U
12574
12575         stack_trap "rm -f $DIR/$tfile.*"
12576         for U in {0..511}; do
12577                 {
12578                 local O=$(printf "%04o" $U)
12579
12580                 umask $(printf "%04o" $((511 ^ $O)))
12581                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12582                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12583
12584                 (( $S == ($O & 0666) )) ||
12585                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12586
12587                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12588                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12589                 (( $S == ($O & 0666) )) ||
12590                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12591
12592                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12593                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12594                 (( $S == ($O & 0666) )) ||
12595                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12596                 rm -f $DIR/$tfile.[smp]$0
12597                 } &
12598                 local pid=$!
12599
12600                 # limit the concurrently running threads to 64. LU-11878
12601                 local idx=$((U % 64))
12602                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12603                 pids[idx]=$pid
12604         done
12605         wait
12606 }
12607 run_test 103b "umask lfs setstripe"
12608
12609 test_103c() {
12610         mkdir -p $DIR/$tdir
12611         cp -rp $DIR/$tdir $DIR/$tdir.bak
12612
12613         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12614                 error "$DIR/$tdir shouldn't contain default ACL"
12615         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12616                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12617         true
12618 }
12619 run_test 103c "'cp -rp' won't set empty acl"
12620
12621 test_103e() {
12622         local numacl
12623         local fileacl
12624         local saved_debug=$($LCTL get_param -n debug)
12625
12626         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12627                 skip "MDS needs to be at least 2.14.52"
12628
12629         large_xattr_enabled || skip_env "ea_inode feature disabled"
12630
12631         mkdir -p $DIR/$tdir
12632         # add big LOV EA to cause reply buffer overflow earlier
12633         $LFS setstripe -C 1000 $DIR/$tdir
12634         lctl set_param mdc.*-mdc*.stats=clear
12635
12636         $LCTL set_param debug=0
12637         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12638         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12639
12640         # add a large number of default ACLs (expect 8000+ for 2.13+)
12641         for U in {2..7000}; do
12642                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12643                         error "Able to add just $U default ACLs"
12644         done
12645         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12646         echo "$numacl default ACLs created"
12647
12648         stat $DIR/$tdir || error "Cannot stat directory"
12649         # check file creation
12650         touch $DIR/$tdir/$tfile ||
12651                 error "failed to create $tfile with $numacl default ACLs"
12652         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12653         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12654         echo "$fileacl ACLs were inherited"
12655         (( $fileacl == $numacl )) ||
12656                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12657         # check that new ACLs creation adds new ACLs to inherited ACLs
12658         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12659                 error "Cannot set new ACL"
12660         numacl=$((numacl + 1))
12661         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12662         (( $fileacl == $numacl )) ||
12663                 error "failed to add new ACL: $fileacl != $numacl as expected"
12664         # adds more ACLs to a file to reach their maximum at 8000+
12665         numacl=0
12666         for U in {20000..25000}; do
12667                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12668                 numacl=$((numacl + 1))
12669         done
12670         echo "Added $numacl more ACLs to the file"
12671         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12672         echo "Total $fileacl ACLs in file"
12673         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12674         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12675         rmdir $DIR/$tdir || error "Cannot remove directory"
12676 }
12677 run_test 103e "inheritance of big amount of default ACLs"
12678
12679 test_103f() {
12680         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12681                 skip "MDS needs to be at least 2.14.51"
12682
12683         large_xattr_enabled || skip_env "ea_inode feature disabled"
12684
12685         # enable changelog to consume more internal MDD buffers
12686         changelog_register
12687
12688         mkdir -p $DIR/$tdir
12689         # add big LOV EA
12690         $LFS setstripe -C 1000 $DIR/$tdir
12691         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12692         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12693         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12694         rmdir $DIR/$tdir || error "Cannot remove directory"
12695 }
12696 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12697
12698 test_104a() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700
12701         touch $DIR/$tfile
12702         lfs df || error "lfs df failed"
12703         lfs df -ih || error "lfs df -ih failed"
12704         lfs df -h $DIR || error "lfs df -h $DIR failed"
12705         lfs df -i $DIR || error "lfs df -i $DIR failed"
12706         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12707         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12708
12709         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12710         lctl --device %$OSC deactivate
12711         lfs df || error "lfs df with deactivated OSC failed"
12712         lctl --device %$OSC activate
12713         # wait the osc back to normal
12714         wait_osc_import_ready client ost
12715
12716         lfs df || error "lfs df with reactivated OSC failed"
12717         rm -f $DIR/$tfile
12718 }
12719 run_test 104a "lfs df [-ih] [path] test ========================="
12720
12721 test_104b() {
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723         [ $RUNAS_ID -eq $UID ] &&
12724                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12725
12726         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12727                         grep "Permission denied" | wc -l)))
12728         if [ $denied_cnt -ne 0 ]; then
12729                 error "lfs check servers test failed"
12730         fi
12731 }
12732 run_test 104b "$RUNAS lfs check servers test ===================="
12733
12734 #
12735 # Verify $1 is within range of $2.
12736 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12737 # $1 is <= 2% of $2. Else Fail.
12738 #
12739 value_in_range() {
12740         # Strip all units (M, G, T)
12741         actual=$(echo $1 | tr -d A-Z)
12742         expect=$(echo $2 | tr -d A-Z)
12743
12744         expect_lo=$(($expect * 98 / 100)) # 2% below
12745         expect_hi=$(($expect * 102 / 100)) # 2% above
12746
12747         # permit 2% drift above and below
12748         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12749 }
12750
12751 test_104c() {
12752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12753         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12754
12755         local ost_param="osd-zfs.$FSNAME-OST0000."
12756         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12757         local ofacets=$(get_facets OST)
12758         local mfacets=$(get_facets MDS)
12759         local saved_ost_blocks=
12760         local saved_mdt_blocks=
12761
12762         echo "Before recordsize change"
12763         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12764         df=($(df -h | grep "$MOUNT"$))
12765
12766         # For checking.
12767         echo "lfs output : ${lfs_df[*]}"
12768         echo "df  output : ${df[*]}"
12769
12770         for facet in ${ofacets//,/ }; do
12771                 if [ -z $saved_ost_blocks ]; then
12772                         saved_ost_blocks=$(do_facet $facet \
12773                                 lctl get_param -n $ost_param.blocksize)
12774                         echo "OST Blocksize: $saved_ost_blocks"
12775                 fi
12776                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12777                 do_facet $facet zfs set recordsize=32768 $ost
12778         done
12779
12780         # BS too small. Sufficient for functional testing.
12781         for facet in ${mfacets//,/ }; do
12782                 if [ -z $saved_mdt_blocks ]; then
12783                         saved_mdt_blocks=$(do_facet $facet \
12784                                 lctl get_param -n $mdt_param.blocksize)
12785                         echo "MDT Blocksize: $saved_mdt_blocks"
12786                 fi
12787                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12788                 do_facet $facet zfs set recordsize=32768 $mdt
12789         done
12790
12791         # Give new values chance to reflect change
12792         sleep 2
12793
12794         echo "After recordsize change"
12795         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12796         df_after=($(df -h | grep "$MOUNT"$))
12797
12798         # For checking.
12799         echo "lfs output : ${lfs_df_after[*]}"
12800         echo "df  output : ${df_after[*]}"
12801
12802         # Verify lfs df
12803         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12804                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12805         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12806                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12807         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12808                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12809
12810         # Verify df
12811         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12812                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12813         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12814                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12815         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12816                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12817
12818         # Restore MDT recordize back to original
12819         for facet in ${mfacets//,/ }; do
12820                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12821                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12822         done
12823
12824         # Restore OST recordize back to original
12825         for facet in ${ofacets//,/ }; do
12826                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12827                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12828         done
12829
12830         return 0
12831 }
12832 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12833
12834 test_104d() {
12835         (( $RUNAS_ID != $UID )) ||
12836                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12837
12838         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12839                 skip "lustre version doesn't support lctl dl with non-root"
12840
12841         # debugfs only allows root users to access files, so the
12842         # previous move of the "devices" file to debugfs broke
12843         # "lctl dl" for non-root users. The LU-9680 Netlink
12844         # interface again allows non-root users to list devices.
12845         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12846                 error "lctl dl doesn't work for non root"
12847
12848         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12849         [ "$ost_count" -eq $OSTCOUNT ]  ||
12850                 error "lctl dl reports wrong number of OST devices"
12851
12852         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12853         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12854                 error "lctl dl reports wrong number of MDT devices"
12855 }
12856 run_test 104d "$RUNAS lctl dl test"
12857
12858 test_105a() {
12859         # doesn't work on 2.4 kernels
12860         touch $DIR/$tfile
12861         if $(flock_is_enabled); then
12862                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12863         else
12864                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12865         fi
12866         rm -f $DIR/$tfile
12867 }
12868 run_test 105a "flock when mounted without -o flock test ========"
12869
12870 test_105b() {
12871         touch $DIR/$tfile
12872         if $(flock_is_enabled); then
12873                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12874         else
12875                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12876         fi
12877         rm -f $DIR/$tfile
12878 }
12879 run_test 105b "fcntl when mounted without -o flock test ========"
12880
12881 test_105c() {
12882         touch $DIR/$tfile
12883         if $(flock_is_enabled); then
12884                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12885         else
12886                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12887         fi
12888         rm -f $DIR/$tfile
12889 }
12890 run_test 105c "lockf when mounted without -o flock test"
12891
12892 test_105d() { # bug 15924
12893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12894
12895         test_mkdir $DIR/$tdir
12896         flock_is_enabled || skip_env "mount w/o flock enabled"
12897         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12898         $LCTL set_param fail_loc=0x80000315
12899         flocks_test 2 $DIR/$tdir
12900 }
12901 run_test 105d "flock race (should not freeze) ========"
12902
12903 test_105e() { # bug 22660 && 22040
12904         flock_is_enabled || skip_env "mount w/o flock enabled"
12905
12906         touch $DIR/$tfile
12907         flocks_test 3 $DIR/$tfile
12908 }
12909 run_test 105e "Two conflicting flocks from same process"
12910
12911 test_106() { #bug 10921
12912         test_mkdir $DIR/$tdir
12913         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12914         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12915 }
12916 run_test 106 "attempt exec of dir followed by chown of that dir"
12917
12918 test_107() {
12919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12920
12921         CDIR=`pwd`
12922         local file=core
12923
12924         cd $DIR
12925         rm -f $file
12926
12927         local save_pattern=$(sysctl -n kernel.core_pattern)
12928         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12929         sysctl -w kernel.core_pattern=$file
12930         sysctl -w kernel.core_uses_pid=0
12931
12932         ulimit -c unlimited
12933         sleep 60 &
12934         SLEEPPID=$!
12935
12936         sleep 1
12937
12938         kill -s 11 $SLEEPPID
12939         wait $SLEEPPID
12940         if [ -e $file ]; then
12941                 size=`stat -c%s $file`
12942                 [ $size -eq 0 ] && error "Fail to create core file $file"
12943         else
12944                 error "Fail to create core file $file"
12945         fi
12946         rm -f $file
12947         sysctl -w kernel.core_pattern=$save_pattern
12948         sysctl -w kernel.core_uses_pid=$save_uses_pid
12949         cd $CDIR
12950 }
12951 run_test 107 "Coredump on SIG"
12952
12953 test_110() {
12954         test_mkdir $DIR/$tdir
12955         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12956         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12957                 error "mkdir with 256 char should fail, but did not"
12958         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12959                 error "create with 255 char failed"
12960         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12961                 error "create with 256 char should fail, but did not"
12962
12963         ls -l $DIR/$tdir
12964         rm -rf $DIR/$tdir
12965 }
12966 run_test 110 "filename length checking"
12967
12968 test_116a() { # was previously test_116()
12969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12970         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12971         remote_mds_nodsh && skip "remote MDS with nodsh"
12972
12973         echo -n "Free space priority "
12974         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12975                 head -n1
12976         declare -a AVAIL
12977         free_min_max
12978
12979         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12980         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12981         stack_trap simple_cleanup_common
12982
12983         # Check if we need to generate uneven OSTs
12984         test_mkdir -p $DIR/$tdir/OST${MINI}
12985         local FILL=$((MINV / 4))
12986         local DIFF=$((MAXV - MINV))
12987         local DIFF2=$((DIFF * 100 / MINV))
12988
12989         local threshold=$(do_facet $SINGLEMDS \
12990                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12991         threshold=${threshold%%%}
12992         echo -n "Check for uneven OSTs: "
12993         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12994
12995         if [[ $DIFF2 -gt $threshold ]]; then
12996                 echo "ok"
12997                 echo "Don't need to fill OST$MINI"
12998         else
12999                 # generate uneven OSTs. Write 2% over the QOS threshold value
13000                 echo "no"
13001                 DIFF=$((threshold - DIFF2 + 2))
13002                 DIFF2=$((MINV * DIFF / 100))
13003                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13004                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13005                         error "setstripe failed"
13006                 DIFF=$((DIFF2 / 2048))
13007                 i=0
13008                 while [ $i -lt $DIFF ]; do
13009                         i=$((i + 1))
13010                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13011                                 bs=2M count=1 2>/dev/null
13012                         echo -n .
13013                 done
13014                 echo .
13015                 sync
13016                 sleep_maxage
13017                 free_min_max
13018         fi
13019
13020         DIFF=$((MAXV - MINV))
13021         DIFF2=$((DIFF * 100 / MINV))
13022         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13023         if [ $DIFF2 -gt $threshold ]; then
13024                 echo "ok"
13025         else
13026                 skip "QOS imbalance criteria not met"
13027         fi
13028
13029         MINI1=$MINI
13030         MINV1=$MINV
13031         MAXI1=$MAXI
13032         MAXV1=$MAXV
13033
13034         # now fill using QOS
13035         $LFS setstripe -c 1 $DIR/$tdir
13036         FILL=$((FILL / 200))
13037         if [ $FILL -gt 600 ]; then
13038                 FILL=600
13039         fi
13040         echo "writing $FILL files to QOS-assigned OSTs"
13041         i=0
13042         while [ $i -lt $FILL ]; do
13043                 i=$((i + 1))
13044                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13045                         count=1 2>/dev/null
13046                 echo -n .
13047         done
13048         echo "wrote $i 200k files"
13049         sync
13050         sleep_maxage
13051
13052         echo "Note: free space may not be updated, so measurements might be off"
13053         free_min_max
13054         DIFF2=$((MAXV - MINV))
13055         echo "free space delta: orig $DIFF final $DIFF2"
13056         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13057         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13058         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13059         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13060         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13061         if [[ $DIFF -gt 0 ]]; then
13062                 FILL=$((DIFF2 * 100 / DIFF - 100))
13063                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13064         fi
13065
13066         # Figure out which files were written where
13067         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13068                awk '/'$MINI1': / {print $2; exit}')
13069         echo $UUID
13070         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13071         echo "$MINC files created on smaller OST $MINI1"
13072         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13073                awk '/'$MAXI1': / {print $2; exit}')
13074         echo $UUID
13075         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13076         echo "$MAXC files created on larger OST $MAXI1"
13077         if [[ $MINC -gt 0 ]]; then
13078                 FILL=$((MAXC * 100 / MINC - 100))
13079                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13080         fi
13081         [[ $MAXC -gt $MINC ]] ||
13082                 error_ignore LU-9 "stripe QOS didn't balance free space"
13083 }
13084 run_test 116a "stripe QOS: free space balance ==================="
13085
13086 test_116b() { # LU-2093
13087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13088         remote_mds_nodsh && skip "remote MDS with nodsh"
13089
13090 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13091         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13092                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13093         [ -z "$old_rr" ] && skip "no QOS"
13094         do_facet $SINGLEMDS lctl set_param \
13095                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13096         mkdir -p $DIR/$tdir
13097         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13098         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13099         do_facet $SINGLEMDS lctl set_param fail_loc=0
13100         rm -rf $DIR/$tdir
13101         do_facet $SINGLEMDS lctl set_param \
13102                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13103 }
13104 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13105
13106 test_117() # bug 10891
13107 {
13108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13109
13110         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13111         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13112         lctl set_param fail_loc=0x21e
13113         > $DIR/$tfile || error "truncate failed"
13114         lctl set_param fail_loc=0
13115         echo "Truncate succeeded."
13116         rm -f $DIR/$tfile
13117 }
13118 run_test 117 "verify osd extend =========="
13119
13120 NO_SLOW_RESENDCOUNT=4
13121 export OLD_RESENDCOUNT=""
13122 set_resend_count () {
13123         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13124         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13125         lctl set_param -n $PROC_RESENDCOUNT $1
13126         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13127 }
13128
13129 # for reduce test_118* time (b=14842)
13130 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13131
13132 # Reset async IO behavior after error case
13133 reset_async() {
13134         FILE=$DIR/reset_async
13135
13136         # Ensure all OSCs are cleared
13137         $LFS setstripe -c -1 $FILE
13138         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13139         sync
13140         rm $FILE
13141 }
13142
13143 test_118a() #bug 11710
13144 {
13145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13146
13147         reset_async
13148
13149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13150         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13151         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13152
13153         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13154                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13155                 return 1;
13156         fi
13157         rm -f $DIR/$tfile
13158 }
13159 run_test 118a "verify O_SYNC works =========="
13160
13161 test_118b()
13162 {
13163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13164         remote_ost_nodsh && skip "remote OST with nodsh"
13165
13166         reset_async
13167
13168         #define OBD_FAIL_SRV_ENOENT 0x217
13169         set_nodes_failloc "$(osts_nodes)" 0x217
13170         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13171         RC=$?
13172         set_nodes_failloc "$(osts_nodes)" 0
13173         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13174         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13175                     grep -c writeback)
13176
13177         if [[ $RC -eq 0 ]]; then
13178                 error "Must return error due to dropped pages, rc=$RC"
13179                 return 1;
13180         fi
13181
13182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13184                 return 1;
13185         fi
13186
13187         echo "Dirty pages not leaked on ENOENT"
13188
13189         # Due to the above error the OSC will issue all RPCs syncronously
13190         # until a subsequent RPC completes successfully without error.
13191         $MULTIOP $DIR/$tfile Ow4096yc
13192         rm -f $DIR/$tfile
13193
13194         return 0
13195 }
13196 run_test 118b "Reclaim dirty pages on fatal error =========="
13197
13198 test_118c()
13199 {
13200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13201
13202         # for 118c, restore the original resend count, LU-1940
13203         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13204                                 set_resend_count $OLD_RESENDCOUNT
13205         remote_ost_nodsh && skip "remote OST with nodsh"
13206
13207         reset_async
13208
13209         #define OBD_FAIL_OST_EROFS               0x216
13210         set_nodes_failloc "$(osts_nodes)" 0x216
13211
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         set_nodes_failloc "$(osts_nodes)" 0
13228         wait $MULTIPID
13229         RC=$?
13230         if [[ $RC -ne 0 ]]; then
13231                 error "Multiop fsync failed, rc=$RC"
13232         fi
13233
13234         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13235         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13236                     grep -c writeback)
13237         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13238                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13239         fi
13240
13241         rm -f $DIR/$tfile
13242         echo "Dirty pages flushed via fsync on EROFS"
13243         return 0
13244 }
13245 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13246
13247 # continue to use small resend count to reduce test_118* time (b=14842)
13248 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13249
13250 test_118d()
13251 {
13252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13253         remote_ost_nodsh && skip "remote OST with nodsh"
13254
13255         reset_async
13256
13257         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13258         set_nodes_failloc "$(osts_nodes)" 0x214
13259         # multiop should block due to fsync until pages are written
13260         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13261         MULTIPID=$!
13262         sleep 1
13263
13264         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13265                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13266         fi
13267
13268         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13269                     grep -c writeback)
13270         if [[ $WRITEBACK -eq 0 ]]; then
13271                 error "No page in writeback, writeback=$WRITEBACK"
13272         fi
13273
13274         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13275         set_nodes_failloc "$(osts_nodes)" 0
13276
13277         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13278         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13279                     grep -c writeback)
13280         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13281                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13282         fi
13283
13284         rm -f $DIR/$tfile
13285         echo "Dirty pages gaurenteed flushed via fsync"
13286         return 0
13287 }
13288 run_test 118d "Fsync validation inject a delay of the bulk =========="
13289
13290 test_118f() {
13291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13292
13293         reset_async
13294
13295         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13296         lctl set_param fail_loc=0x8000040a
13297
13298         # Should simulate EINVAL error which is fatal
13299         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13300         RC=$?
13301         if [[ $RC -eq 0 ]]; then
13302                 error "Must return error due to dropped pages, rc=$RC"
13303         fi
13304
13305         lctl set_param fail_loc=0x0
13306
13307         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13308         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13309         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13310                     grep -c writeback)
13311         if [[ $LOCKED -ne 0 ]]; then
13312                 error "Locked pages remain in cache, locked=$LOCKED"
13313         fi
13314
13315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13317         fi
13318
13319         rm -f $DIR/$tfile
13320         echo "No pages locked after fsync"
13321
13322         reset_async
13323         return 0
13324 }
13325 run_test 118f "Simulate unrecoverable OSC side error =========="
13326
13327 test_118g() {
13328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13329
13330         reset_async
13331
13332         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13333         lctl set_param fail_loc=0x406
13334
13335         # simulate local -ENOMEM
13336         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13337         RC=$?
13338
13339         lctl set_param fail_loc=0
13340         if [[ $RC -eq 0 ]]; then
13341                 error "Must return error due to dropped pages, rc=$RC"
13342         fi
13343
13344         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13345         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13346         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13347                         grep -c writeback)
13348         if [[ $LOCKED -ne 0 ]]; then
13349                 error "Locked pages remain in cache, locked=$LOCKED"
13350         fi
13351
13352         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13353                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13354         fi
13355
13356         rm -f $DIR/$tfile
13357         echo "No pages locked after fsync"
13358
13359         reset_async
13360         return 0
13361 }
13362 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13363
13364 test_118h() {
13365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13366         remote_ost_nodsh && skip "remote OST with nodsh"
13367
13368         reset_async
13369
13370         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13371         set_nodes_failloc "$(osts_nodes)" 0x20e
13372         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13373         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13374         RC=$?
13375
13376         set_nodes_failloc "$(osts_nodes)" 0
13377         if [[ $RC -eq 0 ]]; then
13378                 error "Must return error due to dropped pages, rc=$RC"
13379         fi
13380
13381         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13382         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13383         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13384                     grep -c writeback)
13385         if [[ $LOCKED -ne 0 ]]; then
13386                 error "Locked pages remain in cache, locked=$LOCKED"
13387         fi
13388
13389         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13390                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13391         fi
13392
13393         rm -f $DIR/$tfile
13394         echo "No pages locked after fsync"
13395
13396         return 0
13397 }
13398 run_test 118h "Verify timeout in handling recoverables errors  =========="
13399
13400 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13401
13402 test_118i() {
13403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13404         remote_ost_nodsh && skip "remote OST with nodsh"
13405
13406         reset_async
13407
13408         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13409         set_nodes_failloc "$(osts_nodes)" 0x20e
13410
13411         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13412         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13413         PID=$!
13414         sleep 5
13415         set_nodes_failloc "$(osts_nodes)" 0
13416
13417         wait $PID
13418         RC=$?
13419         if [[ $RC -ne 0 ]]; then
13420                 error "got error, but should be not, rc=$RC"
13421         fi
13422
13423         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13424         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13425         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13426         if [[ $LOCKED -ne 0 ]]; then
13427                 error "Locked pages remain in cache, locked=$LOCKED"
13428         fi
13429
13430         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13431                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13432         fi
13433
13434         rm -f $DIR/$tfile
13435         echo "No pages locked after fsync"
13436
13437         return 0
13438 }
13439 run_test 118i "Fix error before timeout in recoverable error  =========="
13440
13441 [ "$SLOW" = "no" ] && set_resend_count 4
13442
13443 test_118j() {
13444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13445         remote_ost_nodsh && skip "remote OST with nodsh"
13446
13447         reset_async
13448
13449         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13450         set_nodes_failloc "$(osts_nodes)" 0x220
13451
13452         # return -EIO from OST
13453         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13454         RC=$?
13455         set_nodes_failloc "$(osts_nodes)" 0x0
13456         if [[ $RC -eq 0 ]]; then
13457                 error "Must return error due to dropped pages, rc=$RC"
13458         fi
13459
13460         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13461         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13462         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13463         if [[ $LOCKED -ne 0 ]]; then
13464                 error "Locked pages remain in cache, locked=$LOCKED"
13465         fi
13466
13467         # in recoverable error on OST we want resend and stay until it finished
13468         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13469                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13470         fi
13471
13472         rm -f $DIR/$tfile
13473         echo "No pages locked after fsync"
13474
13475         return 0
13476 }
13477 run_test 118j "Simulate unrecoverable OST side error =========="
13478
13479 test_118k()
13480 {
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482         remote_ost_nodsh && skip "remote OSTs with nodsh"
13483
13484         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13485         set_nodes_failloc "$(osts_nodes)" 0x20e
13486         test_mkdir $DIR/$tdir
13487
13488         for ((i=0;i<10;i++)); do
13489                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13490                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13491                 SLEEPPID=$!
13492                 sleep 0.500s
13493                 kill $SLEEPPID
13494                 wait $SLEEPPID
13495         done
13496
13497         set_nodes_failloc "$(osts_nodes)" 0
13498         rm -rf $DIR/$tdir
13499 }
13500 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13501
13502 test_118l() # LU-646
13503 {
13504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13505
13506         test_mkdir $DIR/$tdir
13507         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13508         rm -rf $DIR/$tdir
13509 }
13510 run_test 118l "fsync dir"
13511
13512 test_118m() # LU-3066
13513 {
13514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13515
13516         test_mkdir $DIR/$tdir
13517         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13518         rm -rf $DIR/$tdir
13519 }
13520 run_test 118m "fdatasync dir ========="
13521
13522 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13523
13524 test_118n()
13525 {
13526         local begin
13527         local end
13528
13529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13530         remote_ost_nodsh && skip "remote OSTs with nodsh"
13531
13532         # Sleep to avoid a cached response.
13533         #define OBD_STATFS_CACHE_SECONDS 1
13534         sleep 2
13535
13536         # Inject a 10 second delay in the OST_STATFS handler.
13537         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13538         set_nodes_failloc "$(osts_nodes)" 0x242
13539
13540         begin=$SECONDS
13541         stat --file-system $MOUNT > /dev/null
13542         end=$SECONDS
13543
13544         set_nodes_failloc "$(osts_nodes)" 0
13545
13546         if ((end - begin > 20)); then
13547             error "statfs took $((end - begin)) seconds, expected 10"
13548         fi
13549 }
13550 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13551
13552 test_119a() # bug 11737
13553 {
13554         BSIZE=$((512 * 1024))
13555         directio write $DIR/$tfile 0 1 $BSIZE
13556         # We ask to read two blocks, which is more than a file size.
13557         # directio will indicate an error when requested and actual
13558         # sizes aren't equeal (a normal situation in this case) and
13559         # print actual read amount.
13560         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13561         if [ "$NOB" != "$BSIZE" ]; then
13562                 error "read $NOB bytes instead of $BSIZE"
13563         fi
13564         rm -f $DIR/$tfile
13565 }
13566 run_test 119a "Short directIO read must return actual read amount"
13567
13568 test_119b() # bug 11737
13569 {
13570         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13571
13572         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13573         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13574         sync
13575         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13576                 error "direct read failed"
13577         rm -f $DIR/$tfile
13578 }
13579 run_test 119b "Sparse directIO read must return actual read amount"
13580
13581 test_119c() # bug 13099
13582 {
13583         BSIZE=1048576
13584         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13585         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13586         rm -f $DIR/$tfile
13587 }
13588 run_test 119c "Testing for direct read hitting hole"
13589
13590 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13591 # Maloo test history
13592
13593 test_119e()
13594 {
13595         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13596                 skip "Need server version at least 2.15.58"
13597         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13598
13599         local stripe_size=$((1024 * 1024)) #1 MiB
13600         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13601         local file_size=$((25 * stripe_size))
13602         local bsizes
13603
13604         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13605         stack_trap "rm -f $DIR/$tfile*"
13606
13607         # Just a bit bigger than the largest size in the test set below
13608         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13609                 error "buffered i/o to create file failed"
13610
13611         # trivial test of unaligned DIO
13612         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13613                 iflag=direct oflag=direct ||
13614                 error "trivial unaligned dio failed"
13615
13616         # Test of disabling unaligned DIO support
13617         $LCTL set_param llite.*.unaligned_dio=0
13618         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13619         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13620         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13621                 iflag=direct oflag=direct &&
13622                 error "unaligned dio succeeded when disabled"
13623         $LCTL set_param llite.*.unaligned_dio=1
13624
13625         # Clean up before next part of test
13626         rm -f $DIR/$tfile.2
13627
13628         if zfs_or_rotational; then
13629                 # DIO on ZFS can take up to 2 seconds per IO
13630                 # rotational is better, but still slow.
13631                 # Limit testing on those media to larger sizes
13632                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13633                         $((stripe_size + 1024))"
13634         else
13635                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13636                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13637                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13638                         $((stripe_size - 1)) $stripe_size \
13639                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13640                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13641         fi
13642
13643         for bs in $bsizes; do
13644                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13645                 echo "Read/write with DIO at size $bs"
13646                 # Read and write with DIO from source to dest
13647                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13648                         iflag=direct oflag=direct ||
13649                         error "dio failed"
13650
13651                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13652                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13653                         error "size incorrect, file copy read/write bsize: $bs"
13654                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13655                         error "files differ, bsize $bs"
13656                 rm -f $DIR/$tfile.2
13657         done
13658 }
13659 run_test 119e "Basic tests of dio read and write at various sizes"
13660
13661 test_119f()
13662 {
13663         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13664
13665         local stripe_size=$((1024 * 1024)) #1 MiB
13666         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13667         local file_size=$((25 * stripe_size))
13668         local bsizes
13669
13670         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13671         stack_trap "rm -f $DIR/$tfile*"
13672
13673         # Just a bit bigger than the largest size in the test set below
13674         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13675                 error "buffered i/o to create file failed"
13676
13677         if zfs_or_rotational; then
13678                 # DIO on ZFS can take up to 2 seconds per IO
13679                 # rotational is better, but still slow.
13680                 # Limit testing on those media to larger sizes
13681                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13682                         $((stripe_size + 1024))"
13683         else
13684                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13685                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13686                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13687                         $((stripe_size - 1)) $stripe_size \
13688                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13689                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13690         fi
13691
13692         for bs in $bsizes; do
13693                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13694                 # Read and write with DIO from source to dest in two
13695                 # threads - should give correct copy of file
13696
13697                 echo "bs: $bs"
13698                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13699                         oflag=direct conv=notrunc &
13700                 pid_dio1=$!
13701                 # Note block size is different here for a more interesting race
13702                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13703                         iflag=direct oflag=direct conv=notrunc &
13704                 pid_dio2=$!
13705                 wait $pid_dio1
13706                 rc1=$?
13707                 wait $pid_dio2
13708                 rc2=$?
13709                 if (( rc1 != 0 )); then
13710                         error "dio copy 1 w/bsize $bs failed: $rc1"
13711                 fi
13712                 if (( rc2 != 0 )); then
13713                         error "dio copy 2 w/bsize $bs failed: $rc2"
13714                 fi
13715
13716
13717                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13718                         error "size incorrect, file copy read/write bsize: $bs"
13719                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13720                         error "files differ, bsize $bs"
13721                 rm -f $DIR/$tfile.2
13722         done
13723 }
13724 run_test 119f "dio vs dio race"
13725
13726 test_119g()
13727 {
13728         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13729
13730         local stripe_size=$((1024 * 1024)) #1 MiB
13731         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13732         local file_size=$((25 * stripe_size))
13733         local bsizes
13734
13735         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13736         stack_trap "rm -f $DIR/$tfile*"
13737
13738         # Just a bit bigger than the largest size in the test set below
13739         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13740                 error "buffered i/o to create file failed"
13741
13742         if zfs_or_rotational; then
13743                 # DIO on ZFS can take up to 2 seconds per IO
13744                 # rotational is better, but still slow.
13745                 # Limit testing on those media to larger sizes
13746                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13747                         $((stripe_size + 1024))"
13748         else
13749                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13750                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13751                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13752                         $((stripe_size - 1)) $stripe_size \
13753                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13754                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13755         fi
13756
13757         for bs in $bsizes; do
13758                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13759                 echo "bs: $bs"
13760                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13761                         oflag=direct conv=notrunc &
13762                 pid_dio1=$!
13763                 # Buffered I/O with similar but not the same block size
13764                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13765                 pid_bio2=$!
13766                 wait $pid_dio1
13767                 rc1=$?
13768                 wait $pid_bio2
13769                 rc2=$?
13770                 if (( rc1 != 0 )); then
13771                         error "dio copy 1 w/bsize $bs failed: $rc1"
13772                 fi
13773                 if (( rc2 != 0 )); then
13774                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13775                 fi
13776
13777                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13778                         error "size incorrect"
13779                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13780                         error "files differ, bsize $bs"
13781                 rm -f $DIR/$tfile.2
13782         done
13783 }
13784 run_test 119g "dio vs buffered I/O race"
13785
13786 test_119h()
13787 {
13788         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13789
13790         local stripe_size=$((1024 * 1024)) #1 MiB
13791         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13792         local file_size=$((25 * stripe_size))
13793         local bsizes
13794
13795         stack_trap "rm -f $DIR/$tfile.*"
13796
13797         if zfs_or_rotational; then
13798                 # DIO on ZFS can take up to 2 seconds per IO
13799                 # rotational is better, but still slow.
13800                 # Limit testing on those media to larger sizes
13801                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13802                         $((stripe_size + 1024))"
13803         else
13804                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13805                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13806                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13807                         $((stripe_size - 1)) $stripe_size \
13808                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13809                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13810         fi
13811
13812         for bs in $bsizes; do
13813                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13814                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13815                 echo "unaligned writes of blocksize: $bs"
13816                 # Write a file with unaligned DIO and regular DIO, and compare
13817                 # them
13818                 # with 'u', multiop randomly unaligns the io from the buffer
13819                 $MULTIOP $DIR/$tfile.1 \
13820                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13821                         error "multiop memory unaligned write failed, $bs"
13822                 $MULTIOP $DIR/$tfile.2 \
13823                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13824                         error "multiop memory aligned write failed, $bs"
13825
13826                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13827                         error "files differ, bsize $bs"
13828                 rm -f $DIR/$tfile.*
13829         done
13830
13831         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13832         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13833                 error "dd to create source file for read failed"
13834
13835         # Just a few quick tests to make sure unaligned DIO reads don't crash
13836         for bs in $bsizes; do
13837
13838                 echo "unaligned reads of blocksize: $bs"
13839                 # with 'u', multiop randomly unaligns the io from the buffer
13840                 $MULTIOP $DIR/$tfile.1 \
13841                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13842                         error "multiop memory unaligned read failed, $bs"
13843
13844         done
13845         rm -f $DIR/$tfile*
13846 }
13847 run_test 119h "basic tests of memory unaligned dio"
13848
13849 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13850 test_119i()
13851 {
13852         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13853         which aiocp || skip_env "no aiocp installed"
13854
13855         local stripe_size=$((1024 * 1024)) #1 MiB
13856         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13857         local file_size=$((25 * stripe_size))
13858         local bsizes
13859
13860         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13861         stack_trap "rm -f $DIR/$tfile.*"
13862
13863         # Just a bit bigger than the largest size in the test set below
13864         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13865                 error "buffered i/o to create file failed"
13866
13867         if zfs_or_rotational; then
13868                 # DIO on ZFS can take up to 2 seconds per IO
13869                 # rotational is better, but still slow.
13870                 # Limit testing on those media to larger sizes
13871                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13872                         $((stripe_size + 1024))"
13873         else
13874                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13875                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13876                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13877                         $((stripe_size - 1)) $stripe_size \
13878                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13879                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13880         fi
13881
13882         # Do page aligned and NOT page aligned AIO
13883         for align in 8 512 $((PAGE_SIZE)); do
13884         # Deliberately includes a few aligned sizes
13885         for bs in $bsizes; do
13886                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13887
13888                 echo "bs: $bs, align: $align, file_size $file_size"
13889                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13890                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13891                         error "unaligned aio failed, bs: $bs, align: $align"
13892
13893                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13894                         error "size incorrect"
13895                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13896                         error "files differ"
13897                 rm -f $DIR/$tfile.2
13898         done
13899         done
13900 }
13901 run_test 119i "test unaligned aio at varying sizes"
13902
13903 test_120a() {
13904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13905         remote_mds_nodsh && skip "remote MDS with nodsh"
13906         test_mkdir -i0 -c1 $DIR/$tdir
13907         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13908                 skip_env "no early lock cancel on server"
13909
13910         lru_resize_disable mdc
13911         lru_resize_disable osc
13912         cancel_lru_locks mdc
13913         # asynchronous object destroy at MDT could cause bl ast to client
13914         cancel_lru_locks osc
13915
13916         stat $DIR/$tdir > /dev/null
13917         can1=$(do_facet mds1 \
13918                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13919                awk '/ldlm_cancel/ {print $2}')
13920         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13921                awk '/ldlm_bl_callback/ {print $2}')
13922         test_mkdir -i0 -c1 $DIR/$tdir/d1
13923         can2=$(do_facet mds1 \
13924                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13925                awk '/ldlm_cancel/ {print $2}')
13926         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13927                awk '/ldlm_bl_callback/ {print $2}')
13928         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13929         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13930         lru_resize_enable mdc
13931         lru_resize_enable osc
13932 }
13933 run_test 120a "Early Lock Cancel: mkdir test"
13934
13935 test_120b() {
13936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13937         remote_mds_nodsh && skip "remote MDS with nodsh"
13938         test_mkdir $DIR/$tdir
13939         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13940                 skip_env "no early lock cancel on server"
13941
13942         lru_resize_disable mdc
13943         lru_resize_disable osc
13944         cancel_lru_locks mdc
13945         stat $DIR/$tdir > /dev/null
13946         can1=$(do_facet $SINGLEMDS \
13947                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13948                awk '/ldlm_cancel/ {print $2}')
13949         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13950                awk '/ldlm_bl_callback/ {print $2}')
13951         touch $DIR/$tdir/f1
13952         can2=$(do_facet $SINGLEMDS \
13953                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13954                awk '/ldlm_cancel/ {print $2}')
13955         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13956                awk '/ldlm_bl_callback/ {print $2}')
13957         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13958         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13959         lru_resize_enable mdc
13960         lru_resize_enable osc
13961 }
13962 run_test 120b "Early Lock Cancel: create test"
13963
13964 test_120c() {
13965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13966         remote_mds_nodsh && skip "remote MDS with nodsh"
13967         test_mkdir -i0 -c1 $DIR/$tdir
13968         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13969                 skip "no early lock cancel on server"
13970
13971         lru_resize_disable mdc
13972         lru_resize_disable osc
13973         test_mkdir -i0 -c1 $DIR/$tdir/d1
13974         test_mkdir -i0 -c1 $DIR/$tdir/d2
13975         touch $DIR/$tdir/d1/f1
13976         cancel_lru_locks mdc
13977         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13978         can1=$(do_facet mds1 \
13979                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13980                awk '/ldlm_cancel/ {print $2}')
13981         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13982                awk '/ldlm_bl_callback/ {print $2}')
13983         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13984         can2=$(do_facet mds1 \
13985                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13986                awk '/ldlm_cancel/ {print $2}')
13987         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13988                awk '/ldlm_bl_callback/ {print $2}')
13989         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13990         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13991         lru_resize_enable mdc
13992         lru_resize_enable osc
13993 }
13994 run_test 120c "Early Lock Cancel: link test"
13995
13996 test_120d() {
13997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13998         remote_mds_nodsh && skip "remote MDS with nodsh"
13999         test_mkdir -i0 -c1 $DIR/$tdir
14000         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14001                 skip_env "no early lock cancel on server"
14002
14003         lru_resize_disable mdc
14004         lru_resize_disable osc
14005         touch $DIR/$tdir
14006         cancel_lru_locks mdc
14007         stat $DIR/$tdir > /dev/null
14008         can1=$(do_facet mds1 \
14009                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14010                awk '/ldlm_cancel/ {print $2}')
14011         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14012                awk '/ldlm_bl_callback/ {print $2}')
14013         chmod a+x $DIR/$tdir
14014         can2=$(do_facet mds1 \
14015                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14016                awk '/ldlm_cancel/ {print $2}')
14017         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14018                awk '/ldlm_bl_callback/ {print $2}')
14019         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14020         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14021         lru_resize_enable mdc
14022         lru_resize_enable osc
14023 }
14024 run_test 120d "Early Lock Cancel: setattr test"
14025
14026 test_120e() {
14027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14028         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14029                 skip_env "no early lock cancel on server"
14030         remote_mds_nodsh && skip "remote MDS with nodsh"
14031
14032         local dlmtrace_set=false
14033
14034         test_mkdir -i0 -c1 $DIR/$tdir
14035         lru_resize_disable mdc
14036         lru_resize_disable osc
14037         ! $LCTL get_param debug | grep -q dlmtrace &&
14038                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14039         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14040         cancel_lru_locks mdc
14041         cancel_lru_locks osc
14042         dd if=$DIR/$tdir/f1 of=/dev/null
14043         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14044         # XXX client can not do early lock cancel of OST lock
14045         # during unlink (LU-4206), so cancel osc lock now.
14046         sleep 2
14047         cancel_lru_locks osc
14048         can1=$(do_facet mds1 \
14049                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14050                awk '/ldlm_cancel/ {print $2}')
14051         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14052                awk '/ldlm_bl_callback/ {print $2}')
14053         unlink $DIR/$tdir/f1
14054         sleep 5
14055         can2=$(do_facet mds1 \
14056                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14057                awk '/ldlm_cancel/ {print $2}')
14058         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14059                awk '/ldlm_bl_callback/ {print $2}')
14060         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14061                 $LCTL dk $TMP/cancel.debug.txt
14062         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14063                 $LCTL dk $TMP/blocking.debug.txt
14064         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14065         lru_resize_enable mdc
14066         lru_resize_enable osc
14067 }
14068 run_test 120e "Early Lock Cancel: unlink test"
14069
14070 test_120f() {
14071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14072         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14073                 skip_env "no early lock cancel on server"
14074         remote_mds_nodsh && skip "remote MDS with nodsh"
14075
14076         test_mkdir -i0 -c1 $DIR/$tdir
14077         lru_resize_disable mdc
14078         lru_resize_disable osc
14079         test_mkdir -i0 -c1 $DIR/$tdir/d1
14080         test_mkdir -i0 -c1 $DIR/$tdir/d2
14081         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14082         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14083         cancel_lru_locks mdc
14084         cancel_lru_locks osc
14085         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14086         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14087         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14088         # XXX client can not do early lock cancel of OST lock
14089         # during rename (LU-4206), so cancel osc lock now.
14090         sleep 2
14091         cancel_lru_locks osc
14092         can1=$(do_facet mds1 \
14093                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14094                awk '/ldlm_cancel/ {print $2}')
14095         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14096                awk '/ldlm_bl_callback/ {print $2}')
14097         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14098         sleep 5
14099         can2=$(do_facet mds1 \
14100                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14101                awk '/ldlm_cancel/ {print $2}')
14102         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14103                awk '/ldlm_bl_callback/ {print $2}')
14104         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14105         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14106         lru_resize_enable mdc
14107         lru_resize_enable osc
14108 }
14109 run_test 120f "Early Lock Cancel: rename test"
14110
14111 test_120g() {
14112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14113         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14114                 skip_env "no early lock cancel on server"
14115         remote_mds_nodsh && skip "remote MDS with nodsh"
14116
14117         lru_resize_disable mdc
14118         lru_resize_disable osc
14119         count=10000
14120         echo create $count files
14121         test_mkdir $DIR/$tdir
14122         cancel_lru_locks mdc
14123         cancel_lru_locks osc
14124         t0=$(date +%s)
14125
14126         can0=$(do_facet $SINGLEMDS \
14127                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14128                awk '/ldlm_cancel/ {print $2}')
14129         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14130                awk '/ldlm_bl_callback/ {print $2}')
14131         createmany -o $DIR/$tdir/f $count
14132         sync
14133         can1=$(do_facet $SINGLEMDS \
14134                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14135                awk '/ldlm_cancel/ {print $2}')
14136         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14137                awk '/ldlm_bl_callback/ {print $2}')
14138         t1=$(date +%s)
14139         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14140         echo rm $count files
14141         rm -r $DIR/$tdir
14142         sync
14143         can2=$(do_facet $SINGLEMDS \
14144                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14145                awk '/ldlm_cancel/ {print $2}')
14146         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14147                awk '/ldlm_bl_callback/ {print $2}')
14148         t2=$(date +%s)
14149         echo total: $count removes in $((t2-t1))
14150         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14151         sleep 2
14152         # wait for commitment of removal
14153         lru_resize_enable mdc
14154         lru_resize_enable osc
14155 }
14156 run_test 120g "Early Lock Cancel: performance test"
14157
14158 test_121() { #bug #10589
14159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14160
14161         rm -rf $DIR/$tfile
14162         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14163 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14164         lctl set_param fail_loc=0x310
14165         cancel_lru_locks osc > /dev/null
14166         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14167         lctl set_param fail_loc=0
14168         [[ $reads -eq $writes ]] ||
14169                 error "read $reads blocks, must be $writes blocks"
14170 }
14171 run_test 121 "read cancel race ========="
14172
14173 test_123a_base() { # was test 123, statahead(bug 11401)
14174         local lsx="$1"
14175
14176         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14177
14178         SLOWOK=0
14179         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14180                 log "testing UP system. Performance may be lower than expected."
14181                 SLOWOK=1
14182         fi
14183         running_in_vm && SLOWOK=1
14184
14185         $LCTL set_param mdc.*.batch_stats=0
14186
14187         rm -rf $DIR/$tdir
14188         test_mkdir $DIR/$tdir
14189         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14190         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14191         MULT=10
14192         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14193                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14194
14195                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14196                 lctl set_param -n llite.*.statahead_max 0
14197                 lctl get_param llite.*.statahead_max
14198                 cancel_lru_locks mdc
14199                 cancel_lru_locks osc
14200                 stime=$(date +%s)
14201                 time $lsx $DIR/$tdir | wc -l
14202                 etime=$(date +%s)
14203                 delta=$((etime - stime))
14204                 log "$lsx $i files without statahead: $delta sec"
14205                 lctl set_param llite.*.statahead_max=$max
14206
14207                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14208                          awk '/statahead.wrong:/ { print $NF }')
14209                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14210                 cancel_lru_locks mdc
14211                 cancel_lru_locks osc
14212                 stime=$(date +%s)
14213                 time $lsx $DIR/$tdir | wc -l
14214                 etime=$(date +%s)
14215                 delta_sa=$((etime - stime))
14216                 log "$lsx $i files with statahead: $delta_sa sec"
14217                 lctl get_param -n llite.*.statahead_stats
14218                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14219                          awk '/statahead.wrong:/ { print $NF }')
14220
14221                 [[ $swrong -lt $ewrong ]] &&
14222                         log "statahead was stopped, maybe too many locks held!"
14223                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14224
14225                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14226                         max=$(lctl get_param -n llite.*.statahead_max |
14227                                 head -n 1)
14228                         lctl set_param -n llite.*.statahead_max 0
14229                         lctl get_param llite.*.statahead_max
14230                         cancel_lru_locks mdc
14231                         cancel_lru_locks osc
14232                         stime=$(date +%s)
14233                         time $lsx $DIR/$tdir | wc -l
14234                         etime=$(date +%s)
14235                         delta=$((etime - stime))
14236                         log "$lsx $i files again without statahead: $delta sec"
14237                         lctl set_param llite.*.statahead_max=$max
14238                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14239                                 if [ $SLOWOK -eq 0 ]; then
14240                                         error "$lsx $i files is slower with statahead!"
14241                                 else
14242                                         log "$lsx $i files is slower with statahead!"
14243                                 fi
14244                                 break
14245                         fi
14246                 fi
14247
14248                 [ $delta -gt 20 ] && break
14249                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14250                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14251         done
14252         log "$lsx done"
14253
14254         stime=$(date +%s)
14255         rm -r $DIR/$tdir
14256         sync
14257         etime=$(date +%s)
14258         delta=$((etime - stime))
14259         log "rm -r $DIR/$tdir/: $delta seconds"
14260         log "rm done"
14261         lctl get_param -n llite.*.statahead_stats
14262         $LCTL get_param mdc.*.batch_stats
14263 }
14264
14265 test_123aa() {
14266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14267
14268         test_123a_base "ls -l"
14269 }
14270 run_test 123aa "verify statahead work"
14271
14272 test_123ab() {
14273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14274
14275         statx_supported || skip_env "Test must be statx() syscall supported"
14276
14277         test_123a_base "$STATX -l"
14278 }
14279 run_test 123ab "verify statahead work by using statx"
14280
14281 test_123ac() {
14282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14283
14284         statx_supported || skip_env "Test must be statx() syscall supported"
14285
14286         local rpcs_before
14287         local rpcs_after
14288         local agl_before
14289         local agl_after
14290
14291         cancel_lru_locks $OSC
14292         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14293         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14294                      awk '/agl.total:/ { print $NF }')
14295         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14296         test_123a_base "$STATX --cached=always -D"
14297         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14298                     awk '/agl.total:/ { print $NF }')
14299         [ $agl_before -eq $agl_after ] ||
14300                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14301         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14302         [ $rpcs_after -eq $rpcs_before ] ||
14303                 error "$STATX should not send glimpse RPCs to $OSC"
14304 }
14305 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14306
14307 test_batch_statahead() {
14308         local max=$1
14309         local batch_max=$2
14310         local num=10000
14311         local batch_rpcs
14312         local unbatch_rpcs
14313         local hit_total
14314
14315         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14316         $LCTL set_param mdc.*.batch_stats=0
14317         $LCTL set_param llite.*.statahead_max=$max
14318         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14319         # Verify that batched statahead is faster than one without statahead
14320         test_123a_base "ls -l"
14321
14322         stack_trap "rm -rf $DIR/$tdir" EXIT
14323         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14324         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14325
14326         # unbatched statahead
14327         $LCTL set_param llite.*.statahead_batch_max=0
14328         $LCTL set_param llite.*.statahead_stats=clear
14329         $LCTL set_param mdc.*.stats=clear
14330         cancel_lru_locks mdc
14331         cancel_lru_locks osc
14332         time ls -l $DIR/$tdir | wc -l
14333         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14334         wait_update_facet client "pgrep ll_sa" "" 35 ||
14335                 error "ll_sa thread is still running"
14336         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14337                     awk '/hit.total:/ { print $NF }')
14338         # hit ratio should be larger than 75% (7500).
14339         (( $hit_total > 7500 )) ||
14340                 error "unbatched statahead hit count ($hit_total) is too low"
14341
14342         # batched statahead
14343         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14344         $LCTL set_param llite.*.statahead_stats=clear
14345         $LCTL set_param mdc.*.batch_stats=clear
14346         $LCTL set_param mdc.*.stats=clear
14347         cancel_lru_locks mdc
14348         cancel_lru_locks osc
14349         time ls -l $DIR/$tdir | wc -l
14350         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14351         # wait for statahead thread to quit and update statahead stats
14352         wait_update_facet client "pgrep ll_sa" "" 35 ||
14353                 error "ll_sa thread is still running"
14354         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14355                     awk '/hit.total:/ { print $NF }')
14356         # hit ratio should be larger than 75% (7500).
14357         (( $hit_total > 7500 )) ||
14358                 error "batched statahead hit count ($hit_total) is too low"
14359
14360         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14361         (( $unbatch_rpcs > $batch_rpcs )) ||
14362                 error "batched statahead does not reduce RPC count"
14363         $LCTL get_param mdc.*.batch_stats
14364 }
14365
14366 test_123ad() {
14367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14368
14369         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14370                 skip "Need server version at least 2.15.53"
14371
14372         local max
14373         local batch_max
14374
14375         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14376         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14377
14378         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14379         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14380
14381         test_batch_statahead 32 32
14382         test_batch_statahead 2048 256
14383 }
14384 run_test 123ad "Verify batching statahead works correctly"
14385
14386 test_123b () { # statahead(bug 15027)
14387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14388
14389         test_mkdir $DIR/$tdir
14390         createmany -o $DIR/$tdir/$tfile-%d 1000
14391
14392         cancel_lru_locks mdc
14393         cancel_lru_locks osc
14394
14395 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14396         lctl set_param fail_loc=0x80000803
14397         ls -lR $DIR/$tdir > /dev/null
14398         log "ls done"
14399         lctl set_param fail_loc=0x0
14400         lctl get_param -n llite.*.statahead_stats
14401         rm -r $DIR/$tdir
14402         sync
14403
14404 }
14405 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14406
14407 test_123c() {
14408         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14409
14410         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14411         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14412         touch $DIR/$tdir.1/{1..3}
14413         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14414
14415         remount_client $MOUNT
14416
14417         $MULTIOP $DIR/$tdir.0 Q
14418
14419         # let statahead to complete
14420         ls -l $DIR/$tdir.0 > /dev/null
14421
14422         testid=$(echo $TESTNAME | tr '_' ' ')
14423         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14424                 error "statahead warning" || true
14425 }
14426 run_test 123c "Can not initialize inode warning on DNE statahead"
14427
14428 test_123d() {
14429         local num=100
14430         local swrong
14431         local ewrong
14432
14433         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14434         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14435                 error "setdirstripe $DIR/$tdir failed"
14436         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14437         remount_client $MOUNT
14438         $LCTL get_param llite.*.statahead_max
14439         $LCTL set_param llite.*.statahead_stats=0 ||
14440                 error "clear statahead_stats failed"
14441         swrong=$(lctl get_param -n llite.*.statahead_stats |
14442                  awk '/statahead.wrong:/ { print $NF }')
14443         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14444         # wait for statahead thread finished to update hit/miss stats.
14445         sleep 1
14446         $LCTL get_param -n llite.*.statahead_stats
14447         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14448                  awk '/statahead.wrong:/ { print $NF }')
14449         (( $swrong == $ewrong )) ||
14450                 log "statahead was stopped, maybe too many locks held!"
14451 }
14452 run_test 123d "Statahead on striped directories works correctly"
14453
14454 test_123e() {
14455         local max
14456         local batch_max
14457         local dir=$DIR/$tdir
14458
14459         mkdir $dir || error "mkdir $dir failed"
14460         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14461         stack_trap "rm -rf $dir"
14462
14463         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14464
14465         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14466         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14467         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14468         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14469
14470         $LCTL set_param llite.*.statahead_max=2048
14471         $LCTL set_param llite.*.statahead_batch_max=1024
14472
14473         ls -l $dir
14474         $LCTL get_param mdc.*.batch_stats
14475         $LCTL get_param llite.*.statahead_*
14476 }
14477 run_test 123e "statahead with large wide striping"
14478
14479 test_123f() {
14480         local max
14481         local batch_max
14482         local dir=$DIR/$tdir
14483
14484         mkdir $dir || error "mkdir $dir failed"
14485         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14486         stack_trap "rm -rf $dir"
14487
14488         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14489
14490         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14491         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14492
14493         $LCTL set_param llite.*.statahead_max=64
14494         $LCTL set_param llite.*.statahead_batch_max=64
14495
14496         ls -l $dir
14497         lctl get_param mdc.*.batch_stats
14498         lctl get_param llite.*.statahead_*
14499
14500         $LCTL set_param llite.*.statahead_max=$max
14501         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14502 }
14503 run_test 123f "Retry mechanism with large wide striping files"
14504
14505 test_123g() {
14506         local dir=$DIR/$tdir
14507         local num=1000
14508
14509         mkdir $dir || error "failed to mkdir $dir"
14510         createmany -o $dir/$tfile $num || error "failed creatmany files"
14511         cancel_lru_locks mdc
14512         cancel_lru_locks osc
14513
14514         $LCTL set_param llite.*.statahead_stats=clear
14515         $LCTL set_param mdc.*.batch_stats=clear
14516         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14517                 error "aheadmany $dir with $tfile failed"
14518         wait_update_facet client "pgrep ll_sa" "" 35 ||
14519                 error "ll_sa thread is still running"
14520         $LCTL get_param -n llite.*.statahead_stats
14521         $LCTL get_param -n mdc.*.batch_stats
14522
14523         local count
14524
14525         count=$($LCTL get_param -n llite.*.statahead_stats |
14526                 awk '/hit.total:/ {print $2}')
14527         echo "Hit total: $count"
14528         # Hit ratio should be >= 75%
14529         (( $count > num * 75 / 100)) ||
14530                 error "hit total $count is be > 75% of $num"
14531 }
14532 run_test 123g "Test for stat-ahead advise"
14533
14534 test_124a() {
14535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14536         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14537                 skip_env "no lru resize on server"
14538
14539         local NR=2000
14540
14541         test_mkdir $DIR/$tdir
14542
14543         log "create $NR files at $DIR/$tdir"
14544         createmany -o $DIR/$tdir/f $NR ||
14545                 error "failed to create $NR files in $DIR/$tdir"
14546
14547         cancel_lru_locks mdc
14548         ls -l $DIR/$tdir > /dev/null
14549
14550         local NSDIR=""
14551         local LRU_SIZE=0
14552         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14553                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14554                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14555                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14556                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14557                         log "NSDIR=$NSDIR"
14558                         log "NS=$(basename $NSDIR)"
14559                         break
14560                 fi
14561         done
14562
14563         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14564                 skip "Not enough cached locks created!"
14565         fi
14566         log "LRU=$LRU_SIZE"
14567
14568         local SLEEP=30
14569
14570         # We know that lru resize allows one client to hold $LIMIT locks
14571         # for 10h. After that locks begin to be killed by client.
14572         local MAX_HRS=10
14573         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14574         log "LIMIT=$LIMIT"
14575         if [ $LIMIT -lt $LRU_SIZE ]; then
14576                 skip "Limit is too small $LIMIT"
14577         fi
14578
14579         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14580         # killing locks. Some time was spent for creating locks. This means
14581         # that up to the moment of sleep finish we must have killed some of
14582         # them (10-100 locks). This depends on how fast ther were created.
14583         # Many of them were touched in almost the same moment and thus will
14584         # be killed in groups.
14585         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14586
14587         # Use $LRU_SIZE_B here to take into account real number of locks
14588         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14589         local LRU_SIZE_B=$LRU_SIZE
14590         log "LVF=$LVF"
14591         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14592         log "OLD_LVF=$OLD_LVF"
14593         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14594
14595         # Let's make sure that we really have some margin. Client checks
14596         # cached locks every 10 sec.
14597         SLEEP=$((SLEEP+20))
14598         log "Sleep ${SLEEP} sec"
14599         local SEC=0
14600         while ((SEC<$SLEEP)); do
14601                 echo -n "..."
14602                 sleep 5
14603                 SEC=$((SEC+5))
14604                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14605                 echo -n "$LRU_SIZE"
14606         done
14607         echo ""
14608         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14609         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14610
14611         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14612                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14613                 unlinkmany $DIR/$tdir/f $NR
14614                 return
14615         }
14616
14617         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14618         log "unlink $NR files at $DIR/$tdir"
14619         unlinkmany $DIR/$tdir/f $NR
14620 }
14621 run_test 124a "lru resize ======================================="
14622
14623 get_max_pool_limit()
14624 {
14625         local limit=$($LCTL get_param \
14626                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14627         local max=0
14628         for l in $limit; do
14629                 if [[ $l -gt $max ]]; then
14630                         max=$l
14631                 fi
14632         done
14633         echo $max
14634 }
14635
14636 test_124b() {
14637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14638         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14639                 skip_env "no lru resize on server"
14640
14641         LIMIT=$(get_max_pool_limit)
14642
14643         NR=$(($(default_lru_size)*20))
14644         if [[ $NR -gt $LIMIT ]]; then
14645                 log "Limit lock number by $LIMIT locks"
14646                 NR=$LIMIT
14647         fi
14648
14649         IFree=$(mdsrate_inodes_available)
14650         if [ $IFree -lt $NR ]; then
14651                 log "Limit lock number by $IFree inodes"
14652                 NR=$IFree
14653         fi
14654
14655         lru_resize_disable mdc
14656         test_mkdir -p $DIR/$tdir/disable_lru_resize
14657
14658         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14659         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14660         cancel_lru_locks mdc
14661         stime=`date +%s`
14662         PID=""
14663         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14664         PID="$PID $!"
14665         sleep 2
14666         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14667         PID="$PID $!"
14668         sleep 2
14669         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14670         PID="$PID $!"
14671         wait $PID
14672         etime=`date +%s`
14673         nolruresize_delta=$((etime-stime))
14674         log "ls -la time: $nolruresize_delta seconds"
14675         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14676         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14677
14678         lru_resize_enable mdc
14679         test_mkdir -p $DIR/$tdir/enable_lru_resize
14680
14681         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14682         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14683         cancel_lru_locks mdc
14684         stime=`date +%s`
14685         PID=""
14686         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14687         PID="$PID $!"
14688         sleep 2
14689         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14690         PID="$PID $!"
14691         sleep 2
14692         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14693         PID="$PID $!"
14694         wait $PID
14695         etime=`date +%s`
14696         lruresize_delta=$((etime-stime))
14697         log "ls -la time: $lruresize_delta seconds"
14698         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14699
14700         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14701                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14702         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14703                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14704         else
14705                 log "lru resize performs the same with no lru resize"
14706         fi
14707         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14708 }
14709 run_test 124b "lru resize (performance test) ======================="
14710
14711 test_124c() {
14712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14713         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14714                 skip_env "no lru resize on server"
14715
14716         # cache ununsed locks on client
14717         local nr=100
14718         cancel_lru_locks mdc
14719         test_mkdir $DIR/$tdir
14720         createmany -o $DIR/$tdir/f $nr ||
14721                 error "failed to create $nr files in $DIR/$tdir"
14722         ls -l $DIR/$tdir > /dev/null
14723
14724         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14725         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14726         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14727         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14728         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14729
14730         # set lru_max_age to 1 sec
14731         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14732         echo "sleep $((recalc_p * 2)) seconds..."
14733         sleep $((recalc_p * 2))
14734
14735         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14736         # restore lru_max_age
14737         $LCTL set_param -n $nsdir.lru_max_age $max_age
14738         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14739         unlinkmany $DIR/$tdir/f $nr
14740 }
14741 run_test 124c "LRUR cancel very aged locks"
14742
14743 test_124d() {
14744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14745         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14746                 skip_env "no lru resize on server"
14747
14748         # cache ununsed locks on client
14749         local nr=100
14750
14751         lru_resize_disable mdc
14752         stack_trap "lru_resize_enable mdc" EXIT
14753
14754         cancel_lru_locks mdc
14755
14756         # asynchronous object destroy at MDT could cause bl ast to client
14757         test_mkdir $DIR/$tdir
14758         createmany -o $DIR/$tdir/f $nr ||
14759                 error "failed to create $nr files in $DIR/$tdir"
14760         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14761
14762         ls -l $DIR/$tdir > /dev/null
14763
14764         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14765         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14766         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14767         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14768
14769         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14770
14771         # set lru_max_age to 1 sec
14772         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14773         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14774
14775         echo "sleep $((recalc_p * 2)) seconds..."
14776         sleep $((recalc_p * 2))
14777
14778         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14779
14780         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14781 }
14782 run_test 124d "cancel very aged locks if lru-resize disabled"
14783
14784 test_125() { # 13358
14785         $LCTL get_param -n llite.*.client_type | grep -q local ||
14786                 skip "must run as local client"
14787         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14788                 skip_env "must have acl enabled"
14789         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14790         id $USER0 || skip_env "missing user $USER0"
14791
14792         test_mkdir $DIR/$tdir
14793         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14794         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14795                 error "setfacl $DIR/$tdir failed"
14796         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14797 }
14798 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14799
14800 test_126() { # bug 12829/13455
14801         $GSS && skip_env "must run as gss disabled"
14802         $LCTL get_param -n llite.*.client_type | grep -q local ||
14803                 skip "must run as local client"
14804         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14805
14806         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14807         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14808         rm -f $DIR/$tfile
14809         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14810 }
14811 run_test 126 "check that the fsgid provided by the client is taken into account"
14812
14813 test_127a() { # bug 15521
14814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14815         local name count samp unit min max sum sumsq
14816         local tmpfile=$TMP/$tfile.tmp
14817
14818         # enable stats header if it is disabled
14819         $LCTL set_param enable_stats_header=1
14820
14821         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14822         echo "stats before reset"
14823         stack_trap "rm -f $tmpfile"
14824         local now=$(date +%s)
14825
14826         $LCTL get_param osc.*.stats | tee $tmpfile
14827
14828         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14829         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14830         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14831         local uptime=$(awk '{ print $1 }' /proc/uptime)
14832
14833         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14834         (( ${snapshot_time%\.*} >= $now - 5 &&
14835            ${snapshot_time%\.*} <= $now + 5 )) ||
14836                 error "snapshot_time=$snapshot_time != now=$now"
14837         # elapsed _should_ be from mount, but at least less than uptime
14838         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14839                 error "elapsed=$elapsed > uptime=$uptime"
14840         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14841            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14842                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14843
14844         $LCTL set_param osc.*.stats=0
14845         local reset=$(date +%s)
14846         local fsize=$((2048 * 1024))
14847
14848         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14849         cancel_lru_locks osc
14850         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14851
14852         now=$(date +%s)
14853         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14854         while read name count samp unit min max sum sumsq; do
14855                 [[ "$samp" == "samples" ]] || continue
14856
14857                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14858                 [ ! $min ] && error "Missing min value for $name proc entry"
14859                 eval $name=$count || error "Wrong proc format"
14860
14861                 case $name in
14862                 read_bytes|write_bytes)
14863                         [[ "$unit" =~ "bytes" ]] ||
14864                                 error "unit is not 'bytes': $unit"
14865                         (( $min >= 4096 )) || error "min is too small: $min"
14866                         (( $min <= $fsize )) || error "min is too big: $min"
14867                         (( $max >= 4096 )) || error "max is too small: $max"
14868                         (( $max <= $fsize )) || error "max is too big: $max"
14869                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14870                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14871                                 error "sumsquare is too small: $sumsq"
14872                         (( $sumsq <= $fsize * $fsize )) ||
14873                                 error "sumsquare is too big: $sumsq"
14874                         ;;
14875                 ost_read|ost_write)
14876                         [[ "$unit" =~ "usec" ]] ||
14877                                 error "unit is not 'usec': $unit"
14878                         ;;
14879                 *)      ;;
14880                 esac
14881         done < $tmpfile
14882
14883         #check that we actually got some stats
14884         [ "$read_bytes" ] || error "Missing read_bytes stats"
14885         [ "$write_bytes" ] || error "Missing write_bytes stats"
14886         [ "$read_bytes" != 0 ] || error "no read done"
14887         [ "$write_bytes" != 0 ] || error "no write done"
14888
14889         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14890         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14891         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14892
14893         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14894         (( ${snapshot_time%\.*} >= $now - 5 &&
14895            ${snapshot_time%\.*} <= $now + 5 )) ||
14896                 error "reset snapshot_time=$snapshot_time != now=$now"
14897         # elapsed should be from time of stats reset
14898         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14899            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14900                 error "reset elapsed=$elapsed > $now - $reset"
14901         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14902            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14903                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14904 }
14905 run_test 127a "verify the client stats are sane"
14906
14907 test_127b() { # bug LU-333
14908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14909         local name count samp unit min max sum sumsq
14910
14911         echo "stats before reset"
14912         $LCTL get_param llite.*.stats
14913         $LCTL set_param llite.*.stats=0
14914
14915         # perform 2 reads and writes so MAX is different from SUM.
14916         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14917         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14918         cancel_lru_locks osc
14919         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14920         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14921
14922         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14923         stack_trap "rm -f $TMP/$tfile.tmp"
14924         while read name count samp unit min max sum sumsq; do
14925                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14926                 eval $name=$count || error "Wrong proc format"
14927
14928                 case $name in
14929                 read_bytes|write_bytes)
14930                         [[ "$unit" =~ "bytes" ]] ||
14931                                 error "unit is not 'bytes': $unit"
14932                         (( $count == 2 )) || error "count is not 2: $count"
14933                         (( $min == $PAGE_SIZE )) ||
14934                                 error "min is not $PAGE_SIZE: $min"
14935                         (( $max == $PAGE_SIZE )) ||
14936                                 error "max is not $PAGE_SIZE: $max"
14937                         (( $sum == $PAGE_SIZE * 2 )) ||
14938                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14939                         ;;
14940                 read|write)
14941                         [[ "$unit" =~ "usec" ]] ||
14942                                 error "unit is not 'usec': $unit"
14943                         ;;
14944                 *)      ;;
14945                 esac
14946         done < $TMP/$tfile.tmp
14947
14948         #check that we actually got some stats
14949         [ "$read_bytes" ] || error "Missing read_bytes stats"
14950         [ "$write_bytes" ] || error "Missing write_bytes stats"
14951         [ "$read_bytes" != 0 ] || error "no read done"
14952         [ "$write_bytes" != 0 ] || error "no write done"
14953 }
14954 run_test 127b "verify the llite client stats are sane"
14955
14956 test_127c() { # LU-12394
14957         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14958         local size
14959         local bsize
14960         local reads
14961         local writes
14962         local count
14963
14964         $LCTL set_param llite.*.extents_stats=1
14965         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14966
14967         # Use two stripes so there is enough space in default config
14968         $LFS setstripe -c 2 $DIR/$tfile
14969
14970         # Extent stats start at 0-4K and go in power of two buckets
14971         # LL_HIST_START = 12 --> 2^12 = 4K
14972         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14973         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14974         # small configs
14975         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14976                 do
14977                 # Write and read, 2x each, second time at a non-zero offset
14978                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14979                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14980                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14981                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14982                 rm -f $DIR/$tfile
14983         done
14984
14985         $LCTL get_param llite.*.extents_stats
14986
14987         count=2
14988         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14989                 do
14990                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14991                                 grep -m 1 $bsize)
14992                 reads=$(echo $bucket | awk '{print $5}')
14993                 writes=$(echo $bucket | awk '{print $9}')
14994                 [ "$reads" -eq $count ] ||
14995                         error "$reads reads in < $bsize bucket, expect $count"
14996                 [ "$writes" -eq $count ] ||
14997                         error "$writes writes in < $bsize bucket, expect $count"
14998         done
14999
15000         # Test mmap write and read
15001         $LCTL set_param llite.*.extents_stats=c
15002         size=512
15003         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15004         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15005         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15006
15007         $LCTL get_param llite.*.extents_stats
15008
15009         count=$(((size*1024) / PAGE_SIZE))
15010
15011         bsize=$((2 * PAGE_SIZE / 1024))K
15012
15013         bucket=$($LCTL get_param -n llite.*.extents_stats |
15014                         grep -m 1 $bsize)
15015         reads=$(echo $bucket | awk '{print $5}')
15016         writes=$(echo $bucket | awk '{print $9}')
15017         # mmap writes fault in the page first, creating an additonal read
15018         [ "$reads" -eq $((2 * count)) ] ||
15019                 error "$reads reads in < $bsize bucket, expect $count"
15020         [ "$writes" -eq $count ] ||
15021                 error "$writes writes in < $bsize bucket, expect $count"
15022 }
15023 run_test 127c "test llite extent stats with regular & mmap i/o"
15024
15025 test_128() { # bug 15212
15026         touch $DIR/$tfile
15027         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15028                 find $DIR/$tfile
15029                 find $DIR/$tfile
15030         EOF
15031
15032         result=$(grep error $TMP/$tfile.log)
15033         rm -f $DIR/$tfile $TMP/$tfile.log
15034         [ -z "$result" ] ||
15035                 error "consecutive find's under interactive lfs failed"
15036 }
15037 run_test 128 "interactive lfs for 2 consecutive find's"
15038
15039 set_dir_limits () {
15040         local mntdev
15041         local canondev
15042         local node
15043
15044         local ldproc=/proc/fs/ldiskfs
15045         local facets=$(get_facets MDS)
15046
15047         for facet in ${facets//,/ }; do
15048                 canondev=$(ldiskfs_canon \
15049                            *.$(convert_facet2label $facet).mntdev $facet)
15050                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15051                         ldproc=/sys/fs/ldiskfs
15052                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15053                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15054         done
15055 }
15056
15057 check_mds_dmesg() {
15058         local facets=$(get_facets MDS)
15059         for facet in ${facets//,/ }; do
15060                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15061         done
15062         return 1
15063 }
15064
15065 test_129() {
15066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15067         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15068                 skip "Need MDS version with at least 2.5.56"
15069         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15070                 skip_env "ldiskfs only test"
15071         fi
15072         remote_mds_nodsh && skip "remote MDS with nodsh"
15073
15074         local ENOSPC=28
15075         local has_warning=false
15076
15077         rm -rf $DIR/$tdir
15078         mkdir -p $DIR/$tdir
15079
15080         # block size of mds1
15081         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15082         set_dir_limits $maxsize $((maxsize * 6 / 8))
15083         stack_trap "set_dir_limits 0 0"
15084         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15085         local dirsize=$(stat -c%s "$DIR/$tdir")
15086         local nfiles=0
15087         while (( $dirsize <= $maxsize )); do
15088                 $MCREATE $DIR/$tdir/file_base_$nfiles
15089                 rc=$?
15090                 # check two errors:
15091                 # ENOSPC for ext4 max_dir_size, which has been used since
15092                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15093                 if (( rc == ENOSPC )); then
15094                         set_dir_limits 0 0
15095                         echo "rc=$rc returned as expected after $nfiles files"
15096
15097                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15098                                 error "create failed w/o dir size limit"
15099
15100                         # messages may be rate limited if test is run repeatedly
15101                         check_mds_dmesg '"is approaching max"' ||
15102                                 echo "warning message should be output"
15103                         check_mds_dmesg '"has reached max"' ||
15104                                 echo "reached message should be output"
15105
15106                         dirsize=$(stat -c%s "$DIR/$tdir")
15107
15108                         [[ $dirsize -ge $maxsize ]] && return 0
15109                         error "dirsize $dirsize < $maxsize after $nfiles files"
15110                 elif (( rc != 0 )); then
15111                         break
15112                 fi
15113                 nfiles=$((nfiles + 1))
15114                 dirsize=$(stat -c%s "$DIR/$tdir")
15115         done
15116
15117         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15118 }
15119 run_test 129 "test directory size limit ========================"
15120
15121 OLDIFS="$IFS"
15122 cleanup_130() {
15123         trap 0
15124         IFS="$OLDIFS"
15125         rm -f $DIR/$tfile
15126 }
15127
15128 test_130a() {
15129         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15130         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15131
15132         trap cleanup_130 EXIT RETURN
15133
15134         local fm_file=$DIR/$tfile
15135         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15136         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15137                 error "dd failed for $fm_file"
15138
15139         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15140         filefrag -ves $fm_file
15141         local rc=$?
15142         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15143                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15144         (( $rc == 0 )) || error "filefrag $fm_file failed"
15145
15146         filefrag_op=$(filefrag -ve -k $fm_file |
15147                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15148         local lun=$($LFS getstripe -i $fm_file)
15149
15150         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15151         IFS=$'\n'
15152         local tot_len=0
15153         for line in $filefrag_op; do
15154                 local frag_lun=$(echo $line | cut -d: -f5)
15155                 local ext_len=$(echo $line | cut -d: -f4)
15156
15157                 if (( $frag_lun != $lun )); then
15158                         error "FIEMAP on 1-stripe file($fm_file) failed"
15159                         return
15160                 fi
15161                 (( tot_len += ext_len ))
15162         done
15163
15164         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15165                 error "FIEMAP on 1-stripe file($fm_file) failed"
15166                 return
15167         fi
15168
15169         echo "FIEMAP on single striped file succeeded"
15170 }
15171 run_test 130a "FIEMAP (1-stripe file)"
15172
15173 test_130b() {
15174         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15175
15176         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15177         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15178         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15179                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15180
15181         trap cleanup_130 EXIT RETURN
15182
15183         local fm_file=$DIR/$tfile
15184         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15185                 error "setstripe on $fm_file"
15186
15187         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15188                 error "dd failed on $fm_file"
15189
15190         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15191         filefrag_op=$(filefrag -ve -k $fm_file |
15192                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15193
15194         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15195                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15196
15197         IFS=$'\n'
15198         local tot_len=0
15199         local num_luns=1
15200
15201         for line in $filefrag_op; do
15202                 local frag_lun=$(echo $line | cut -d: -f5 |
15203                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15204                 local ext_len=$(echo $line | cut -d: -f4)
15205                 if (( $frag_lun != $last_lun )); then
15206                         if (( tot_len != 1024 )); then
15207                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15208                                 return
15209                         else
15210                                 (( num_luns += 1 ))
15211                                 tot_len=0
15212                         fi
15213                 fi
15214                 (( tot_len += ext_len ))
15215                 last_lun=$frag_lun
15216         done
15217         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15218                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15219                 return
15220         fi
15221
15222         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15223 }
15224 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15225
15226 test_130c() {
15227         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15228
15229         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15230         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15231         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15232                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15233
15234         trap cleanup_130 EXIT RETURN
15235
15236         local fm_file=$DIR/$tfile
15237         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15238
15239         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15240                 error "dd failed on $fm_file"
15241
15242         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15243         filefrag_op=$(filefrag -ve -k $fm_file |
15244                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15245
15246         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15247                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15248
15249         IFS=$'\n'
15250         local tot_len=0
15251         local num_luns=1
15252         for line in $filefrag_op; do
15253                 local frag_lun=$(echo $line | cut -d: -f5 |
15254                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15255                 local ext_len=$(echo $line | cut -d: -f4)
15256                 if (( $frag_lun != $last_lun )); then
15257                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15258                         if (( logical != 512 )); then
15259                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15260                                 return
15261                         fi
15262                         if (( tot_len != 512 )); then
15263                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15264                                 return
15265                         else
15266                                 (( num_luns += 1 ))
15267                                 tot_len=0
15268                         fi
15269                 fi
15270                 (( tot_len += ext_len ))
15271                 last_lun=$frag_lun
15272         done
15273         if (( num_luns != 2 || tot_len != 512 )); then
15274                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15275                 return
15276         fi
15277
15278         echo "FIEMAP on 2-stripe file with hole succeeded"
15279 }
15280 run_test 130c "FIEMAP (2-stripe file with hole)"
15281
15282 test_130d() {
15283         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15284
15285         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15286         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15287         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15288                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15289
15290         trap cleanup_130 EXIT RETURN
15291
15292         local fm_file=$DIR/$tfile
15293         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15294                         error "setstripe on $fm_file"
15295
15296         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15297         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15298                 error "dd failed on $fm_file"
15299
15300         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15301         filefrag_op=$(filefrag -ve -k $fm_file |
15302                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15303
15304         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15305                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15306
15307         IFS=$'\n'
15308         local tot_len=0
15309         local num_luns=1
15310         for line in $filefrag_op; do
15311                 local frag_lun=$(echo $line | cut -d: -f5 |
15312                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15313                 local ext_len=$(echo $line | cut -d: -f4)
15314                 if (( $frag_lun != $last_lun )); then
15315                         if (( tot_len != 1024 )); then
15316                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15317                                 return
15318                         else
15319                                 (( num_luns += 1 ))
15320                                 local tot_len=0
15321                         fi
15322                 fi
15323                 (( tot_len += ext_len ))
15324                 last_lun=$frag_lun
15325         done
15326         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15327                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15328                 return
15329         fi
15330
15331         echo "FIEMAP on N-stripe file succeeded"
15332 }
15333 run_test 130d "FIEMAP (N-stripe file)"
15334
15335 test_130e() {
15336         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15337
15338         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15339         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15340         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15341                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15342
15343         trap cleanup_130 EXIT RETURN
15344
15345         local fm_file=$DIR/$tfile
15346         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15347         stack_trap "rm -f $fm_file"
15348
15349         local num_blks=512
15350         local expected_len=$(( (num_blks / 2) * 64 ))
15351         for ((i = 0; i < $num_blks; i++)); do
15352                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15353                         conv=notrunc > /dev/null 2>&1
15354         done
15355
15356         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15357         filefrag_op=$(filefrag -ve -k $fm_file |
15358                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15359
15360         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15361
15362         IFS=$'\n'
15363         local tot_len=0
15364         local num_luns=1
15365         for line in $filefrag_op; do
15366                 local frag_lun=$(echo $line | cut -d: -f5)
15367                 local ext_len=$(echo $line | cut -d: -f4)
15368                 if (( $frag_lun != $last_lun )); then
15369                         if (( tot_len != $expected_len )); then
15370                                 error "OST$last_lun $tot_len != $expected_len"
15371                         else
15372                                 (( num_luns += 1 ))
15373                                 tot_len=0
15374                         fi
15375                 fi
15376                 (( tot_len += ext_len ))
15377                 last_lun=$frag_lun
15378         done
15379         if (( num_luns != 2 || tot_len != $expected_len )); then
15380                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15381         fi
15382
15383         echo "FIEMAP with continuation calls succeeded"
15384 }
15385 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15386
15387 test_130f() {
15388         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15389         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15390         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15391                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15392
15393         local fm_file=$DIR/$tfile
15394         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15395                 error "multiop create with lov_delay_create on $fm_file"
15396
15397         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15398         filefrag_extents=$(filefrag -vek $fm_file |
15399                            awk '/extents? found/ { print $2 }')
15400         if (( $filefrag_extents != 0 )); then
15401                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15402         fi
15403
15404         rm -f $fm_file
15405 }
15406 run_test 130f "FIEMAP (unstriped file)"
15407
15408 test_130g() {
15409         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15410                 skip "Need MDS version with at least 2.12.53 for overstriping"
15411         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15412         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15413         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15414                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15415
15416         local file=$DIR/$tfile
15417         local nr=$((OSTCOUNT * 100))
15418
15419         $LFS setstripe -C $nr -S1M $file ||
15420                 error "failed to setstripe -C $nr $file"
15421
15422         stack_trap "rm -f $file"
15423         dd if=/dev/zero of=$file count=$nr bs=1M
15424         sync
15425         nr=$($LFS getstripe -c $file)
15426
15427         local extents=$(filefrag -v $file |
15428                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15429
15430         echo "filefrag list $extents extents in file with stripecount $nr"
15431         if (( extents < nr )); then
15432                 $LFS getstripe $file
15433                 filefrag -v $file
15434                 error "filefrag printed $extents < $nr extents"
15435         fi
15436 }
15437 run_test 130g "FIEMAP (overstripe file)"
15438
15439 # Test for writev/readv
15440 test_131a() {
15441         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15442                 error "writev test failed"
15443         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15444                 error "readv failed"
15445         rm -f $DIR/$tfile
15446 }
15447 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15448
15449 test_131b() {
15450         local fsize=$((524288 + 1048576 + 1572864))
15451         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15452                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15453                         error "append writev test failed"
15454
15455         ((fsize += 1572864 + 1048576))
15456         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15457                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15458                         error "append writev test failed"
15459         rm -f $DIR/$tfile
15460 }
15461 run_test 131b "test append writev"
15462
15463 test_131c() {
15464         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15465         error "NOT PASS"
15466 }
15467 run_test 131c "test read/write on file w/o objects"
15468
15469 test_131d() {
15470         rwv -f $DIR/$tfile -w -n 1 1572864
15471         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15472         if [ "$NOB" != 1572864 ]; then
15473                 error "Short read filed: read $NOB bytes instead of 1572864"
15474         fi
15475         rm -f $DIR/$tfile
15476 }
15477 run_test 131d "test short read"
15478
15479 test_131e() {
15480         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15481         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15482         error "read hitting hole failed"
15483         rm -f $DIR/$tfile
15484 }
15485 run_test 131e "test read hitting hole"
15486
15487 check_stats() {
15488         local facet=$1
15489         local op=$2
15490         local want=${3:-0}
15491         local res
15492
15493         # open             11 samples [usecs] 468 4793 13658 35791898
15494         case $facet in
15495         mds*) res=($(do_facet $facet \
15496                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15497                  ;;
15498         ost*) res=($(do_facet $facet \
15499                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15500                  ;;
15501         *) error "Wrong facet '$facet'" ;;
15502         esac
15503         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15504         # if $want is zero, it means any stat increment is ok.
15505         if (( $want > 0 )); then
15506                 local count=${res[1]}
15507
15508                 if (( $count != $want )); then
15509                         if [[ $facet =~ "mds" ]]; then
15510                                 do_nodes $(comma_list $(mdts_nodes)) \
15511                                         $LCTL get_param mdt.*.md_stats
15512                         else
15513                                 do_nodes $(comma_list $(osts-nodes)) \
15514                                         $LCTL get_param obdfilter.*.stats
15515                         fi
15516                         error "The $op counter on $facet is $count, not $want"
15517                 fi
15518         fi
15519 }
15520
15521 test_133a() {
15522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15523         remote_ost_nodsh && skip "remote OST with nodsh"
15524         remote_mds_nodsh && skip "remote MDS with nodsh"
15525         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15526                 skip_env "MDS doesn't support rename stats"
15527
15528         local testdir=$DIR/${tdir}/stats_testdir
15529
15530         mkdir -p $DIR/${tdir}
15531
15532         # clear stats.
15533         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15534         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15535
15536         # verify mdt stats first.
15537         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15538         check_stats $SINGLEMDS "mkdir" 1
15539
15540         # clear "open" from "lfs mkdir" above
15541         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15542         touch ${testdir}/${tfile} || error "touch failed"
15543         check_stats $SINGLEMDS "open" 1
15544         check_stats $SINGLEMDS "close" 1
15545         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15546                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15547                 check_stats $SINGLEMDS "mknod" 2
15548         }
15549         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15550         check_stats $SINGLEMDS "unlink" 1
15551         rm -f ${testdir}/${tfile} || error "file remove failed"
15552         check_stats $SINGLEMDS "unlink" 2
15553
15554         # remove working dir and check mdt stats again.
15555         rmdir ${testdir} || error "rmdir failed"
15556         check_stats $SINGLEMDS "rmdir" 1
15557
15558         local testdir1=$DIR/${tdir}/stats_testdir1
15559         mkdir_on_mdt0 -p ${testdir}
15560         mkdir_on_mdt0 -p ${testdir1}
15561         touch ${testdir1}/test1
15562         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15563         check_stats $SINGLEMDS "crossdir_rename" 1
15564
15565         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15566         check_stats $SINGLEMDS "samedir_rename" 1
15567
15568         rm -rf $DIR/${tdir}
15569 }
15570 run_test 133a "Verifying MDT stats ========================================"
15571
15572 test_133b() {
15573         local res
15574
15575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15576         remote_ost_nodsh && skip "remote OST with nodsh"
15577         remote_mds_nodsh && skip "remote MDS with nodsh"
15578
15579         local testdir=$DIR/${tdir}/stats_testdir
15580
15581         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15582         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15583         touch ${testdir}/${tfile} || error "touch failed"
15584         cancel_lru_locks mdc
15585
15586         # clear stats.
15587         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15588         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15589
15590         # extra mdt stats verification.
15591         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15592         check_stats $SINGLEMDS "setattr" 1
15593         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15594         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15595         then            # LU-1740
15596                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15597                 check_stats $SINGLEMDS "getattr" 1
15598         fi
15599         rm -rf $DIR/${tdir}
15600
15601         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15602         # so the check below is not reliable
15603         [ $MDSCOUNT -eq 1 ] || return 0
15604
15605         # Sleep to avoid a cached response.
15606         #define OBD_STATFS_CACHE_SECONDS 1
15607         sleep 2
15608         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15609         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15610         $LFS df || error "lfs failed"
15611         check_stats $SINGLEMDS "statfs" 1
15612
15613         # check aggregated statfs (LU-10018)
15614         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15615                 return 0
15616         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15617                 return 0
15618         sleep 2
15619         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15620         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15621         df $DIR
15622         check_stats $SINGLEMDS "statfs" 1
15623
15624         # We want to check that the client didn't send OST_STATFS to
15625         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15626         # extra care is needed here.
15627         if remote_mds; then
15628                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15629                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15630
15631                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15632                 [ "$res" ] && error "OST got STATFS"
15633         fi
15634
15635         return 0
15636 }
15637 run_test 133b "Verifying extra MDT stats =================================="
15638
15639 test_133c() {
15640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15641         remote_ost_nodsh && skip "remote OST with nodsh"
15642         remote_mds_nodsh && skip "remote MDS with nodsh"
15643
15644         local testdir=$DIR/$tdir/stats_testdir
15645
15646         test_mkdir -p $testdir
15647
15648         # verify obdfilter stats.
15649         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15650         sync
15651         cancel_lru_locks osc
15652         wait_delete_completed
15653
15654         # clear stats.
15655         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15656         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15657
15658         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15659                 error "dd failed"
15660         sync
15661         cancel_lru_locks osc
15662         check_stats ost1 "write" 1
15663
15664         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15665         check_stats ost1 "read" 1
15666
15667         > $testdir/$tfile || error "truncate failed"
15668         check_stats ost1 "punch" 1
15669
15670         rm -f $testdir/$tfile || error "file remove failed"
15671         wait_delete_completed
15672         check_stats ost1 "destroy" 1
15673
15674         rm -rf $DIR/$tdir
15675 }
15676 run_test 133c "Verifying OST stats ========================================"
15677
15678 order_2() {
15679         local value=$1
15680         local orig=$value
15681         local order=1
15682
15683         while [ $value -ge 2 ]; do
15684                 order=$((order*2))
15685                 value=$((value/2))
15686         done
15687
15688         if [ $orig -gt $order ]; then
15689                 order=$((order*2))
15690         fi
15691         echo $order
15692 }
15693
15694 size_in_KMGT() {
15695     local value=$1
15696     local size=('K' 'M' 'G' 'T');
15697     local i=0
15698     local size_string=$value
15699
15700     while [ $value -ge 1024 ]; do
15701         if [ $i -gt 3 ]; then
15702             #T is the biggest unit we get here, if that is bigger,
15703             #just return XXXT
15704             size_string=${value}T
15705             break
15706         fi
15707         value=$((value >> 10))
15708         if [ $value -lt 1024 ]; then
15709             size_string=${value}${size[$i]}
15710             break
15711         fi
15712         i=$((i + 1))
15713     done
15714
15715     echo $size_string
15716 }
15717
15718 get_rename_size() {
15719         local size=$1
15720         local context=${2:-.}
15721         local sample=$(do_facet $SINGLEMDS $LCTL \
15722                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15723                 grep -A1 $context |
15724                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15725         echo $sample
15726 }
15727
15728 test_133d() {
15729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15730         remote_ost_nodsh && skip "remote OST with nodsh"
15731         remote_mds_nodsh && skip "remote MDS with nodsh"
15732         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15733                 skip_env "MDS doesn't support rename stats"
15734
15735         local testdir1=$DIR/${tdir}/stats_testdir1
15736         local testdir2=$DIR/${tdir}/stats_testdir2
15737         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15738
15739         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15740
15741         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15742         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15743
15744         createmany -o $testdir1/test 512 || error "createmany failed"
15745
15746         # check samedir rename size
15747         mv ${testdir1}/test0 ${testdir1}/test_0
15748
15749         local testdir1_size=$(ls -l $DIR/${tdir} |
15750                 awk '/stats_testdir1/ {print $5}')
15751         local testdir2_size=$(ls -l $DIR/${tdir} |
15752                 awk '/stats_testdir2/ {print $5}')
15753
15754         testdir1_size=$(order_2 $testdir1_size)
15755         testdir2_size=$(order_2 $testdir2_size)
15756
15757         testdir1_size=$(size_in_KMGT $testdir1_size)
15758         testdir2_size=$(size_in_KMGT $testdir2_size)
15759
15760         echo "source rename dir size: ${testdir1_size}"
15761         echo "target rename dir size: ${testdir2_size}"
15762
15763         local cmd="do_facet $SINGLEMDS $LCTL "
15764         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15765
15766         eval $cmd || error "$cmd failed"
15767         local samedir=$($cmd | grep 'same_dir')
15768         local same_sample=$(get_rename_size $testdir1_size)
15769         [ -z "$samedir" ] && error "samedir_rename_size count error"
15770         [[ $same_sample -eq 1 ]] ||
15771                 error "samedir_rename_size error $same_sample"
15772         echo "Check same dir rename stats success"
15773
15774         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15775
15776         # check crossdir rename size
15777         mv ${testdir1}/test_0 ${testdir2}/test_0
15778
15779         testdir1_size=$(ls -l $DIR/${tdir} |
15780                 awk '/stats_testdir1/ {print $5}')
15781         testdir2_size=$(ls -l $DIR/${tdir} |
15782                 awk '/stats_testdir2/ {print $5}')
15783
15784         testdir1_size=$(order_2 $testdir1_size)
15785         testdir2_size=$(order_2 $testdir2_size)
15786
15787         testdir1_size=$(size_in_KMGT $testdir1_size)
15788         testdir2_size=$(size_in_KMGT $testdir2_size)
15789
15790         echo "source rename dir size: ${testdir1_size}"
15791         echo "target rename dir size: ${testdir2_size}"
15792
15793         eval $cmd || error "$cmd failed"
15794         local crossdir=$($cmd | grep 'crossdir')
15795         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15796         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15797         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15798         [[ $src_sample -eq 1 ]] ||
15799                 error "crossdir_rename_size error $src_sample"
15800         [[ $tgt_sample -eq 1 ]] ||
15801                 error "crossdir_rename_size error $tgt_sample"
15802         echo "Check cross dir rename stats success"
15803         rm -rf $DIR/${tdir}
15804 }
15805 run_test 133d "Verifying rename_stats ========================================"
15806
15807 test_133e() {
15808         remote_mds_nodsh && skip "remote MDS with nodsh"
15809         remote_ost_nodsh && skip "remote OST with nodsh"
15810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15811
15812         local testdir=$DIR/${tdir}/stats_testdir
15813         local ctr f0 f1 bs=32768 count=42 sum
15814
15815         mkdir -p ${testdir} || error "mkdir failed"
15816
15817         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15818
15819         for ctr in {write,read}_bytes; do
15820                 sync
15821                 cancel_lru_locks osc
15822
15823                 do_facet ost1 $LCTL set_param -n \
15824                         "obdfilter.*.exports.clear=clear"
15825
15826                 if [ $ctr = write_bytes ]; then
15827                         f0=/dev/zero
15828                         f1=${testdir}/${tfile}
15829                 else
15830                         f0=${testdir}/${tfile}
15831                         f1=/dev/null
15832                 fi
15833
15834                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15835                         error "dd failed"
15836                 sync
15837                 cancel_lru_locks osc
15838
15839                 sum=$(do_facet ost1 $LCTL get_param \
15840                         "obdfilter.*.exports.*.stats" |
15841                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15842                                 $1 == ctr { sum += $7 }
15843                                 END { printf("%0.0f", sum) }')
15844
15845                 if ((sum != bs * count)); then
15846                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15847                 fi
15848         done
15849
15850         rm -rf $DIR/${tdir}
15851 }
15852 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15853
15854 test_133f() {
15855         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15856                 skip "too old lustre for get_param -R ($facet_ver)"
15857
15858         # verifying readability.
15859         $LCTL get_param -R '*' &> /dev/null
15860
15861         # Verifing writability with badarea_io.
15862         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15863         local skipped_params='force_lbug|changelog_mask|daemon_file'
15864         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15865                 egrep -v "$skipped_params" |
15866                 xargs -n 1 find $proc_dirs -name |
15867                 xargs -n 1 badarea_io ||
15868                 error "client badarea_io failed"
15869
15870         # remount the FS in case writes/reads /proc break the FS
15871         cleanup || error "failed to unmount"
15872         setup || error "failed to setup"
15873 }
15874 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15875
15876 test_133g() {
15877         remote_mds_nodsh && skip "remote MDS with nodsh"
15878         remote_ost_nodsh && skip "remote OST with nodsh"
15879
15880         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15881         local proc_dirs_str=$(eval echo $proc_dirs)
15882         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15883         local facet
15884         for facet in mds1 ost1; do
15885                 local facet_ver=$(lustre_version_code $facet)
15886                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15887                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15888                 else
15889                         log "$facet: too old lustre for get_param -R"
15890                 fi
15891                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15892                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15893                                 tr -d = | egrep -v $skipped_params |
15894                                 xargs -n 1 find $proc_dirs_str -name |
15895                                 xargs -n 1 badarea_io" ||
15896                                         error "$facet badarea_io failed"
15897                 else
15898                         skip_noexit "$facet: too old lustre for get_param -R"
15899                 fi
15900         done
15901
15902         # remount the FS in case writes/reads /proc break the FS
15903         cleanup || error "failed to unmount"
15904         setup || error "failed to setup"
15905 }
15906 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15907
15908 test_133h() {
15909         remote_mds_nodsh && skip "remote MDS with nodsh"
15910         remote_ost_nodsh && skip "remote OST with nodsh"
15911         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15912                 skip "Need MDS version at least 2.9.54"
15913
15914         local facet
15915         for facet in client mds1 ost1; do
15916                 # Get the list of files that are missing the terminating newline
15917                 local plist=$(do_facet $facet
15918                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15919                 local ent
15920                 for ent in $plist; do
15921                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15922                                 awk -v FS='\v' -v RS='\v\v' \
15923                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15924                                         print FILENAME}'" 2>/dev/null)
15925                         [ -z $missing ] || {
15926                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15927                                 error "file does not end with newline: $facet-$ent"
15928                         }
15929                 done
15930         done
15931 }
15932 run_test 133h "Proc files should end with newlines"
15933
15934 test_134a() {
15935         remote_mds_nodsh && skip "remote MDS with nodsh"
15936         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15937                 skip "Need MDS version at least 2.7.54"
15938
15939         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15940         cancel_lru_locks mdc
15941
15942         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15943         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15944         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15945
15946         local nr=1000
15947         createmany -o $DIR/$tdir/f $nr ||
15948                 error "failed to create $nr files in $DIR/$tdir"
15949         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15950
15951         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15952         do_facet mds1 $LCTL set_param fail_loc=0x327
15953         do_facet mds1 $LCTL set_param fail_val=500
15954         touch $DIR/$tdir/m
15955
15956         echo "sleep 10 seconds ..."
15957         sleep 10
15958         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15959
15960         do_facet mds1 $LCTL set_param fail_loc=0
15961         do_facet mds1 $LCTL set_param fail_val=0
15962         [ $lck_cnt -lt $unused ] ||
15963                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15964
15965         rm $DIR/$tdir/m
15966         unlinkmany $DIR/$tdir/f $nr
15967 }
15968 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15969
15970 test_134b() {
15971         remote_mds_nodsh && skip "remote MDS with nodsh"
15972         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15973                 skip "Need MDS version at least 2.7.54"
15974
15975         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15976         cancel_lru_locks mdc
15977
15978         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15979                         ldlm.lock_reclaim_threshold_mb)
15980         # disable reclaim temporarily
15981         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15982
15983         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15984         do_facet mds1 $LCTL set_param fail_loc=0x328
15985         do_facet mds1 $LCTL set_param fail_val=500
15986
15987         $LCTL set_param debug=+trace
15988
15989         local nr=600
15990         createmany -o $DIR/$tdir/f $nr &
15991         local create_pid=$!
15992
15993         echo "Sleep $TIMEOUT seconds ..."
15994         sleep $TIMEOUT
15995         if ! ps -p $create_pid  > /dev/null 2>&1; then
15996                 do_facet mds1 $LCTL set_param fail_loc=0
15997                 do_facet mds1 $LCTL set_param fail_val=0
15998                 do_facet mds1 $LCTL set_param \
15999                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16000                 error "createmany finished incorrectly!"
16001         fi
16002         do_facet mds1 $LCTL set_param fail_loc=0
16003         do_facet mds1 $LCTL set_param fail_val=0
16004         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16005         wait $create_pid || return 1
16006
16007         unlinkmany $DIR/$tdir/f $nr
16008 }
16009 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16010
16011 test_135() {
16012         remote_mds_nodsh && skip "remote MDS with nodsh"
16013         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16014                 skip "Need MDS version at least 2.13.50"
16015         local fname
16016
16017         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16018
16019 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16020         #set only one record at plain llog
16021         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16022
16023         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16024
16025         #fill already existed plain llog each 64767
16026         #wrapping whole catalog
16027         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16028
16029         createmany -o $DIR/$tdir/$tfile_ 64700
16030         for (( i = 0; i < 64700; i = i + 2 ))
16031         do
16032                 rm $DIR/$tdir/$tfile_$i &
16033                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16034                 local pid=$!
16035                 wait $pid
16036         done
16037
16038         #waiting osp synchronization
16039         wait_delete_completed
16040 }
16041 run_test 135 "Race catalog processing"
16042
16043 test_136() {
16044         remote_mds_nodsh && skip "remote MDS with nodsh"
16045         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16046                 skip "Need MDS version at least 2.13.50"
16047         local fname
16048
16049         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16050         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16051         #set only one record at plain llog
16052 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16053         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16054
16055         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16056
16057         #fill already existed 2 plain llogs each 64767
16058         #wrapping whole catalog
16059         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16060         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16061         wait_delete_completed
16062
16063         createmany -o $DIR/$tdir/$tfile_ 10
16064         sleep 25
16065
16066         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16067         for (( i = 0; i < 10; i = i + 3 ))
16068         do
16069                 rm $DIR/$tdir/$tfile_$i &
16070                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16071                 local pid=$!
16072                 wait $pid
16073                 sleep 7
16074                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16075         done
16076
16077         #waiting osp synchronization
16078         wait_delete_completed
16079 }
16080 run_test 136 "Race catalog processing 2"
16081
16082 test_140() { #bug-17379
16083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16084
16085         test_mkdir $DIR/$tdir
16086         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16087         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16088
16089         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16090         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16091         local i=0
16092         while i=$((i + 1)); do
16093                 test_mkdir $i
16094                 cd $i || error "Changing to $i"
16095                 ln -s ../stat stat || error "Creating stat symlink"
16096                 # Read the symlink until ELOOP present,
16097                 # not LBUGing the system is considered success,
16098                 # we didn't overrun the stack.
16099                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16100                 if [ $ret -ne 0 ]; then
16101                         if [ $ret -eq 40 ]; then
16102                                 break  # -ELOOP
16103                         else
16104                                 error "Open stat symlink"
16105                                         return
16106                         fi
16107                 fi
16108         done
16109         i=$((i - 1))
16110         echo "The symlink depth = $i"
16111         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16112                 error "Invalid symlink depth"
16113
16114         # Test recursive symlink
16115         ln -s symlink_self symlink_self
16116         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16117         echo "open symlink_self returns $ret"
16118         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16119 }
16120 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16121
16122 test_150a() {
16123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16124
16125         local TF="$TMP/$tfile"
16126
16127         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16128         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16129         cp $TF $DIR/$tfile
16130         cancel_lru_locks $OSC
16131         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16132         remount_client $MOUNT
16133         df -P $MOUNT
16134         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16135
16136         $TRUNCATE $TF 6000
16137         $TRUNCATE $DIR/$tfile 6000
16138         cancel_lru_locks $OSC
16139         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16140
16141         echo "12345" >>$TF
16142         echo "12345" >>$DIR/$tfile
16143         cancel_lru_locks $OSC
16144         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16145
16146         echo "12345" >>$TF
16147         echo "12345" >>$DIR/$tfile
16148         cancel_lru_locks $OSC
16149         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16150 }
16151 run_test 150a "truncate/append tests"
16152
16153 test_150b() {
16154         check_set_fallocate_or_skip
16155         local out
16156
16157         touch $DIR/$tfile
16158         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16159         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16160                 skip_eopnotsupp "$out|check_fallocate failed"
16161 }
16162 run_test 150b "Verify fallocate (prealloc) functionality"
16163
16164 test_150bb() {
16165         check_set_fallocate_or_skip
16166
16167         touch $DIR/$tfile
16168         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16169         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16170         > $DIR/$tfile
16171         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16172         # precomputed md5sum for 20MB of zeroes
16173         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16174         local sum=($(md5sum $DIR/$tfile))
16175
16176         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16177
16178         check_set_fallocate 1
16179
16180         > $DIR/$tfile
16181         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16182         sum=($(md5sum $DIR/$tfile))
16183
16184         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16185 }
16186 run_test 150bb "Verify fallocate modes both zero space"
16187
16188 test_150c() {
16189         check_set_fallocate_or_skip
16190         local striping="-c2"
16191
16192         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16193         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16194         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16195         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16196         local want=$((OSTCOUNT * 1048576))
16197
16198         # Must allocate all requested space, not more than 5% extra
16199         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16200                 error "bytes $bytes is not $want"
16201
16202         rm -f $DIR/$tfile
16203
16204         echo "verify fallocate on PFL file"
16205
16206         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16207
16208         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16209                 error "Create $DIR/$tfile failed"
16210         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16211         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16212         want=$((512 * 1048576))
16213
16214         # Must allocate all requested space, not more than 5% extra
16215         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16216                 error "bytes $bytes is not $want"
16217 }
16218 run_test 150c "Verify fallocate Size and Blocks"
16219
16220 test_150d() {
16221         check_set_fallocate_or_skip
16222         local striping="-c2"
16223
16224         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16225
16226         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16227         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16228                 error "setstripe failed"
16229         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16230         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16231         local want=$((OSTCOUNT * 1048576))
16232
16233         # Must allocate all requested space, not more than 5% extra
16234         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16235                 error "bytes $bytes is not $want"
16236 }
16237 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16238
16239 test_150e() {
16240         check_set_fallocate_or_skip
16241
16242         echo "df before:"
16243         $LFS df
16244         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16245         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16246                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16247
16248         # Find OST with Minimum Size
16249         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16250                        sort -un | head -1)
16251
16252         # Get 100MB per OST of the available space to reduce run time
16253         # else 60% of the available space if we are running SLOW tests
16254         if [ $SLOW == "no" ]; then
16255                 local space=$((1024 * 100 * OSTCOUNT))
16256         else
16257                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16258         fi
16259
16260         fallocate -l${space}k $DIR/$tfile ||
16261                 error "fallocate ${space}k $DIR/$tfile failed"
16262         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16263
16264         # get size immediately after fallocate. This should be correctly
16265         # updated
16266         local size=$(stat -c '%s' $DIR/$tfile)
16267         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16268
16269         # Sleep for a while for statfs to get updated. And not pull from cache.
16270         sleep 2
16271
16272         echo "df after fallocate:"
16273         $LFS df
16274
16275         (( size / 1024 == space )) || error "size $size != requested $space"
16276         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16277                 error "used $used < space $space"
16278
16279         rm $DIR/$tfile || error "rm failed"
16280         sync
16281         wait_delete_completed
16282
16283         echo "df after unlink:"
16284         $LFS df
16285 }
16286 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16287
16288 test_150f() {
16289         local size
16290         local blocks
16291         local want_size_before=20480 # in bytes
16292         local want_blocks_before=40 # 512 sized blocks
16293         local want_blocks_after=24  # 512 sized blocks
16294         local length=$(((want_blocks_before - want_blocks_after) * 512))
16295
16296         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16297                 skip "need at least 2.14.0 for fallocate punch"
16298
16299         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16300                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16301         fi
16302
16303         check_set_fallocate_or_skip
16304         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16305
16306         [[ "x$DOM" == "xyes" ]] &&
16307                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16308
16309         echo "Verify fallocate punch: Range within the file range"
16310         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16311                 error "dd failed for bs 4096 and count 5"
16312
16313         # Call fallocate with punch range which is within the file range
16314         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16315                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16316         # client must see changes immediately after fallocate
16317         size=$(stat -c '%s' $DIR/$tfile)
16318         blocks=$(stat -c '%b' $DIR/$tfile)
16319
16320         # Verify punch worked.
16321         (( blocks == want_blocks_after )) ||
16322                 error "punch failed: blocks $blocks != $want_blocks_after"
16323
16324         (( size == want_size_before )) ||
16325                 error "punch failed: size $size != $want_size_before"
16326
16327         # Verify there is hole in file
16328         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16329         # precomputed md5sum
16330         local expect="4a9a834a2db02452929c0a348273b4aa"
16331
16332         cksum=($(md5sum $DIR/$tfile))
16333         [[ "${cksum[0]}" == "$expect" ]] ||
16334                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16335
16336         # Start second sub-case for fallocate punch.
16337         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16338         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16339                 error "dd failed for bs 4096 and count 5"
16340
16341         # Punch range less than block size will have no change in block count
16342         want_blocks_after=40  # 512 sized blocks
16343
16344         # Punch overlaps two blocks and less than blocksize
16345         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16346                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16347         size=$(stat -c '%s' $DIR/$tfile)
16348         blocks=$(stat -c '%b' $DIR/$tfile)
16349
16350         # Verify punch worked.
16351         (( blocks == want_blocks_after )) ||
16352                 error "punch failed: blocks $blocks != $want_blocks_after"
16353
16354         (( size == want_size_before )) ||
16355                 error "punch failed: size $size != $want_size_before"
16356
16357         # Verify if range is really zero'ed out. We expect Zeros.
16358         # precomputed md5sum
16359         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16360         cksum=($(md5sum $DIR/$tfile))
16361         [[ "${cksum[0]}" == "$expect" ]] ||
16362                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16363 }
16364 run_test 150f "Verify fallocate punch functionality"
16365
16366 test_150g() {
16367         local space
16368         local size
16369         local blocks
16370         local blocks_after
16371         local size_after
16372         local BS=4096 # Block size in bytes
16373
16374         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16375                 skip "need at least 2.14.0 for fallocate punch"
16376
16377         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16378                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16379         fi
16380
16381         check_set_fallocate_or_skip
16382         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16383
16384         if [[ "x$DOM" == "xyes" ]]; then
16385                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16386                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16387         else
16388                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16389                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16390         fi
16391
16392         # Get 100MB per OST of the available space to reduce run time
16393         # else 60% of the available space if we are running SLOW tests
16394         if [ $SLOW == "no" ]; then
16395                 space=$((1024 * 100 * OSTCOUNT))
16396         else
16397                 # Find OST with Minimum Size
16398                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16399                         sort -un | head -1)
16400                 echo "min size OST: $space"
16401                 space=$(((space * 60)/100 * OSTCOUNT))
16402         fi
16403         # space in 1k units, round to 4k blocks
16404         local blkcount=$((space * 1024 / $BS))
16405
16406         echo "Verify fallocate punch: Very large Range"
16407         fallocate -l${space}k $DIR/$tfile ||
16408                 error "fallocate ${space}k $DIR/$tfile failed"
16409         # write 1M at the end, start and in the middle
16410         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16411                 error "dd failed: bs $BS count 256"
16412         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16413                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16414         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16415                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16416
16417         # Gather stats.
16418         size=$(stat -c '%s' $DIR/$tfile)
16419
16420         # gather punch length.
16421         local punch_size=$((size - (BS * 2)))
16422
16423         echo "punch_size = $punch_size"
16424         echo "size - punch_size: $((size - punch_size))"
16425         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16426
16427         # Call fallocate to punch all except 2 blocks. We leave the
16428         # first and the last block
16429         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16430         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16431                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16432
16433         size_after=$(stat -c '%s' $DIR/$tfile)
16434         blocks_after=$(stat -c '%b' $DIR/$tfile)
16435
16436         # Verify punch worked.
16437         # Size should be kept
16438         (( size == size_after )) ||
16439                 error "punch failed: size $size != $size_after"
16440
16441         # two 4k data blocks to remain plus possible 1 extra extent block
16442         (( blocks_after <= ((BS / 512) * 3) )) ||
16443                 error "too many blocks remains: $blocks_after"
16444
16445         # Verify that file has hole between the first and the last blocks
16446         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16447         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16448
16449         echo "Hole at [$hole_start, $hole_end)"
16450         (( hole_start == BS )) ||
16451                 error "no hole at offset $BS after punch"
16452
16453         (( hole_end == BS + punch_size )) ||
16454                 error "data at offset $hole_end < $((BS + punch_size))"
16455 }
16456 run_test 150g "Verify fallocate punch on large range"
16457
16458 test_150h() {
16459         local file=$DIR/$tfile
16460         local size
16461
16462         check_set_fallocate_or_skip
16463         statx_supported || skip_env "Test must be statx() syscall supported"
16464
16465         # fallocate() does not update the size information on the MDT
16466         fallocate -l 16K $file || error "failed to fallocate $file"
16467         cancel_lru_locks $OSC
16468         # STATX with cached-always mode will not send glimpse RPCs to OST,
16469         # it uses the caching attrs on the client side as much as possible.
16470         size=$($STATX --cached=always -c %s $file)
16471         [ $size == 16384 ] ||
16472                 error "size after fallocate() is $size, expected 16384"
16473 }
16474 run_test 150h "Verify extend fallocate updates the file size"
16475
16476 #LU-2902 roc_hit was not able to read all values from lproc
16477 function roc_hit_init() {
16478         local list=$(comma_list $(osts_nodes))
16479         local dir=$DIR/$tdir-check
16480         local file=$dir/$tfile
16481         local BEFORE
16482         local AFTER
16483         local idx
16484
16485         test_mkdir $dir
16486         #use setstripe to do a write to every ost
16487         for i in $(seq 0 $((OSTCOUNT-1))); do
16488                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16489                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16490                 idx=$(printf %04x $i)
16491                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16492                         awk '$1 == "cache_access" {sum += $7}
16493                                 END { printf("%0.0f", sum) }')
16494
16495                 cancel_lru_locks osc
16496                 cat $file >/dev/null
16497
16498                 AFTER=$(get_osd_param $list *OST*$idx stats |
16499                         awk '$1 == "cache_access" {sum += $7}
16500                                 END { printf("%0.0f", sum) }')
16501
16502                 echo BEFORE:$BEFORE AFTER:$AFTER
16503                 if ! let "AFTER - BEFORE == 4"; then
16504                         rm -rf $dir
16505                         error "roc_hit is not safe to use"
16506                 fi
16507                 rm $file
16508         done
16509
16510         rm -rf $dir
16511 }
16512
16513 function roc_hit() {
16514         local list=$(comma_list $(osts_nodes))
16515         echo $(get_osd_param $list '' stats |
16516                 awk '$1 == "cache_hit" {sum += $7}
16517                         END { printf("%0.0f", sum) }')
16518 }
16519
16520 function set_cache() {
16521         local on=1
16522
16523         if [ "$2" == "off" ]; then
16524                 on=0;
16525         fi
16526         local list=$(comma_list $(osts_nodes))
16527         set_osd_param $list '' $1_cache_enable $on
16528
16529         cancel_lru_locks osc
16530 }
16531
16532 test_151() {
16533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16534         remote_ost_nodsh && skip "remote OST with nodsh"
16535         (( CLIENT_VERSION == OST1_VERSION )) ||
16536                 skip "LU-13081: no interop testing for OSS cache"
16537
16538         local CPAGES=3
16539         local list=$(comma_list $(osts_nodes))
16540
16541         # check whether obdfilter is cache capable at all
16542         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16543                 skip "not cache-capable obdfilter"
16544         fi
16545
16546         # check cache is enabled on all obdfilters
16547         if get_osd_param $list '' read_cache_enable | grep 0; then
16548                 skip "oss cache is disabled"
16549         fi
16550
16551         set_osd_param $list '' writethrough_cache_enable 1
16552
16553         # check write cache is enabled on all obdfilters
16554         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16555                 skip "oss write cache is NOT enabled"
16556         fi
16557
16558         roc_hit_init
16559
16560         #define OBD_FAIL_OBD_NO_LRU  0x609
16561         do_nodes $list $LCTL set_param fail_loc=0x609
16562
16563         # pages should be in the case right after write
16564         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16565                 error "dd failed"
16566
16567         local BEFORE=$(roc_hit)
16568         cancel_lru_locks osc
16569         cat $DIR/$tfile >/dev/null
16570         local AFTER=$(roc_hit)
16571
16572         do_nodes $list $LCTL set_param fail_loc=0
16573
16574         if ! let "AFTER - BEFORE == CPAGES"; then
16575                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16576         fi
16577
16578         cancel_lru_locks osc
16579         # invalidates OST cache
16580         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16581         set_osd_param $list '' read_cache_enable 0
16582         cat $DIR/$tfile >/dev/null
16583
16584         # now data shouldn't be found in the cache
16585         BEFORE=$(roc_hit)
16586         cancel_lru_locks osc
16587         cat $DIR/$tfile >/dev/null
16588         AFTER=$(roc_hit)
16589         if let "AFTER - BEFORE != 0"; then
16590                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16591         fi
16592
16593         set_osd_param $list '' read_cache_enable 1
16594         rm -f $DIR/$tfile
16595 }
16596 run_test 151 "test cache on oss and controls ==============================="
16597
16598 test_152() {
16599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16600
16601         local TF="$TMP/$tfile"
16602
16603         # simulate ENOMEM during write
16604 #define OBD_FAIL_OST_NOMEM      0x226
16605         lctl set_param fail_loc=0x80000226
16606         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16607         cp $TF $DIR/$tfile
16608         sync || error "sync failed"
16609         lctl set_param fail_loc=0
16610
16611         # discard client's cache
16612         cancel_lru_locks osc
16613
16614         # simulate ENOMEM during read
16615         lctl set_param fail_loc=0x80000226
16616         cmp $TF $DIR/$tfile || error "cmp failed"
16617         lctl set_param fail_loc=0
16618
16619         rm -f $TF
16620 }
16621 run_test 152 "test read/write with enomem ============================"
16622
16623 test_153() {
16624         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16625 }
16626 run_test 153 "test if fdatasync does not crash ======================="
16627
16628 dot_lustre_fid_permission_check() {
16629         local fid=$1
16630         local ffid=$MOUNT/.lustre/fid/$fid
16631         local test_dir=$2
16632
16633         echo "stat fid $fid"
16634         stat $ffid || error "stat $ffid failed."
16635         echo "touch fid $fid"
16636         touch $ffid || error "touch $ffid failed."
16637         echo "write to fid $fid"
16638         cat /etc/hosts > $ffid || error "write $ffid failed."
16639         echo "read fid $fid"
16640         diff /etc/hosts $ffid || error "read $ffid failed."
16641         echo "append write to fid $fid"
16642         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16643         echo "rename fid $fid"
16644         mv $ffid $test_dir/$tfile.1 &&
16645                 error "rename $ffid to $tfile.1 should fail."
16646         touch $test_dir/$tfile.1
16647         mv $test_dir/$tfile.1 $ffid &&
16648                 error "rename $tfile.1 to $ffid should fail."
16649         rm -f $test_dir/$tfile.1
16650         echo "truncate fid $fid"
16651         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16652         echo "link fid $fid"
16653         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16654         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16655                 id $USER0 || skip_env "missing user $USER0"
16656                 echo "setfacl fid $fid"
16657                 setfacl -R -m u:$USER0:rwx $ffid ||
16658                         error "setfacl $ffid failed"
16659                 echo "getfacl fid $fid"
16660                 getfacl $ffid || error "getfacl $ffid failed."
16661         fi
16662         echo "unlink fid $fid"
16663         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16664         echo "mknod fid $fid"
16665         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16666
16667         fid=[0xf00000400:0x1:0x0]
16668         ffid=$MOUNT/.lustre/fid/$fid
16669
16670         echo "stat non-exist fid $fid"
16671         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16672         echo "write to non-exist fid $fid"
16673         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16674         echo "link new fid $fid"
16675         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16676
16677         mkdir -p $test_dir/$tdir
16678         touch $test_dir/$tdir/$tfile
16679         fid=$($LFS path2fid $test_dir/$tdir)
16680         rc=$?
16681         [ $rc -ne 0 ] &&
16682                 error "error: could not get fid for $test_dir/$dir/$tfile."
16683
16684         ffid=$MOUNT/.lustre/fid/$fid
16685
16686         echo "ls $fid"
16687         ls $ffid || error "ls $ffid failed."
16688         echo "touch $fid/$tfile.1"
16689         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16690
16691         echo "touch $MOUNT/.lustre/fid/$tfile"
16692         touch $MOUNT/.lustre/fid/$tfile && \
16693                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16694
16695         echo "setxattr to $MOUNT/.lustre/fid"
16696         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16697
16698         echo "listxattr for $MOUNT/.lustre/fid"
16699         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16700
16701         echo "delxattr from $MOUNT/.lustre/fid"
16702         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16703
16704         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16705         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16706                 error "touch invalid fid should fail."
16707
16708         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16709         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16710                 error "touch non-normal fid should fail."
16711
16712         echo "rename $tdir to $MOUNT/.lustre/fid"
16713         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16714                 error "rename to $MOUNT/.lustre/fid should fail."
16715
16716         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16717         then            # LU-3547
16718                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16719                 local new_obf_mode=777
16720
16721                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16722                 chmod $new_obf_mode $DIR/.lustre/fid ||
16723                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16724
16725                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16726                 [ $obf_mode -eq $new_obf_mode ] ||
16727                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16728
16729                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16730                 chmod $old_obf_mode $DIR/.lustre/fid ||
16731                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16732         fi
16733
16734         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16735         fid=$($LFS path2fid $test_dir/$tfile-2)
16736
16737         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16738         then # LU-5424
16739                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16740                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16741                         error "create lov data thru .lustre failed"
16742         fi
16743         echo "cp /etc/passwd $test_dir/$tfile-2"
16744         cp /etc/passwd $test_dir/$tfile-2 ||
16745                 error "copy to $test_dir/$tfile-2 failed."
16746         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16747         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16748                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16749
16750         rm -rf $test_dir/tfile.lnk
16751         rm -rf $test_dir/$tfile-2
16752 }
16753
16754 test_154A() {
16755         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16756                 skip "Need MDS version at least 2.4.1"
16757
16758         local tf=$DIR/$tfile
16759         touch $tf
16760
16761         local fid=$($LFS path2fid $tf)
16762         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16763
16764         # check that we get the same pathname back
16765         local rootpath
16766         local found
16767         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16768                 echo "$rootpath $fid"
16769                 found=$($LFS fid2path $rootpath "$fid")
16770                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16771                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16772         done
16773
16774         # check wrong root path format
16775         rootpath=$MOUNT"_wrong"
16776         found=$($LFS fid2path $rootpath "$fid")
16777         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16778 }
16779 run_test 154A "lfs path2fid and fid2path basic checks"
16780
16781 test_154B() {
16782         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16783                 skip "Need MDS version at least 2.4.1"
16784
16785         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16786         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16787         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16788         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16789
16790         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16791         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16792
16793         # check that we get the same pathname
16794         echo "PFID: $PFID, name: $name"
16795         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16796         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16797         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16798                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16799
16800         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16801 }
16802 run_test 154B "verify the ll_decode_linkea tool"
16803
16804 test_154a() {
16805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16806         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16807         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16808                 skip "Need MDS version at least 2.2.51"
16809         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16810
16811         cp /etc/hosts $DIR/$tfile
16812
16813         fid=$($LFS path2fid $DIR/$tfile)
16814         rc=$?
16815         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16816
16817         dot_lustre_fid_permission_check "$fid" $DIR ||
16818                 error "dot lustre permission check $fid failed"
16819
16820         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16821
16822         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16823
16824         touch $MOUNT/.lustre/file &&
16825                 error "creation is not allowed under .lustre"
16826
16827         mkdir $MOUNT/.lustre/dir &&
16828                 error "mkdir is not allowed under .lustre"
16829
16830         rm -rf $DIR/$tfile
16831 }
16832 run_test 154a "Open-by-FID"
16833
16834 test_154b() {
16835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16836         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16838         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16839                 skip "Need MDS version at least 2.2.51"
16840
16841         local remote_dir=$DIR/$tdir/remote_dir
16842         local MDTIDX=1
16843         local rc=0
16844
16845         mkdir -p $DIR/$tdir
16846         $LFS mkdir -i $MDTIDX $remote_dir ||
16847                 error "create remote directory failed"
16848
16849         cp /etc/hosts $remote_dir/$tfile
16850
16851         fid=$($LFS path2fid $remote_dir/$tfile)
16852         rc=$?
16853         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16854
16855         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16856                 error "dot lustre permission check $fid failed"
16857         rm -rf $DIR/$tdir
16858 }
16859 run_test 154b "Open-by-FID for remote directory"
16860
16861 test_154c() {
16862         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16863                 skip "Need MDS version at least 2.4.1"
16864
16865         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16866         local FID1=$($LFS path2fid $DIR/$tfile.1)
16867         local FID2=$($LFS path2fid $DIR/$tfile.2)
16868         local FID3=$($LFS path2fid $DIR/$tfile.3)
16869
16870         local N=1
16871         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16872                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16873                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16874                 local want=FID$N
16875                 [ "$FID" = "${!want}" ] ||
16876                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16877                 N=$((N + 1))
16878         done
16879
16880         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16881         do
16882                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16883                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16884                 N=$((N + 1))
16885         done
16886 }
16887 run_test 154c "lfs path2fid and fid2path multiple arguments"
16888
16889 test_154d() {
16890         remote_mds_nodsh && skip "remote MDS with nodsh"
16891         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16892                 skip "Need MDS version at least 2.5.53"
16893
16894         if remote_mds; then
16895                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16896         else
16897                 nid="0@lo"
16898         fi
16899         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16900         local fd
16901         local cmd
16902
16903         rm -f $DIR/$tfile
16904         touch $DIR/$tfile
16905
16906         local fid=$($LFS path2fid $DIR/$tfile)
16907         # Open the file
16908         fd=$(free_fd)
16909         cmd="exec $fd<$DIR/$tfile"
16910         eval $cmd
16911         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16912         echo "$fid_list" | grep "$fid"
16913         rc=$?
16914
16915         cmd="exec $fd>/dev/null"
16916         eval $cmd
16917         if [ $rc -ne 0 ]; then
16918                 error "FID $fid not found in open files list $fid_list"
16919         fi
16920 }
16921 run_test 154d "Verify open file fid"
16922
16923 test_154e()
16924 {
16925         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16926                 skip "Need MDS version at least 2.6.50"
16927
16928         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16929                 error ".lustre returned by readdir"
16930         fi
16931 }
16932 run_test 154e ".lustre is not returned by readdir"
16933
16934 test_154f() {
16935         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16936
16937         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16938         mkdir_on_mdt0 $DIR/$tdir
16939         # test dirs inherit from its stripe
16940         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16941         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16942         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16943         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16944         touch $DIR/f
16945
16946         # get fid of parents
16947         local FID0=$($LFS path2fid $DIR/$tdir)
16948         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16949         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16950         local FID3=$($LFS path2fid $DIR)
16951
16952         # check that path2fid --parents returns expected <parent_fid>/name
16953         # 1) test for a directory (single parent)
16954         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16955         [ "$parent" == "$FID0/foo1" ] ||
16956                 error "expected parent: $FID0/foo1, got: $parent"
16957
16958         # 2) test for a file with nlink > 1 (multiple parents)
16959         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16960         echo "$parent" | grep -F "$FID1/$tfile" ||
16961                 error "$FID1/$tfile not returned in parent list"
16962         echo "$parent" | grep -F "$FID2/link" ||
16963                 error "$FID2/link not returned in parent list"
16964
16965         # 3) get parent by fid
16966         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16967         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16968         echo "$parent" | grep -F "$FID1/$tfile" ||
16969                 error "$FID1/$tfile not returned in parent list (by fid)"
16970         echo "$parent" | grep -F "$FID2/link" ||
16971                 error "$FID2/link not returned in parent list (by fid)"
16972
16973         # 4) test for entry in root directory
16974         parent=$($LFS path2fid --parents $DIR/f)
16975         echo "$parent" | grep -F "$FID3/f" ||
16976                 error "$FID3/f not returned in parent list"
16977
16978         # 5) test it on root directory
16979         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16980                 error "$MOUNT should not have parents"
16981
16982         # enable xattr caching and check that linkea is correctly updated
16983         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16984         save_lustre_params client "llite.*.xattr_cache" > $save
16985         lctl set_param llite.*.xattr_cache 1
16986
16987         # 6.1) linkea update on rename
16988         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16989
16990         # get parents by fid
16991         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16992         # foo1 should no longer be returned in parent list
16993         echo "$parent" | grep -F "$FID1" &&
16994                 error "$FID1 should no longer be in parent list"
16995         # the new path should appear
16996         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16997                 error "$FID2/$tfile.moved is not in parent list"
16998
16999         # 6.2) linkea update on unlink
17000         rm -f $DIR/$tdir/foo2/link
17001         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17002         # foo2/link should no longer be returned in parent list
17003         echo "$parent" | grep -F "$FID2/link" &&
17004                 error "$FID2/link should no longer be in parent list"
17005         true
17006
17007         rm -f $DIR/f
17008         restore_lustre_params < $save
17009         rm -f $save
17010 }
17011 run_test 154f "get parent fids by reading link ea"
17012
17013 test_154g()
17014 {
17015         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17016            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17017                 skip "Need MDS version at least 2.6.92"
17018
17019         mkdir_on_mdt0 $DIR/$tdir
17020         llapi_fid_test -d $DIR/$tdir
17021 }
17022 run_test 154g "various llapi FID tests"
17023
17024 test_154h()
17025 {
17026         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17027                 skip "Need client at least version 2.15.55.1"
17028
17029         # Create an empty file
17030         touch $DIR/$tfile
17031
17032         # Get FID (interactive mode) and save under $TMP/$tfile.log
17033         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17034                 path2fid $DIR/$tfile
17035         EOF
17036
17037         fid=$(cat $TMP/$tfile.log)
17038         # $fid should not be empty
17039         [[ ! -z $fid ]] || error "FID is empty"
17040         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17041 }
17042 run_test 154h "Verify interactive path2fid"
17043
17044 test_155_small_load() {
17045     local temp=$TMP/$tfile
17046     local file=$DIR/$tfile
17047
17048     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17049         error "dd of=$temp bs=6096 count=1 failed"
17050     cp $temp $file
17051     cancel_lru_locks $OSC
17052     cmp $temp $file || error "$temp $file differ"
17053
17054     $TRUNCATE $temp 6000
17055     $TRUNCATE $file 6000
17056     cmp $temp $file || error "$temp $file differ (truncate1)"
17057
17058     echo "12345" >>$temp
17059     echo "12345" >>$file
17060     cmp $temp $file || error "$temp $file differ (append1)"
17061
17062     echo "12345" >>$temp
17063     echo "12345" >>$file
17064     cmp $temp $file || error "$temp $file differ (append2)"
17065
17066     rm -f $temp $file
17067     true
17068 }
17069
17070 test_155_big_load() {
17071         remote_ost_nodsh && skip "remote OST with nodsh"
17072
17073         local temp=$TMP/$tfile
17074         local file=$DIR/$tfile
17075
17076         free_min_max
17077         local cache_size=$(do_facet ost$((MAXI+1)) \
17078                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17079
17080         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17081         # pre-set value
17082         if [ -z "$cache_size" ]; then
17083                 cache_size=256
17084         fi
17085         local large_file_size=$((cache_size * 2))
17086
17087         echo "OSS cache size: $cache_size KB"
17088         echo "Large file size: $large_file_size KB"
17089
17090         [ $MAXV -le $large_file_size ] &&
17091                 skip_env "max available OST size needs > $large_file_size KB"
17092
17093         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17094
17095         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17096                 error "dd of=$temp bs=$large_file_size count=1k failed"
17097         cp $temp $file
17098         ls -lh $temp $file
17099         cancel_lru_locks osc
17100         cmp $temp $file || error "$temp $file differ"
17101
17102         rm -f $temp $file
17103         true
17104 }
17105
17106 save_writethrough() {
17107         local facets=$(get_facets OST)
17108
17109         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17110 }
17111
17112 test_155a() {
17113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17114
17115         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17116
17117         save_writethrough $p
17118
17119         set_cache read on
17120         set_cache writethrough on
17121         test_155_small_load
17122         restore_lustre_params < $p
17123         rm -f $p
17124 }
17125 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17126
17127 test_155b() {
17128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17129
17130         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17131
17132         save_writethrough $p
17133
17134         set_cache read on
17135         set_cache writethrough off
17136         test_155_small_load
17137         restore_lustre_params < $p
17138         rm -f $p
17139 }
17140 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17141
17142 test_155c() {
17143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17144
17145         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17146
17147         save_writethrough $p
17148
17149         set_cache read off
17150         set_cache writethrough on
17151         test_155_small_load
17152         restore_lustre_params < $p
17153         rm -f $p
17154 }
17155 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17156
17157 test_155d() {
17158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17159
17160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17161
17162         save_writethrough $p
17163
17164         set_cache read off
17165         set_cache writethrough off
17166         test_155_small_load
17167         restore_lustre_params < $p
17168         rm -f $p
17169 }
17170 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17171
17172 test_155e() {
17173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17174
17175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17176
17177         save_writethrough $p
17178
17179         set_cache read on
17180         set_cache writethrough on
17181         test_155_big_load
17182         restore_lustre_params < $p
17183         rm -f $p
17184 }
17185 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17186
17187 test_155f() {
17188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17189
17190         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17191
17192         save_writethrough $p
17193
17194         set_cache read on
17195         set_cache writethrough off
17196         test_155_big_load
17197         restore_lustre_params < $p
17198         rm -f $p
17199 }
17200 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17201
17202 test_155g() {
17203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17204
17205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17206
17207         save_writethrough $p
17208
17209         set_cache read off
17210         set_cache writethrough on
17211         test_155_big_load
17212         restore_lustre_params < $p
17213         rm -f $p
17214 }
17215 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17216
17217 test_155h() {
17218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17219
17220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17221
17222         save_writethrough $p
17223
17224         set_cache read off
17225         set_cache writethrough off
17226         test_155_big_load
17227         restore_lustre_params < $p
17228         rm -f $p
17229 }
17230 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17231
17232 test_156() {
17233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17234         remote_ost_nodsh && skip "remote OST with nodsh"
17235         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17236                 skip "stats not implemented on old servers"
17237         [ "$ost1_FSTYPE" = "zfs" ] &&
17238                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17239         (( CLIENT_VERSION == OST1_VERSION )) ||
17240                 skip "LU-13081: no interop testing for OSS cache"
17241
17242         local CPAGES=3
17243         local BEFORE
17244         local AFTER
17245         local file="$DIR/$tfile"
17246         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17247
17248         save_writethrough $p
17249         roc_hit_init
17250
17251         log "Turn on read and write cache"
17252         set_cache read on
17253         set_cache writethrough on
17254
17255         log "Write data and read it back."
17256         log "Read should be satisfied from the cache."
17257         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17258         BEFORE=$(roc_hit)
17259         cancel_lru_locks osc
17260         cat $file >/dev/null
17261         AFTER=$(roc_hit)
17262         if ! let "AFTER - BEFORE == CPAGES"; then
17263                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17264         else
17265                 log "cache hits: before: $BEFORE, after: $AFTER"
17266         fi
17267
17268         log "Read again; it should be satisfied from the cache."
17269         BEFORE=$AFTER
17270         cancel_lru_locks osc
17271         cat $file >/dev/null
17272         AFTER=$(roc_hit)
17273         if ! let "AFTER - BEFORE == CPAGES"; then
17274                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17275         else
17276                 log "cache hits:: before: $BEFORE, after: $AFTER"
17277         fi
17278
17279         log "Turn off the read cache and turn on the write cache"
17280         set_cache read off
17281         set_cache writethrough on
17282
17283         log "Read again; it should be satisfied from the cache."
17284         BEFORE=$(roc_hit)
17285         cancel_lru_locks osc
17286         cat $file >/dev/null
17287         AFTER=$(roc_hit)
17288         if ! let "AFTER - BEFORE == CPAGES"; then
17289                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17290         else
17291                 log "cache hits:: before: $BEFORE, after: $AFTER"
17292         fi
17293
17294         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17295                 # > 2.12.56 uses pagecache if cached
17296                 log "Read again; it should not be satisfied from the cache."
17297                 BEFORE=$AFTER
17298                 cancel_lru_locks osc
17299                 cat $file >/dev/null
17300                 AFTER=$(roc_hit)
17301                 if ! let "AFTER - BEFORE == 0"; then
17302                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17303                 else
17304                         log "cache hits:: before: $BEFORE, after: $AFTER"
17305                 fi
17306         fi
17307
17308         log "Write data and read it back."
17309         log "Read should be satisfied from the cache."
17310         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17311         BEFORE=$(roc_hit)
17312         cancel_lru_locks osc
17313         cat $file >/dev/null
17314         AFTER=$(roc_hit)
17315         if ! let "AFTER - BEFORE == CPAGES"; then
17316                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17317         else
17318                 log "cache hits:: before: $BEFORE, after: $AFTER"
17319         fi
17320
17321         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17322                 # > 2.12.56 uses pagecache if cached
17323                 log "Read again; it should not be satisfied from the cache."
17324                 BEFORE=$AFTER
17325                 cancel_lru_locks osc
17326                 cat $file >/dev/null
17327                 AFTER=$(roc_hit)
17328                 if ! let "AFTER - BEFORE == 0"; then
17329                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17330                 else
17331                         log "cache hits:: before: $BEFORE, after: $AFTER"
17332                 fi
17333         fi
17334
17335         log "Turn off read and write cache"
17336         set_cache read off
17337         set_cache writethrough off
17338
17339         log "Write data and read it back"
17340         log "It should not be satisfied from the cache."
17341         rm -f $file
17342         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17343         cancel_lru_locks osc
17344         BEFORE=$(roc_hit)
17345         cat $file >/dev/null
17346         AFTER=$(roc_hit)
17347         if ! let "AFTER - BEFORE == 0"; then
17348                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17349         else
17350                 log "cache hits:: before: $BEFORE, after: $AFTER"
17351         fi
17352
17353         log "Turn on the read cache and turn off the write cache"
17354         set_cache read on
17355         set_cache writethrough off
17356
17357         log "Write data and read it back"
17358         log "It should not be satisfied from the cache."
17359         rm -f $file
17360         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17361         BEFORE=$(roc_hit)
17362         cancel_lru_locks osc
17363         cat $file >/dev/null
17364         AFTER=$(roc_hit)
17365         if ! let "AFTER - BEFORE == 0"; then
17366                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17367         else
17368                 log "cache hits:: before: $BEFORE, after: $AFTER"
17369         fi
17370
17371         log "Read again; it should be satisfied from the cache."
17372         BEFORE=$(roc_hit)
17373         cancel_lru_locks osc
17374         cat $file >/dev/null
17375         AFTER=$(roc_hit)
17376         if ! let "AFTER - BEFORE == CPAGES"; then
17377                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17378         else
17379                 log "cache hits:: before: $BEFORE, after: $AFTER"
17380         fi
17381
17382         restore_lustre_params < $p
17383         rm -f $p $file
17384 }
17385 run_test 156 "Verification of tunables"
17386
17387 test_160a() {
17388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17389         remote_mds_nodsh && skip "remote MDS with nodsh"
17390         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17391                 skip "Need MDS version at least 2.2.0"
17392
17393         changelog_register || error "changelog_register failed"
17394         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17395         changelog_users $SINGLEMDS | grep -q $cl_user ||
17396                 error "User $cl_user not found in changelog_users"
17397
17398         mkdir_on_mdt0 $DIR/$tdir
17399
17400         # change something
17401         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17402         changelog_clear 0 || error "changelog_clear failed"
17403         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17404         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17405         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17406         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17407         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17408         rm $DIR/$tdir/pics/desktop.jpg
17409
17410         echo "verifying changelog mask"
17411         changelog_chmask "-MKDIR"
17412         changelog_chmask "-CLOSE"
17413
17414         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17415         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17416
17417         changelog_chmask "+MKDIR"
17418         changelog_chmask "+CLOSE"
17419
17420         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17421         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17422
17423         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17424         CLOSES=$(changelog_dump | grep -c "CLOSE")
17425         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17426         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17427
17428         # verify contents
17429         echo "verifying target fid"
17430         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17431         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17432         [ "$fidc" == "$fidf" ] ||
17433                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17434         echo "verifying parent fid"
17435         # The FID returned from the Changelog may be the directory shard on
17436         # a different MDT, and not the FID returned by path2fid on the parent.
17437         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17438         # since this is what will matter when recreating this file in the tree.
17439         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17440         local pathp=$($LFS fid2path $MOUNT "$fidp")
17441         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17442                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17443
17444         echo "getting records for $cl_user"
17445         changelog_users $SINGLEMDS
17446         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17447         local nclr=3
17448         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17449                 error "changelog_clear failed"
17450         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17451         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17452         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17453                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17454
17455         local min0_rec=$(changelog_users $SINGLEMDS |
17456                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17457         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17458                           awk '{ print $1; exit; }')
17459
17460         changelog_dump | tail -n 5
17461         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17462         [ $first_rec == $((min0_rec + 1)) ] ||
17463                 error "first index should be $min0_rec + 1 not $first_rec"
17464
17465         # LU-3446 changelog index reset on MDT restart
17466         local cur_rec1=$(changelog_users $SINGLEMDS |
17467                          awk '/^current.index:/ { print $NF }')
17468         changelog_clear 0 ||
17469                 error "clear all changelog records for $cl_user failed"
17470         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17471         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17472                 error "Fail to start $SINGLEMDS"
17473         local cur_rec2=$(changelog_users $SINGLEMDS |
17474                          awk '/^current.index:/ { print $NF }')
17475         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17476         [ $cur_rec1 == $cur_rec2 ] ||
17477                 error "current index should be $cur_rec1 not $cur_rec2"
17478
17479         echo "verifying users from this test are deregistered"
17480         changelog_deregister || error "changelog_deregister failed"
17481         changelog_users $SINGLEMDS | grep -q $cl_user &&
17482                 error "User '$cl_user' still in changelog_users"
17483
17484         # lctl get_param -n mdd.*.changelog_users
17485         # current_index: 144
17486         # ID    index (idle seconds)
17487         # cl3   144   (2) mask=<list>
17488         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17489                 # this is the normal case where all users were deregistered
17490                 # make sure no new records are added when no users are present
17491                 local last_rec1=$(changelog_users $SINGLEMDS |
17492                                   awk '/^current.index:/ { print $NF }')
17493                 touch $DIR/$tdir/chloe
17494                 local last_rec2=$(changelog_users $SINGLEMDS |
17495                                   awk '/^current.index:/ { print $NF }')
17496                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17497                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17498         else
17499                 # any changelog users must be leftovers from a previous test
17500                 changelog_users $SINGLEMDS
17501                 echo "other changelog users; can't verify off"
17502         fi
17503 }
17504 run_test 160a "changelog sanity"
17505
17506 test_160b() { # LU-3587
17507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17510                 skip "Need MDS version at least 2.2.0"
17511
17512         changelog_register || error "changelog_register failed"
17513         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17514         changelog_users $SINGLEMDS | grep -q $cl_user ||
17515                 error "User '$cl_user' not found in changelog_users"
17516
17517         local longname1=$(str_repeat a 255)
17518         local longname2=$(str_repeat b 255)
17519
17520         cd $DIR
17521         echo "creating very long named file"
17522         touch $longname1 || error "create of '$longname1' failed"
17523         echo "renaming very long named file"
17524         mv $longname1 $longname2
17525
17526         changelog_dump | grep RENME | tail -n 5
17527         rm -f $longname2
17528 }
17529 run_test 160b "Verify that very long rename doesn't crash in changelog"
17530
17531 test_160c() {
17532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17533         remote_mds_nodsh && skip "remote MDS with nodsh"
17534
17535         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17536                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17537                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17538                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17539
17540         local rc=0
17541
17542         # Registration step
17543         changelog_register || error "changelog_register failed"
17544
17545         rm -rf $DIR/$tdir
17546         mkdir -p $DIR/$tdir
17547         $MCREATE $DIR/$tdir/foo_160c
17548         changelog_chmask "-TRUNC"
17549         $TRUNCATE $DIR/$tdir/foo_160c 200
17550         changelog_chmask "+TRUNC"
17551         $TRUNCATE $DIR/$tdir/foo_160c 199
17552         changelog_dump | tail -n 5
17553         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17554         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17555 }
17556 run_test 160c "verify that changelog log catch the truncate event"
17557
17558 test_160d() {
17559         remote_mds_nodsh && skip "remote MDS with nodsh"
17560         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17562         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17563                 skip "Need MDS version at least 2.7.60"
17564
17565         # Registration step
17566         changelog_register || error "changelog_register failed"
17567
17568         mkdir -p $DIR/$tdir/migrate_dir
17569         changelog_clear 0 || error "changelog_clear failed"
17570
17571         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17572         changelog_dump | tail -n 5
17573         local migrates=$(changelog_dump | grep -c "MIGRT")
17574         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17575 }
17576 run_test 160d "verify that changelog log catch the migrate event"
17577
17578 test_160e() {
17579         remote_mds_nodsh && skip "remote MDS with nodsh"
17580
17581         # Create a user
17582         changelog_register || error "changelog_register failed"
17583
17584         local MDT0=$(facet_svc $SINGLEMDS)
17585         local rc
17586
17587         # No user (expect fail)
17588         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17589         rc=$?
17590         if [ $rc -eq 0 ]; then
17591                 error "Should fail without user"
17592         elif [ $rc -ne 4 ]; then
17593                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17594         fi
17595
17596         # Delete a future user (expect fail)
17597         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17598         rc=$?
17599         if [ $rc -eq 0 ]; then
17600                 error "Deleted non-existant user cl77"
17601         elif [ $rc -ne 2 ]; then
17602                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17603         fi
17604
17605         # Clear to a bad index (1 billion should be safe)
17606         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17607         rc=$?
17608
17609         if [ $rc -eq 0 ]; then
17610                 error "Successfully cleared to invalid CL index"
17611         elif [ $rc -ne 22 ]; then
17612                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17613         fi
17614 }
17615 run_test 160e "changelog negative testing (should return errors)"
17616
17617 test_160f() {
17618         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17619         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17620                 skip "Need MDS version at least 2.10.56"
17621
17622         local mdts=$(comma_list $(mdts_nodes))
17623
17624         # Create a user
17625         changelog_register || error "first changelog_register failed"
17626         changelog_register || error "second changelog_register failed"
17627         local cl_users
17628         declare -A cl_user1
17629         declare -A cl_user2
17630         local user_rec1
17631         local user_rec2
17632         local i
17633
17634         # generate some changelog records to accumulate on each MDT
17635         # use all_char because created files should be evenly distributed
17636         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17637                 error "test_mkdir $tdir failed"
17638         log "$(date +%s): creating first files"
17639         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17640                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17641                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17642         done
17643
17644         # check changelogs have been generated
17645         local start=$SECONDS
17646         local idle_time=$((MDSCOUNT * 5 + 5))
17647         local nbcl=$(changelog_dump | wc -l)
17648         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17649
17650         for param in "changelog_max_idle_time=$idle_time" \
17651                      "changelog_gc=1" \
17652                      "changelog_min_gc_interval=2" \
17653                      "changelog_min_free_cat_entries=3"; do
17654                 local MDT0=$(facet_svc $SINGLEMDS)
17655                 local var="${param%=*}"
17656                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17657
17658                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17659                 do_nodes $mdts $LCTL set_param mdd.*.$param
17660         done
17661
17662         # force cl_user2 to be idle (1st part), but also cancel the
17663         # cl_user1 records so that it is not evicted later in the test.
17664         local sleep1=$((idle_time / 2))
17665         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17666         sleep $sleep1
17667
17668         # simulate changelog catalog almost full
17669         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17670         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17671
17672         for i in $(seq $MDSCOUNT); do
17673                 cl_users=(${CL_USERS[mds$i]})
17674                 cl_user1[mds$i]="${cl_users[0]}"
17675                 cl_user2[mds$i]="${cl_users[1]}"
17676
17677                 [ -n "${cl_user1[mds$i]}" ] ||
17678                         error "mds$i: no user registered"
17679                 [ -n "${cl_user2[mds$i]}" ] ||
17680                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17681
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                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17686                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17687                 [ -n "$user_rec2" ] ||
17688                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17689                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17690                      "$user_rec1 + 2 == $user_rec2"
17691                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17692                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17693                               "$user_rec1 + 2, but is $user_rec2"
17694                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17695                 [ -n "$user_rec2" ] ||
17696                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17697                 [ $user_rec1 == $user_rec2 ] ||
17698                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17699                               "$user_rec1, but is $user_rec2"
17700         done
17701
17702         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17703         local sleep2=$((idle_time - (SECONDS - start) + 1))
17704         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17705         sleep $sleep2
17706
17707         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17708         # cl_user1 should be OK because it recently processed records.
17709         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17710         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17711                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17712                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17713         done
17714
17715         # ensure gc thread is done
17716         for i in $(mdts_nodes); do
17717                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17718                         error "$i: GC-thread not done"
17719         done
17720
17721         local first_rec
17722         for (( i = 1; i <= MDSCOUNT; i++ )); do
17723                 # check cl_user1 still registered
17724                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17725                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17726                 # check cl_user2 unregistered
17727                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17728                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17729
17730                 # check changelogs are present and starting at $user_rec1 + 1
17731                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17732                 [ -n "$user_rec1" ] ||
17733                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17734                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17735                             awk '{ print $1; exit; }')
17736
17737                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17738                 [ $((user_rec1 + 1)) == $first_rec ] ||
17739                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17740         done
17741 }
17742 run_test 160f "changelog garbage collect (timestamped users)"
17743
17744 test_160g() {
17745         remote_mds_nodsh && skip "remote MDS with nodsh"
17746         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17747                 skip "Need MDS version at least 2.14.55"
17748
17749         local mdts=$(comma_list $(mdts_nodes))
17750
17751         # Create a user
17752         changelog_register || error "first changelog_register failed"
17753         changelog_register || error "second changelog_register failed"
17754         local cl_users
17755         declare -A cl_user1
17756         declare -A cl_user2
17757         local user_rec1
17758         local user_rec2
17759         local i
17760
17761         # generate some changelog records to accumulate on each MDT
17762         # use all_char because created files should be evenly distributed
17763         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17764                 error "test_mkdir $tdir failed"
17765         for ((i = 0; i < MDSCOUNT; i++)); do
17766                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17767                         error "create $DIR/$tdir/d$i.1 failed"
17768         done
17769
17770         # check changelogs have been generated
17771         local nbcl=$(changelog_dump | wc -l)
17772         (( $nbcl > 0 )) || error "no changelogs found"
17773
17774         # reduce the max_idle_indexes value to make sure we exceed it
17775         for param in "changelog_max_idle_indexes=2" \
17776                      "changelog_gc=1" \
17777                      "changelog_min_gc_interval=2"; do
17778                 local MDT0=$(facet_svc $SINGLEMDS)
17779                 local var="${param%=*}"
17780                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17781
17782                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17783                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17784                         error "unable to set mdd.*.$param"
17785         done
17786
17787         local start=$SECONDS
17788         for i in $(seq $MDSCOUNT); do
17789                 cl_users=(${CL_USERS[mds$i]})
17790                 cl_user1[mds$i]="${cl_users[0]}"
17791                 cl_user2[mds$i]="${cl_users[1]}"
17792
17793                 [ -n "${cl_user1[mds$i]}" ] ||
17794                         error "mds$i: user1 is not registered"
17795                 [ -n "${cl_user2[mds$i]}" ] ||
17796                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17797
17798                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17799                 [ -n "$user_rec1" ] ||
17800                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17801                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17802                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17803                 [ -n "$user_rec2" ] ||
17804                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17805                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17806                      "$user_rec1 + 2 == $user_rec2"
17807                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17808                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17809                               "expected $user_rec1 + 2, but is $user_rec2"
17810                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17811                 [ -n "$user_rec2" ] ||
17812                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17813                 [ $user_rec1 == $user_rec2 ] ||
17814                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17815                               "expected $user_rec1, but is $user_rec2"
17816         done
17817
17818         # ensure we are past the previous changelog_min_gc_interval set above
17819         local sleep2=$((start + 2 - SECONDS))
17820         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17821         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17822         # cl_user1 should be OK because it recently processed records.
17823         for ((i = 0; i < MDSCOUNT; i++)); do
17824                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17825                         error "create $DIR/$tdir/d$i.3 failed"
17826         done
17827
17828         # ensure gc thread is done
17829         for i in $(mdts_nodes); do
17830                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17831                         error "$i: GC-thread not done"
17832         done
17833
17834         local first_rec
17835         for (( i = 1; i <= MDSCOUNT; i++ )); do
17836                 # check cl_user1 still registered
17837                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17838                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17839                 # check cl_user2 unregistered
17840                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17841                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17842
17843                 # check changelogs are present and starting at $user_rec1 + 1
17844                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17845                 [ -n "$user_rec1" ] ||
17846                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17847                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17848                             awk '{ print $1; exit; }')
17849
17850                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17851                 [ $((user_rec1 + 1)) == $first_rec ] ||
17852                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17853         done
17854 }
17855 run_test 160g "changelog garbage collect on idle records"
17856
17857 test_160h() {
17858         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17859         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17860                 skip "Need MDS version at least 2.10.56"
17861
17862         local mdts=$(comma_list $(mdts_nodes))
17863
17864         # Create a user
17865         changelog_register || error "first changelog_register failed"
17866         changelog_register || error "second changelog_register failed"
17867         local cl_users
17868         declare -A cl_user1
17869         declare -A cl_user2
17870         local user_rec1
17871         local user_rec2
17872         local i
17873
17874         # generate some changelog records to accumulate on each MDT
17875         # use all_char because created files should be evenly distributed
17876         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17877                 error "test_mkdir $tdir failed"
17878         for ((i = 0; i < MDSCOUNT; i++)); do
17879                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17880                         error "create $DIR/$tdir/d$i.1 failed"
17881         done
17882
17883         # check changelogs have been generated
17884         local nbcl=$(changelog_dump | wc -l)
17885         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17886
17887         for param in "changelog_max_idle_time=10" \
17888                      "changelog_gc=1" \
17889                      "changelog_min_gc_interval=2"; do
17890                 local MDT0=$(facet_svc $SINGLEMDS)
17891                 local var="${param%=*}"
17892                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17893
17894                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17895                 do_nodes $mdts $LCTL set_param mdd.*.$param
17896         done
17897
17898         # force cl_user2 to be idle (1st part)
17899         sleep 9
17900
17901         for i in $(seq $MDSCOUNT); do
17902                 cl_users=(${CL_USERS[mds$i]})
17903                 cl_user1[mds$i]="${cl_users[0]}"
17904                 cl_user2[mds$i]="${cl_users[1]}"
17905
17906                 [ -n "${cl_user1[mds$i]}" ] ||
17907                         error "mds$i: no user registered"
17908                 [ -n "${cl_user2[mds$i]}" ] ||
17909                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17910
17911                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17912                 [ -n "$user_rec1" ] ||
17913                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17914                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17915                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17916                 [ -n "$user_rec2" ] ||
17917                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17918                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17919                      "$user_rec1 + 2 == $user_rec2"
17920                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17921                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17922                               "$user_rec1 + 2, but is $user_rec2"
17923                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17924                 [ -n "$user_rec2" ] ||
17925                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17926                 [ $user_rec1 == $user_rec2 ] ||
17927                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17928                               "$user_rec1, but is $user_rec2"
17929         done
17930
17931         # force cl_user2 to be idle (2nd part) and to reach
17932         # changelog_max_idle_time
17933         sleep 2
17934
17935         # force each GC-thread start and block then
17936         # one per MDT/MDD, set fail_val accordingly
17937         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17938         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17939
17940         # generate more changelogs to trigger fail_loc
17941         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17942                 error "create $DIR/$tdir/${tfile}bis failed"
17943
17944         # stop MDT to stop GC-thread, should be done in back-ground as it will
17945         # block waiting for the thread to be released and exit
17946         declare -A stop_pids
17947         for i in $(seq $MDSCOUNT); do
17948                 stop mds$i &
17949                 stop_pids[mds$i]=$!
17950         done
17951
17952         for i in $(mdts_nodes); do
17953                 local facet
17954                 local nb=0
17955                 local facets=$(facets_up_on_host $i)
17956
17957                 for facet in ${facets//,/ }; do
17958                         if [[ $facet == mds* ]]; then
17959                                 nb=$((nb + 1))
17960                         fi
17961                 done
17962                 # ensure each MDS's gc threads are still present and all in "R"
17963                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17964                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17965                         error "$i: expected $nb GC-thread"
17966                 wait_update $i \
17967                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17968                         "R" 20 ||
17969                         error "$i: GC-thread not found in R-state"
17970                 # check umounts of each MDT on MDS have reached kthread_stop()
17971                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17972                         error "$i: expected $nb umount"
17973                 wait_update $i \
17974                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17975                         error "$i: umount not found in D-state"
17976         done
17977
17978         # release all GC-threads
17979         do_nodes $mdts $LCTL set_param fail_loc=0
17980
17981         # wait for MDT stop to complete
17982         for i in $(seq $MDSCOUNT); do
17983                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17984         done
17985
17986         # XXX
17987         # may try to check if any orphan changelog records are present
17988         # via ldiskfs/zfs and llog_reader...
17989
17990         # re-start/mount MDTs
17991         for i in $(seq $MDSCOUNT); do
17992                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17993                         error "Fail to start mds$i"
17994         done
17995
17996         local first_rec
17997         for i in $(seq $MDSCOUNT); do
17998                 # check cl_user1 still registered
17999                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18000                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18001                 # check cl_user2 unregistered
18002                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18003                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18004
18005                 # check changelogs are present and starting at $user_rec1 + 1
18006                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18007                 [ -n "$user_rec1" ] ||
18008                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18009                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18010                             awk '{ print $1; exit; }')
18011
18012                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18013                 [ $((user_rec1 + 1)) == $first_rec ] ||
18014                         error "mds$i: first index should be $user_rec1 + 1, " \
18015                               "but is $first_rec"
18016         done
18017 }
18018 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18019               "during mount"
18020
18021 test_160i() {
18022
18023         local mdts=$(comma_list $(mdts_nodes))
18024
18025         changelog_register || error "first changelog_register failed"
18026
18027         # generate some changelog records to accumulate on each MDT
18028         # use all_char because created files should be evenly distributed
18029         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18030                 error "test_mkdir $tdir failed"
18031         for ((i = 0; i < MDSCOUNT; i++)); do
18032                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18033                         error "create $DIR/$tdir/d$i.1 failed"
18034         done
18035
18036         # check changelogs have been generated
18037         local nbcl=$(changelog_dump | wc -l)
18038         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18039
18040         # simulate race between register and unregister
18041         # XXX as fail_loc is set per-MDS, with DNE configs the race
18042         # simulation will only occur for one MDT per MDS and for the
18043         # others the normal race scenario will take place
18044         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18045         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18046         do_nodes $mdts $LCTL set_param fail_val=1
18047
18048         # unregister 1st user
18049         changelog_deregister &
18050         local pid1=$!
18051         # wait some time for deregister work to reach race rdv
18052         sleep 2
18053         # register 2nd user
18054         changelog_register || error "2nd user register failed"
18055
18056         wait $pid1 || error "1st user deregister failed"
18057
18058         local i
18059         local last_rec
18060         declare -A LAST_REC
18061         for i in $(seq $MDSCOUNT); do
18062                 if changelog_users mds$i | grep "^cl"; then
18063                         # make sure new records are added with one user present
18064                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18065                                           awk '/^current.index:/ { print $NF }')
18066                 else
18067                         error "mds$i has no user registered"
18068                 fi
18069         done
18070
18071         # generate more changelog records to accumulate on each MDT
18072         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18073                 error "create $DIR/$tdir/${tfile}bis failed"
18074
18075         for i in $(seq $MDSCOUNT); do
18076                 last_rec=$(changelog_users $SINGLEMDS |
18077                            awk '/^current.index:/ { print $NF }')
18078                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18079                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18080                         error "changelogs are off on mds$i"
18081         done
18082 }
18083 run_test 160i "changelog user register/unregister race"
18084
18085 test_160j() {
18086         remote_mds_nodsh && skip "remote MDS with nodsh"
18087         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18088                 skip "Need MDS version at least 2.12.56"
18089
18090         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18091         stack_trap "umount $MOUNT2" EXIT
18092
18093         changelog_register || error "first changelog_register failed"
18094         stack_trap "changelog_deregister" EXIT
18095
18096         # generate some changelog
18097         # use all_char because created files should be evenly distributed
18098         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18099                 error "mkdir $tdir failed"
18100         for ((i = 0; i < MDSCOUNT; i++)); do
18101                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18102                         error "create $DIR/$tdir/d$i.1 failed"
18103         done
18104
18105         # open the changelog device
18106         exec 3>/dev/changelog-$FSNAME-MDT0000
18107         stack_trap "exec 3>&-" EXIT
18108         exec 4</dev/changelog-$FSNAME-MDT0000
18109         stack_trap "exec 4<&-" EXIT
18110
18111         # umount the first lustre mount
18112         umount $MOUNT
18113         stack_trap "mount_client $MOUNT" EXIT
18114
18115         # read changelog, which may or may not fail, but should not crash
18116         cat <&4 >/dev/null
18117
18118         # clear changelog
18119         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18120         changelog_users $SINGLEMDS | grep -q $cl_user ||
18121                 error "User $cl_user not found in changelog_users"
18122
18123         printf 'clear:'$cl_user':0' >&3
18124 }
18125 run_test 160j "client can be umounted while its chanangelog is being used"
18126
18127 test_160k() {
18128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18129         remote_mds_nodsh && skip "remote MDS with nodsh"
18130
18131         mkdir -p $DIR/$tdir/1/1
18132
18133         changelog_register || error "changelog_register failed"
18134         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18135
18136         changelog_users $SINGLEMDS | grep -q $cl_user ||
18137                 error "User '$cl_user' not found in changelog_users"
18138 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18139         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18140         rmdir $DIR/$tdir/1/1 & sleep 1
18141         mkdir $DIR/$tdir/2
18142         touch $DIR/$tdir/2/2
18143         rm -rf $DIR/$tdir/2
18144
18145         wait
18146         sleep 4
18147
18148         changelog_dump | grep rmdir || error "rmdir not recorded"
18149 }
18150 run_test 160k "Verify that changelog records are not lost"
18151
18152 # Verifies that a file passed as a parameter has recently had an operation
18153 # performed on it that has generated an MTIME changelog which contains the
18154 # correct parent FID. As files might reside on a different MDT from the
18155 # parent directory in DNE configurations, the FIDs are translated to paths
18156 # before being compared, which should be identical
18157 compare_mtime_changelog() {
18158         local file="${1}"
18159         local mdtidx
18160         local mtime
18161         local cl_fid
18162         local pdir
18163         local dir
18164
18165         mdtidx=$($LFS getstripe --mdt-index $file)
18166         mdtidx=$(printf "%04x" $mdtidx)
18167
18168         # Obtain the parent FID from the MTIME changelog
18169         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18170         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18171
18172         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18173         [ -z "$cl_fid" ] && error "parent FID not present"
18174
18175         # Verify that the path for the parent FID is the same as the path for
18176         # the test directory
18177         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18178
18179         dir=$(dirname $1)
18180
18181         [[ "${pdir%/}" == "$dir" ]] ||
18182                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18183 }
18184
18185 test_160l() {
18186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18187
18188         remote_mds_nodsh && skip "remote MDS with nodsh"
18189         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18190                 skip "Need MDS version at least 2.13.55"
18191
18192         local cl_user
18193
18194         changelog_register || error "changelog_register failed"
18195         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18196
18197         changelog_users $SINGLEMDS | grep -q $cl_user ||
18198                 error "User '$cl_user' not found in changelog_users"
18199
18200         # Clear some types so that MTIME changelogs are generated
18201         changelog_chmask "-CREAT"
18202         changelog_chmask "-CLOSE"
18203
18204         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18205
18206         # Test CL_MTIME during setattr
18207         touch $DIR/$tdir/$tfile
18208         compare_mtime_changelog $DIR/$tdir/$tfile
18209
18210         # Test CL_MTIME during close
18211         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18212         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18213 }
18214 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18215
18216 test_160m() {
18217         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18218         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18219                 skip "Need MDS version at least 2.14.51"
18220         local cl_users
18221         local cl_user1
18222         local cl_user2
18223         local pid1
18224
18225         # Create a user
18226         changelog_register || error "first changelog_register failed"
18227         changelog_register || error "second changelog_register failed"
18228
18229         cl_users=(${CL_USERS[mds1]})
18230         cl_user1="${cl_users[0]}"
18231         cl_user2="${cl_users[1]}"
18232         # generate some changelog records to accumulate on MDT0
18233         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18234         createmany -m $DIR/$tdir/$tfile 50 ||
18235                 error "create $DIR/$tdir/$tfile failed"
18236         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18237         rm -f $DIR/$tdir
18238
18239         # check changelogs have been generated
18240         local nbcl=$(changelog_dump | wc -l)
18241         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18242
18243 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18244         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18245
18246         __changelog_clear mds1 $cl_user1 +10
18247         __changelog_clear mds1 $cl_user2 0 &
18248         pid1=$!
18249         sleep 2
18250         __changelog_clear mds1 $cl_user1 0 ||
18251                 error "fail to cancel record for $cl_user1"
18252         wait $pid1
18253         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18254 }
18255 run_test 160m "Changelog clear race"
18256
18257 test_160n() {
18258         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18259         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18260                 skip "Need MDS version at least 2.14.51"
18261         local cl_users
18262         local cl_user1
18263         local cl_user2
18264         local pid1
18265         local first_rec
18266         local last_rec=0
18267
18268         # Create a user
18269         changelog_register || error "first changelog_register failed"
18270
18271         cl_users=(${CL_USERS[mds1]})
18272         cl_user1="${cl_users[0]}"
18273
18274         # generate some changelog records to accumulate on MDT0
18275         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18276         first_rec=$(changelog_users $SINGLEMDS |
18277                         awk '/^current.index:/ { print $NF }')
18278         while (( last_rec < (( first_rec + 65000)) )); do
18279                 createmany -m $DIR/$tdir/$tfile 10000 ||
18280                         error "create $DIR/$tdir/$tfile failed"
18281
18282                 for i in $(seq 0 10000); do
18283                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18284                                 > /dev/null
18285                 done
18286
18287                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18288                         error "unlinkmany failed unlink"
18289                 last_rec=$(changelog_users $SINGLEMDS |
18290                         awk '/^current.index:/ { print $NF }')
18291                 echo last record $last_rec
18292                 (( last_rec == 0 )) && error "no changelog found"
18293         done
18294
18295 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18296         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18297
18298         __changelog_clear mds1 $cl_user1 0 &
18299         pid1=$!
18300         sleep 2
18301         __changelog_clear mds1 $cl_user1 0 ||
18302                 error "fail to cancel record for $cl_user1"
18303         wait $pid1
18304         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18305 }
18306 run_test 160n "Changelog destroy race"
18307
18308 test_160o() {
18309         local mdt="$(facet_svc $SINGLEMDS)"
18310
18311         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18312         remote_mds_nodsh && skip "remote MDS with nodsh"
18313         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18314                 skip "Need MDS version at least 2.14.52"
18315
18316         changelog_register --user test_160o -m unlnk+close+open ||
18317                 error "changelog_register failed"
18318
18319         do_facet $SINGLEMDS $LCTL --device $mdt \
18320                                 changelog_register -u "Tt3_-#" &&
18321                 error "bad symbols in name should fail"
18322
18323         do_facet $SINGLEMDS $LCTL --device $mdt \
18324                                 changelog_register -u test_160o &&
18325                 error "the same name registration should fail"
18326
18327         do_facet $SINGLEMDS $LCTL --device $mdt \
18328                         changelog_register -u test_160toolongname &&
18329                 error "too long name registration should fail"
18330
18331         changelog_chmask "MARK+HSM"
18332         lctl get_param mdd.*.changelog*mask
18333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18334         changelog_users $SINGLEMDS | grep -q $cl_user ||
18335                 error "User $cl_user not found in changelog_users"
18336         #verify username
18337         echo $cl_user | grep -q test_160o ||
18338                 error "User $cl_user has no specific name 'test160o'"
18339
18340         # change something
18341         changelog_clear 0 || error "changelog_clear failed"
18342         # generate some changelog records to accumulate on MDT0
18343         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18344         touch $DIR/$tdir/$tfile                 # open 1
18345
18346         OPENS=$(changelog_dump | grep -c "OPEN")
18347         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18348
18349         # must be no MKDIR it wasn't set as user mask
18350         MKDIR=$(changelog_dump | grep -c "MKDIR")
18351         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18352
18353         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18354                                 mdd.$mdt.changelog_current_mask -n)
18355         # register maskless user
18356         changelog_register || error "changelog_register failed"
18357         # effective mask should be not changed because it is not minimal
18358         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18359                                 mdd.$mdt.changelog_current_mask -n)
18360         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18361         # set server mask to minimal value
18362         changelog_chmask "MARK"
18363         # check effective mask again, should be treated as DEFMASK now
18364         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18365                                 mdd.$mdt.changelog_current_mask -n)
18366         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18367
18368         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18369                 # set server mask back to some value
18370                 changelog_chmask "CLOSE,UNLNK"
18371                 # check effective mask again, should not remain as DEFMASK
18372                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18373                                 mdd.$mdt.changelog_current_mask -n)
18374                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18375         fi
18376
18377         do_facet $SINGLEMDS $LCTL --device $mdt \
18378                                 changelog_deregister -u test_160o ||
18379                 error "cannot deregister by name"
18380 }
18381 run_test 160o "changelog user name and mask"
18382
18383 test_160p() {
18384         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18385         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18386                 skip "Need MDS version at least 2.14.51"
18387         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18388         local cl_users
18389         local cl_user1
18390         local entry_count
18391
18392         # Create a user
18393         changelog_register || error "first changelog_register failed"
18394
18395         cl_users=(${CL_USERS[mds1]})
18396         cl_user1="${cl_users[0]}"
18397
18398         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18399         createmany -m $DIR/$tdir/$tfile 50 ||
18400                 error "create $DIR/$tdir/$tfile failed"
18401         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18402         rm -rf $DIR/$tdir
18403
18404         # check changelogs have been generated
18405         entry_count=$(changelog_dump | wc -l)
18406         ((entry_count != 0)) || error "no changelog entries found"
18407
18408         # remove changelog_users and check that orphan entries are removed
18409         stop mds1
18410         local dev=$(mdsdevname 1)
18411         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18412         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18413         entry_count=$(changelog_dump | wc -l)
18414         ((entry_count == 0)) ||
18415                 error "found $entry_count changelog entries, expected none"
18416 }
18417 run_test 160p "Changelog orphan cleanup with no users"
18418
18419 test_160q() {
18420         local mdt="$(facet_svc $SINGLEMDS)"
18421         local clu
18422
18423         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18424         remote_mds_nodsh && skip "remote MDS with nodsh"
18425         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18426                 skip "Need MDS version at least 2.14.54"
18427
18428         # set server mask to minimal value like server init does
18429         changelog_chmask "MARK"
18430         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18431                 error "changelog_register failed"
18432         # check effective mask again, should be treated as DEFMASK now
18433         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18434                                 mdd.$mdt.changelog_current_mask -n)
18435         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18436                 error "changelog_deregister failed"
18437         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18438 }
18439 run_test 160q "changelog effective mask is DEFMASK if not set"
18440
18441 test_160s() {
18442         remote_mds_nodsh && skip "remote MDS with nodsh"
18443         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18444                 skip "Need MDS version at least 2.14.55"
18445
18446         local mdts=$(comma_list $(mdts_nodes))
18447
18448         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18449         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18450                                        fail_val=$((24 * 3600 * 10))
18451
18452         # Create a user which is 10 days old
18453         changelog_register || error "first changelog_register failed"
18454         local cl_users
18455         declare -A cl_user1
18456         local i
18457
18458         # generate some changelog records to accumulate on each MDT
18459         # use all_char because created files should be evenly distributed
18460         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18461                 error "test_mkdir $tdir failed"
18462         for ((i = 0; i < MDSCOUNT; i++)); do
18463                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18464                         error "create $DIR/$tdir/d$i.1 failed"
18465         done
18466
18467         # check changelogs have been generated
18468         local nbcl=$(changelog_dump | wc -l)
18469         (( nbcl > 0 )) || error "no changelogs found"
18470
18471         # reduce the max_idle_indexes value to make sure we exceed it
18472         for param in "changelog_max_idle_indexes=2097446912" \
18473                      "changelog_max_idle_time=2592000" \
18474                      "changelog_gc=1" \
18475                      "changelog_min_gc_interval=2"; do
18476                 local MDT0=$(facet_svc $SINGLEMDS)
18477                 local var="${param%=*}"
18478                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18479
18480                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18481                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18482                         error "unable to set mdd.*.$param"
18483         done
18484
18485         local start=$SECONDS
18486         for i in $(seq $MDSCOUNT); do
18487                 cl_users=(${CL_USERS[mds$i]})
18488                 cl_user1[mds$i]="${cl_users[0]}"
18489
18490                 [[ -n "${cl_user1[mds$i]}" ]] ||
18491                         error "mds$i: no user registered"
18492         done
18493
18494         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18495         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18496
18497         # ensure we are past the previous changelog_min_gc_interval set above
18498         local sleep2=$((start + 2 - SECONDS))
18499         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18500
18501         # Generate one more changelog to trigger GC
18502         for ((i = 0; i < MDSCOUNT; i++)); do
18503                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18504                         error "create $DIR/$tdir/d$i.3 failed"
18505         done
18506
18507         # ensure gc thread is done
18508         for node in $(mdts_nodes); do
18509                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18510                         error "$node: GC-thread not done"
18511         done
18512
18513         do_nodes $mdts $LCTL set_param fail_loc=0
18514
18515         for (( i = 1; i <= MDSCOUNT; i++ )); do
18516                 # check cl_user1 is purged
18517                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18518                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18519         done
18520         return 0
18521 }
18522 run_test 160s "changelog garbage collect on idle records * time"
18523
18524 test_160t() {
18525         remote_mds_nodsh && skip "remote MDS with nodsh"
18526         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18527                 skip "Need MDS version at least 2.15.50"
18528
18529         local MDT0=$(facet_svc $SINGLEMDS)
18530         local cl_users
18531         local cl_user1
18532         local cl_user2
18533         local start
18534
18535         changelog_register --user user1 -m all ||
18536                 error "user1 failed to register"
18537
18538         mkdir_on_mdt0 $DIR/$tdir
18539         # create default overstripe to maximize changelog size
18540         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18541         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18542         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18543
18544         # user2 consumes less records so less space
18545         changelog_register --user user2 || error "user2 failed to register"
18546         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18547         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18548
18549         # check changelogs have been generated
18550         local nbcl=$(changelog_dump | wc -l)
18551         (( nbcl > 0 )) || error "no changelogs found"
18552
18553         # reduce the changelog_min_gc_interval to force check
18554         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18555                 local var="${param%=*}"
18556                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18557
18558                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18559                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18560                         error "unable to set mdd.*.$param"
18561         done
18562
18563         start=$SECONDS
18564         cl_users=(${CL_USERS[mds1]})
18565         cl_user1="${cl_users[0]}"
18566         cl_user2="${cl_users[1]}"
18567
18568         [[ -n $cl_user1 ]] ||
18569                 error "mds1: user #1 isn't registered"
18570         [[ -n $cl_user2 ]] ||
18571                 error "mds1: user #2 isn't registered"
18572
18573         # ensure we are past the previous changelog_min_gc_interval set above
18574         local sleep2=$((start + 2 - SECONDS))
18575         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18576
18577         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18578         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18579                         fail_val=$(((llog_size1 + llog_size2) / 2))
18580
18581         # Generate more changelog to trigger GC
18582         createmany -o $DIR/$tdir/u3_ 4 ||
18583                 error "create failed for more files"
18584
18585         # ensure gc thread is done
18586         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18587                 error "mds1: GC-thread not done"
18588
18589         do_facet mds1 $LCTL set_param fail_loc=0
18590
18591         # check cl_user1 is purged
18592         changelog_users mds1 | grep -q "$cl_user1" &&
18593                 error "User $cl_user1 is registered"
18594         # check cl_user2 is not purged
18595         changelog_users mds1 | grep -q "$cl_user2" ||
18596                 error "User $cl_user2 is not registered"
18597 }
18598 run_test 160t "changelog garbage collect on lack of space"
18599
18600 test_161a() {
18601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18602
18603         test_mkdir -c1 $DIR/$tdir
18604         cp /etc/hosts $DIR/$tdir/$tfile
18605         test_mkdir -c1 $DIR/$tdir/foo1
18606         test_mkdir -c1 $DIR/$tdir/foo2
18607         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18608         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18609         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18610         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18611         local FID=$($LFS path2fid $DIR/$tdir/$tfile | 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 $DIR/$tdir/foo2/zachary
18618         # last
18619         rm $DIR/$tdir/foo2/thor
18620         # first
18621         rm $DIR/$tdir/$tfile
18622         # rename
18623         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18624         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18625                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18626         rm $DIR/$tdir/foo2/maggie
18627
18628         # overflow the EA
18629         local longname=$tfile.avg_len_is_thirty_two_
18630         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18631                 error_noexit 'failed to unlink many hardlinks'" EXIT
18632         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18633                 error "failed to hardlink many files"
18634         links=$($LFS fid2path $DIR $FID | wc -l)
18635         echo -n "${links}/1000 links in link EA"
18636         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18637 }
18638 run_test 161a "link ea sanity"
18639
18640 test_161b() {
18641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18642         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18643
18644         local MDTIDX=1
18645         local remote_dir=$DIR/$tdir/remote_dir
18646
18647         mkdir -p $DIR/$tdir
18648         $LFS mkdir -i $MDTIDX $remote_dir ||
18649                 error "create remote directory failed"
18650
18651         cp /etc/hosts $remote_dir/$tfile
18652         mkdir -p $remote_dir/foo1
18653         mkdir -p $remote_dir/foo2
18654         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18655         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18656         ln $remote_dir/$tfile $remote_dir/foo1/luna
18657         ln $remote_dir/$tfile $remote_dir/foo2/thor
18658
18659         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18660                      tr -d ']')
18661         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18662                 $LFS fid2path $DIR $FID
18663                 error "bad link ea"
18664         fi
18665         # middle
18666         rm $remote_dir/foo2/zachary
18667         # last
18668         rm $remote_dir/foo2/thor
18669         # first
18670         rm $remote_dir/$tfile
18671         # rename
18672         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18673         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18674         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18675                 $LFS fid2path $DIR $FID
18676                 error "bad link rename"
18677         fi
18678         rm $remote_dir/foo2/maggie
18679
18680         # overflow the EA
18681         local longname=filename_avg_len_is_thirty_two_
18682         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18683                 error "failed to hardlink many files"
18684         links=$($LFS fid2path $DIR $FID | wc -l)
18685         echo -n "${links}/1000 links in link EA"
18686         [[ ${links} -gt 60 ]] ||
18687                 error "expected at least 60 links in link EA"
18688         unlinkmany $remote_dir/foo2/$longname 1000 ||
18689         error "failed to unlink many hardlinks"
18690 }
18691 run_test 161b "link ea sanity under remote directory"
18692
18693 test_161c() {
18694         remote_mds_nodsh && skip "remote MDS with nodsh"
18695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18696         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18697                 skip "Need MDS version at least 2.1.5"
18698
18699         # define CLF_RENAME_LAST 0x0001
18700         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18701         changelog_register || error "changelog_register failed"
18702
18703         rm -rf $DIR/$tdir
18704         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18705         touch $DIR/$tdir/foo_161c
18706         touch $DIR/$tdir/bar_161c
18707         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18708         changelog_dump | grep RENME | tail -n 5
18709         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18710         changelog_clear 0 || error "changelog_clear failed"
18711         if [ x$flags != "x0x1" ]; then
18712                 error "flag $flags is not 0x1"
18713         fi
18714
18715         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18716         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18717         touch $DIR/$tdir/foo_161c
18718         touch $DIR/$tdir/bar_161c
18719         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18720         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18721         changelog_dump | grep RENME | tail -n 5
18722         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18723         changelog_clear 0 || error "changelog_clear failed"
18724         if [ x$flags != "x0x0" ]; then
18725                 error "flag $flags is not 0x0"
18726         fi
18727         echo "rename overwrite a target having nlink > 1," \
18728                 "changelog record has flags of $flags"
18729
18730         # rename doesn't overwrite a target (changelog flag 0x0)
18731         touch $DIR/$tdir/foo_161c
18732         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18733         changelog_dump | grep RENME | tail -n 5
18734         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18735         changelog_clear 0 || error "changelog_clear failed"
18736         if [ x$flags != "x0x0" ]; then
18737                 error "flag $flags is not 0x0"
18738         fi
18739         echo "rename doesn't overwrite a target," \
18740                 "changelog record has flags of $flags"
18741
18742         # define CLF_UNLINK_LAST 0x0001
18743         # unlink a file having nlink = 1 (changelog flag 0x1)
18744         rm -f $DIR/$tdir/foo2_161c
18745         changelog_dump | grep UNLNK | tail -n 5
18746         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18747         changelog_clear 0 || error "changelog_clear failed"
18748         if [ x$flags != "x0x1" ]; then
18749                 error "flag $flags is not 0x1"
18750         fi
18751         echo "unlink a file having nlink = 1," \
18752                 "changelog record has flags of $flags"
18753
18754         # unlink a file having nlink > 1 (changelog flag 0x0)
18755         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18756         rm -f $DIR/$tdir/foobar_161c
18757         changelog_dump | grep UNLNK | tail -n 5
18758         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18759         changelog_clear 0 || error "changelog_clear failed"
18760         if [ x$flags != "x0x0" ]; then
18761                 error "flag $flags is not 0x0"
18762         fi
18763         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18764 }
18765 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18766
18767 test_161d() {
18768         remote_mds_nodsh && skip "remote MDS with nodsh"
18769         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18770
18771         local pid
18772         local fid
18773
18774         changelog_register || error "changelog_register failed"
18775
18776         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18777         # interfer with $MOUNT/.lustre/fid/ access
18778         mkdir $DIR/$tdir
18779         [[ $? -eq 0 ]] || error "mkdir failed"
18780
18781         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18782         $LCTL set_param fail_loc=0x8000140c
18783         # 5s pause
18784         $LCTL set_param fail_val=5
18785
18786         # create file
18787         echo foofoo > $DIR/$tdir/$tfile &
18788         pid=$!
18789
18790         # wait for create to be delayed
18791         sleep 2
18792
18793         ps -p $pid
18794         [[ $? -eq 0 ]] || error "create should be blocked"
18795
18796         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18797         stack_trap "rm -f $tempfile"
18798         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18799         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18800         # some delay may occur during ChangeLog publishing and file read just
18801         # above, that could allow file write to happen finally
18802         [[ -s $tempfile ]] && echo "file should be empty"
18803
18804         $LCTL set_param fail_loc=0
18805
18806         wait $pid
18807         [[ $? -eq 0 ]] || error "create failed"
18808 }
18809 run_test 161d "create with concurrent .lustre/fid access"
18810
18811 check_path() {
18812         local expected="$1"
18813         shift
18814         local fid="$2"
18815
18816         local path
18817         path=$($LFS fid2path "$@")
18818         local rc=$?
18819
18820         if [ $rc -ne 0 ]; then
18821                 error "path looked up of '$expected' failed: rc=$rc"
18822         elif [ "$path" != "$expected" ]; then
18823                 error "path looked up '$path' instead of '$expected'"
18824         else
18825                 echo "FID '$fid' resolves to path '$path' as expected"
18826         fi
18827 }
18828
18829 test_162a() { # was test_162
18830         test_mkdir -p -c1 $DIR/$tdir/d2
18831         touch $DIR/$tdir/d2/$tfile
18832         touch $DIR/$tdir/d2/x1
18833         touch $DIR/$tdir/d2/x2
18834         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18835         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18836         # regular file
18837         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18838         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18839
18840         # softlink
18841         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18842         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18843         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18844
18845         # softlink to wrong file
18846         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18847         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18848         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18849
18850         # hardlink
18851         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18852         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18853         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18854         # fid2path dir/fsname should both work
18855         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18856         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18857
18858         # hardlink count: check that there are 2 links
18859         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18860         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18861
18862         # hardlink indexing: remove the first link
18863         rm $DIR/$tdir/d2/p/q/r/hlink
18864         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18865 }
18866 run_test 162a "path lookup sanity"
18867
18868 test_162b() {
18869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18871
18872         mkdir $DIR/$tdir
18873         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18874                                 error "create striped dir failed"
18875
18876         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18877                                         tail -n 1 | awk '{print $2}')
18878         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18879
18880         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18881         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18882
18883         # regular file
18884         for ((i=0;i<5;i++)); do
18885                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18886                         error "get fid for f$i failed"
18887                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18888
18889                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18890                         error "get fid for d$i failed"
18891                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18892         done
18893
18894         return 0
18895 }
18896 run_test 162b "striped directory path lookup sanity"
18897
18898 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18899 test_162c() {
18900         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18901                 skip "Need MDS version at least 2.7.51"
18902
18903         local lpath=$tdir.local
18904         local rpath=$tdir.remote
18905
18906         test_mkdir $DIR/$lpath
18907         test_mkdir $DIR/$rpath
18908
18909         for ((i = 0; i <= 101; i++)); do
18910                 lpath="$lpath/$i"
18911                 mkdir $DIR/$lpath
18912                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18913                         error "get fid for local directory $DIR/$lpath failed"
18914                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18915
18916                 rpath="$rpath/$i"
18917                 test_mkdir $DIR/$rpath
18918                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18919                         error "get fid for remote directory $DIR/$rpath failed"
18920                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18921         done
18922
18923         return 0
18924 }
18925 run_test 162c "fid2path works with paths 100 or more directories deep"
18926
18927 oalr_event_count() {
18928         local event="${1}"
18929         local trace="${2}"
18930
18931         awk -v name="${FSNAME}-OST0000" \
18932             -v event="${event}" \
18933             '$1 == "TRACE" && $2 == event && $3 == name' \
18934             "${trace}" |
18935         wc -l
18936 }
18937
18938 oalr_expect_event_count() {
18939         local event="${1}"
18940         local trace="${2}"
18941         local expect="${3}"
18942         local count
18943
18944         count=$(oalr_event_count "${event}" "${trace}")
18945         if ((count == expect)); then
18946                 return 0
18947         fi
18948
18949         error_noexit "${event} event count was '${count}', expected ${expect}"
18950         cat "${trace}" >&2
18951         exit 1
18952 }
18953
18954 cleanup_165() {
18955         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18956         stop ost1
18957         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18958 }
18959
18960 setup_165() {
18961         sync # Flush previous IOs so we can count log entries.
18962         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18963         stack_trap cleanup_165 EXIT
18964 }
18965
18966 test_165a() {
18967         local trace="/tmp/${tfile}.trace"
18968         local rc
18969         local count
18970
18971         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18972                 skip "OFD access log unsupported"
18973
18974         setup_165
18975         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18976         sleep 5
18977
18978         do_facet ost1 ofd_access_log_reader --list
18979         stop ost1
18980
18981         do_facet ost1 killall -TERM ofd_access_log_reader
18982         wait
18983         rc=$?
18984
18985         if ((rc != 0)); then
18986                 error "ofd_access_log_reader exited with rc = '${rc}'"
18987         fi
18988
18989         # Parse trace file for discovery events:
18990         oalr_expect_event_count alr_log_add "${trace}" 1
18991         oalr_expect_event_count alr_log_eof "${trace}" 1
18992         oalr_expect_event_count alr_log_free "${trace}" 1
18993 }
18994 run_test 165a "ofd access log discovery"
18995
18996 test_165b() {
18997         local trace="/tmp/${tfile}.trace"
18998         local file="${DIR}/${tfile}"
18999         local pfid1
19000         local pfid2
19001         local -a entry
19002         local rc
19003         local count
19004         local size
19005         local flags
19006
19007         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19008                 skip "OFD access log unsupported"
19009
19010         setup_165
19011         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19012         sleep 5
19013
19014         do_facet ost1 ofd_access_log_reader --list
19015
19016         lfs setstripe -c 1 -i 0 "${file}"
19017         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19018                 error "cannot create '${file}'"
19019
19020         sleep 5
19021         do_facet ost1 killall -TERM ofd_access_log_reader
19022         wait
19023         rc=$?
19024
19025         if ((rc != 0)); then
19026                 error "ofd_access_log_reader exited with rc = '${rc}'"
19027         fi
19028
19029         oalr_expect_event_count alr_log_entry "${trace}" 1
19030
19031         pfid1=$($LFS path2fid "${file}")
19032
19033         # 1     2             3   4    5     6   7    8    9     10
19034         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19035         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19036
19037         echo "entry = '${entry[*]}'" >&2
19038
19039         pfid2=${entry[4]}
19040         if [[ "${pfid1}" != "${pfid2}" ]]; then
19041                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19042         fi
19043
19044         size=${entry[8]}
19045         if ((size != 1048576)); then
19046                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19047         fi
19048
19049         flags=${entry[10]}
19050         if [[ "${flags}" != "w" ]]; then
19051                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19052         fi
19053
19054         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19055         sleep 5
19056
19057         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19058                 error "cannot read '${file}'"
19059         sleep 5
19060
19061         do_facet ost1 killall -TERM ofd_access_log_reader
19062         wait
19063         rc=$?
19064
19065         if ((rc != 0)); then
19066                 error "ofd_access_log_reader exited with rc = '${rc}'"
19067         fi
19068
19069         oalr_expect_event_count alr_log_entry "${trace}" 1
19070
19071         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19072         echo "entry = '${entry[*]}'" >&2
19073
19074         pfid2=${entry[4]}
19075         if [[ "${pfid1}" != "${pfid2}" ]]; then
19076                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19077         fi
19078
19079         size=${entry[8]}
19080         if ((size != 524288)); then
19081                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19082         fi
19083
19084         flags=${entry[10]}
19085         if [[ "${flags}" != "r" ]]; then
19086                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19087         fi
19088 }
19089 run_test 165b "ofd access log entries are produced and consumed"
19090
19091 test_165c() {
19092         local trace="/tmp/${tfile}.trace"
19093         local file="${DIR}/${tdir}/${tfile}"
19094
19095         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19096                 skip "OFD access log unsupported"
19097
19098         test_mkdir "${DIR}/${tdir}"
19099
19100         setup_165
19101         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19102         sleep 5
19103
19104         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19105
19106         # 4096 / 64 = 64. Create twice as many entries.
19107         for ((i = 0; i < 128; i++)); do
19108                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19109                         error "cannot create file"
19110         done
19111
19112         sync
19113
19114         do_facet ost1 killall -TERM ofd_access_log_reader
19115         wait
19116         rc=$?
19117         if ((rc != 0)); then
19118                 error "ofd_access_log_reader exited with rc = '${rc}'"
19119         fi
19120
19121         unlinkmany  "${file}-%d" 128
19122 }
19123 run_test 165c "full ofd access logs do not block IOs"
19124
19125 oal_get_read_count() {
19126         local stats="$1"
19127
19128         # STATS lustre-OST0001 alr_read_count 1
19129
19130         do_facet ost1 cat "${stats}" |
19131         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19132              END { print count; }'
19133 }
19134
19135 oal_expect_read_count() {
19136         local stats="$1"
19137         local count
19138         local expect="$2"
19139
19140         # Ask ofd_access_log_reader to write stats.
19141         do_facet ost1 killall -USR1 ofd_access_log_reader
19142
19143         # Allow some time for things to happen.
19144         sleep 1
19145
19146         count=$(oal_get_read_count "${stats}")
19147         if ((count == expect)); then
19148                 return 0
19149         fi
19150
19151         error_noexit "bad read count, got ${count}, expected ${expect}"
19152         do_facet ost1 cat "${stats}" >&2
19153         exit 1
19154 }
19155
19156 test_165d() {
19157         local stats="/tmp/${tfile}.stats"
19158         local file="${DIR}/${tdir}/${tfile}"
19159         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19160
19161         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19162                 skip "OFD access log unsupported"
19163
19164         test_mkdir "${DIR}/${tdir}"
19165
19166         setup_165
19167         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19168         sleep 5
19169
19170         lfs setstripe -c 1 -i 0 "${file}"
19171
19172         do_facet ost1 lctl set_param "${param}=rw"
19173         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19174                 error "cannot create '${file}'"
19175         oal_expect_read_count "${stats}" 1
19176
19177         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19178                 error "cannot read '${file}'"
19179         oal_expect_read_count "${stats}" 2
19180
19181         do_facet ost1 lctl set_param "${param}=r"
19182         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19183                 error "cannot create '${file}'"
19184         oal_expect_read_count "${stats}" 2
19185
19186         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19187                 error "cannot read '${file}'"
19188         oal_expect_read_count "${stats}" 3
19189
19190         do_facet ost1 lctl set_param "${param}=w"
19191         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19192                 error "cannot create '${file}'"
19193         oal_expect_read_count "${stats}" 4
19194
19195         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19196                 error "cannot read '${file}'"
19197         oal_expect_read_count "${stats}" 4
19198
19199         do_facet ost1 lctl set_param "${param}=0"
19200         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19201                 error "cannot create '${file}'"
19202         oal_expect_read_count "${stats}" 4
19203
19204         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19205                 error "cannot read '${file}'"
19206         oal_expect_read_count "${stats}" 4
19207
19208         do_facet ost1 killall -TERM ofd_access_log_reader
19209         wait
19210         rc=$?
19211         if ((rc != 0)); then
19212                 error "ofd_access_log_reader exited with rc = '${rc}'"
19213         fi
19214 }
19215 run_test 165d "ofd_access_log mask works"
19216
19217 test_165e() {
19218         local stats="/tmp/${tfile}.stats"
19219         local file0="${DIR}/${tdir}-0/${tfile}"
19220         local file1="${DIR}/${tdir}-1/${tfile}"
19221
19222         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19223                 skip "OFD access log unsupported"
19224
19225         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19226
19227         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19228         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19229
19230         lfs setstripe -c 1 -i 0 "${file0}"
19231         lfs setstripe -c 1 -i 0 "${file1}"
19232
19233         setup_165
19234         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19235         sleep 5
19236
19237         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19238                 error "cannot create '${file0}'"
19239         sync
19240         oal_expect_read_count "${stats}" 0
19241
19242         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19243                 error "cannot create '${file1}'"
19244         sync
19245         oal_expect_read_count "${stats}" 1
19246
19247         do_facet ost1 killall -TERM ofd_access_log_reader
19248         wait
19249         rc=$?
19250         if ((rc != 0)); then
19251                 error "ofd_access_log_reader exited with rc = '${rc}'"
19252         fi
19253 }
19254 run_test 165e "ofd_access_log MDT index filter works"
19255
19256 test_165f() {
19257         local trace="/tmp/${tfile}.trace"
19258         local rc
19259         local count
19260
19261         setup_165
19262         do_facet ost1 timeout 60 ofd_access_log_reader \
19263                 --exit-on-close --debug=- --trace=- > "${trace}" &
19264         sleep 5
19265         stop ost1
19266
19267         wait
19268         rc=$?
19269
19270         if ((rc != 0)); then
19271                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19272                 cat "${trace}"
19273                 exit 1
19274         fi
19275 }
19276 run_test 165f "ofd_access_log_reader --exit-on-close works"
19277
19278 test_169() {
19279         # do directio so as not to populate the page cache
19280         log "creating a 10 Mb file"
19281         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19282                 error "multiop failed while creating a file"
19283         log "starting reads"
19284         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19285         log "truncating the file"
19286         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19287                 error "multiop failed while truncating the file"
19288         log "killing dd"
19289         kill %+ || true # reads might have finished
19290         echo "wait until dd is finished"
19291         wait
19292         log "removing the temporary file"
19293         rm -rf $DIR/$tfile || error "tmp file removal failed"
19294 }
19295 run_test 169 "parallel read and truncate should not deadlock"
19296
19297 test_170() {
19298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19299
19300         $LCTL clear     # bug 18514
19301         $LCTL debug_daemon start $TMP/${tfile}_log_good
19302         touch $DIR/$tfile
19303         $LCTL debug_daemon stop
19304         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19305                 error "sed failed to read log_good"
19306
19307         $LCTL debug_daemon start $TMP/${tfile}_log_good
19308         rm -rf $DIR/$tfile
19309         $LCTL debug_daemon stop
19310
19311         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19312                error "lctl df log_bad failed"
19313
19314         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19315         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19316
19317         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19318         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19319
19320         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19321                 error "bad_line good_line1 good_line2 are empty"
19322
19323         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19324         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19325         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19326
19327         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19328         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19329         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19330
19331         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19332                 error "bad_line_new good_line_new are empty"
19333
19334         local expected_good=$((good_line1 + good_line2*2))
19335
19336         rm -f $TMP/${tfile}*
19337         # LU-231, short malformed line may not be counted into bad lines
19338         if [ $bad_line -ne $bad_line_new ] &&
19339                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19340                 error "expected $bad_line bad lines, but got $bad_line_new"
19341                 return 1
19342         fi
19343
19344         if [ $expected_good -ne $good_line_new ]; then
19345                 error "expected $expected_good good lines, but got $good_line_new"
19346                 return 2
19347         fi
19348         true
19349 }
19350 run_test 170 "test lctl df to handle corrupted log ====================="
19351
19352 test_171() { # bug20592
19353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19354
19355         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19356         $LCTL set_param fail_loc=0x50e
19357         $LCTL set_param fail_val=3000
19358         multiop_bg_pause $DIR/$tfile O_s || true
19359         local MULTIPID=$!
19360         kill -USR1 $MULTIPID
19361         # cause log dump
19362         sleep 3
19363         wait $MULTIPID
19364         if dmesg | grep "recursive fault"; then
19365                 error "caught a recursive fault"
19366         fi
19367         $LCTL set_param fail_loc=0
19368         true
19369 }
19370 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19371
19372 test_172() {
19373
19374         #define OBD_FAIL_OBD_CLEANUP  0x60e
19375         $LCTL set_param fail_loc=0x60e
19376         umount $MOUNT || error "umount $MOUNT failed"
19377         stack_trap "mount_client $MOUNT"
19378
19379         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19380                 error "no client OBDs are remained"
19381
19382         $LCTL dl | while read devno state type name foo; do
19383                 case $type in
19384                 lov|osc|lmv|mdc)
19385                         $LCTL --device $name cleanup
19386                         $LCTL --device $name detach
19387                         ;;
19388                 *)
19389                         # skip server devices
19390                         ;;
19391                 esac
19392         done
19393
19394         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19395                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19396                 error "some client OBDs are still remained"
19397         fi
19398
19399 }
19400 run_test 172 "manual device removal with lctl cleanup/detach ======"
19401
19402 # it would be good to share it with obdfilter-survey/iokit-libecho code
19403 setup_obdecho_osc () {
19404         local rc=0
19405         local ost_nid=$1
19406         local obdfilter_name=$2
19407         echo "Creating new osc for $obdfilter_name on $ost_nid"
19408         # make sure we can find loopback nid
19409         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19410
19411         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19412                            ${obdfilter_name}_osc_UUID || rc=2; }
19413         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19414                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19415         return $rc
19416 }
19417
19418 cleanup_obdecho_osc () {
19419         local obdfilter_name=$1
19420         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19421         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19422         return 0
19423 }
19424
19425 obdecho_test() {
19426         local OBD=$1
19427         local node=$2
19428         local pages=${3:-64}
19429         local rc=0
19430         local id
19431
19432         local count=10
19433         local obd_size=$(get_obd_size $node $OBD)
19434         local page_size=$(get_page_size $node)
19435         if [[ -n "$obd_size" ]]; then
19436                 local new_count=$((obd_size / (pages * page_size / 1024)))
19437                 [[ $new_count -ge $count ]] || count=$new_count
19438         fi
19439
19440         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19441         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19442                            rc=2; }
19443         if [ $rc -eq 0 ]; then
19444             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19445             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19446         fi
19447         echo "New object id is $id"
19448         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19449                            rc=4; }
19450         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19451                            "test_brw $count w v $pages $id" || rc=4; }
19452         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19453                            rc=4; }
19454         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19455                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19456         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19457                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19458         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19459         return $rc
19460 }
19461
19462 test_180a() {
19463         skip "obdecho on osc is no longer supported"
19464 }
19465 run_test 180a "test obdecho on osc"
19466
19467 test_180b() {
19468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19469         remote_ost_nodsh && skip "remote OST with nodsh"
19470
19471         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19472                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19473                 error "failed to load module obdecho"
19474
19475         local target=$(do_facet ost1 $LCTL dl |
19476                        awk '/obdfilter/ { print $4; exit; }')
19477
19478         if [ -n "$target" ]; then
19479                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19480         else
19481                 do_facet ost1 $LCTL dl
19482                 error "there is no obdfilter target on ost1"
19483         fi
19484 }
19485 run_test 180b "test obdecho directly on obdfilter"
19486
19487 test_180c() { # LU-2598
19488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19489         remote_ost_nodsh && skip "remote OST with nodsh"
19490         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19491                 skip "Need MDS version at least 2.4.0"
19492
19493         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19494                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19495                 error "failed to load module obdecho"
19496
19497         local target=$(do_facet ost1 $LCTL dl |
19498                        awk '/obdfilter/ { print $4; exit; }')
19499
19500         if [ -n "$target" ]; then
19501                 local pages=16384 # 64MB bulk I/O RPC size
19502
19503                 obdecho_test "$target" ost1 "$pages" ||
19504                         error "obdecho_test with pages=$pages failed with $?"
19505         else
19506                 do_facet ost1 $LCTL dl
19507                 error "there is no obdfilter target on ost1"
19508         fi
19509 }
19510 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19511
19512 test_181() { # bug 22177
19513         test_mkdir $DIR/$tdir
19514         # create enough files to index the directory
19515         createmany -o $DIR/$tdir/foobar 4000
19516         # print attributes for debug purpose
19517         lsattr -d .
19518         # open dir
19519         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19520         MULTIPID=$!
19521         # remove the files & current working dir
19522         unlinkmany $DIR/$tdir/foobar 4000
19523         rmdir $DIR/$tdir
19524         kill -USR1 $MULTIPID
19525         wait $MULTIPID
19526         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19527         return 0
19528 }
19529 run_test 181 "Test open-unlinked dir ========================"
19530
19531 test_182a() {
19532         local fcount=1000
19533         local tcount=10
19534
19535         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19536
19537         $LCTL set_param mdc.*.rpc_stats=clear
19538
19539         for (( i = 0; i < $tcount; i++ )) ; do
19540                 mkdir $DIR/$tdir/$i
19541         done
19542
19543         for (( i = 0; i < $tcount; i++ )) ; do
19544                 createmany -o $DIR/$tdir/$i/f- $fcount &
19545         done
19546         wait
19547
19548         for (( i = 0; i < $tcount; i++ )) ; do
19549                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19550         done
19551         wait
19552
19553         $LCTL get_param mdc.*.rpc_stats
19554
19555         rm -rf $DIR/$tdir
19556 }
19557 run_test 182a "Test parallel modify metadata operations from mdc"
19558
19559 test_182b() {
19560         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19562         local dcount=1000
19563         local tcount=10
19564         local stime
19565         local etime
19566         local delta
19567
19568         do_facet mds1 $LCTL list_param \
19569                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19570                 skip "MDS lacks parallel RPC handling"
19571
19572         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19573
19574         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19575                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19576
19577         stime=$(date +%s)
19578         createmany -i 0 -d $DIR/$tdir/t- $tcount
19579
19580         for (( i = 0; i < $tcount; i++ )) ; do
19581                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19582         done
19583         wait
19584         etime=$(date +%s)
19585         delta=$((etime - stime))
19586         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19587
19588         stime=$(date +%s)
19589         for (( i = 0; i < $tcount; i++ )) ; do
19590                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19591         done
19592         wait
19593         etime=$(date +%s)
19594         delta=$((etime - stime))
19595         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19596
19597         rm -rf $DIR/$tdir
19598
19599         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19600
19601         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19602
19603         stime=$(date +%s)
19604         createmany -i 0 -d $DIR/$tdir/t- $tcount
19605
19606         for (( i = 0; i < $tcount; i++ )) ; do
19607                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19608         done
19609         wait
19610         etime=$(date +%s)
19611         delta=$((etime - stime))
19612         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19613
19614         stime=$(date +%s)
19615         for (( i = 0; i < $tcount; i++ )) ; do
19616                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19617         done
19618         wait
19619         etime=$(date +%s)
19620         delta=$((etime - stime))
19621         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19622
19623         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19624 }
19625 run_test 182b "Test parallel modify metadata operations from osp"
19626
19627 test_183() { # LU-2275
19628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19629         remote_mds_nodsh && skip "remote MDS with nodsh"
19630         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19631                 skip "Need MDS version at least 2.3.56"
19632
19633         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19634         echo aaa > $DIR/$tdir/$tfile
19635
19636 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19637         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19638
19639         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19640         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19641
19642         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19643
19644         # Flush negative dentry cache
19645         touch $DIR/$tdir/$tfile
19646
19647         # We are not checking for any leaked references here, they'll
19648         # become evident next time we do cleanup with module unload.
19649         rm -rf $DIR/$tdir
19650 }
19651 run_test 183 "No crash or request leak in case of strange dispositions ========"
19652
19653 # test suite 184 is for LU-2016, LU-2017
19654 test_184a() {
19655         check_swap_layouts_support
19656
19657         dir0=$DIR/$tdir/$testnum
19658         test_mkdir -p -c1 $dir0
19659         ref1=/etc/passwd
19660         ref2=/etc/group
19661         file1=$dir0/f1
19662         file2=$dir0/f2
19663         $LFS setstripe -c1 $file1
19664         cp $ref1 $file1
19665         $LFS setstripe -c2 $file2
19666         cp $ref2 $file2
19667         gen1=$($LFS getstripe -g $file1)
19668         gen2=$($LFS getstripe -g $file2)
19669
19670         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19671         gen=$($LFS getstripe -g $file1)
19672         [[ $gen1 != $gen ]] ||
19673                 error "Layout generation on $file1 does not change"
19674         gen=$($LFS getstripe -g $file2)
19675         [[ $gen2 != $gen ]] ||
19676                 error "Layout generation on $file2 does not change"
19677
19678         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19679         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19680
19681         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19682 }
19683 run_test 184a "Basic layout swap"
19684
19685 test_184b() {
19686         check_swap_layouts_support
19687
19688         dir0=$DIR/$tdir/$testnum
19689         mkdir -p $dir0 || error "creating dir $dir0"
19690         file1=$dir0/f1
19691         file2=$dir0/f2
19692         file3=$dir0/f3
19693         dir1=$dir0/d1
19694         dir2=$dir0/d2
19695         mkdir $dir1 $dir2
19696         $LFS setstripe -c1 $file1
19697         $LFS setstripe -c2 $file2
19698         $LFS setstripe -c1 $file3
19699         chown $RUNAS_ID $file3
19700         gen1=$($LFS getstripe -g $file1)
19701         gen2=$($LFS getstripe -g $file2)
19702
19703         $LFS swap_layouts $dir1 $dir2 &&
19704                 error "swap of directories layouts should fail"
19705         $LFS swap_layouts $dir1 $file1 &&
19706                 error "swap of directory and file layouts should fail"
19707         $RUNAS $LFS swap_layouts $file1 $file2 &&
19708                 error "swap of file we cannot write should fail"
19709         $LFS swap_layouts $file1 $file3 &&
19710                 error "swap of file with different owner should fail"
19711         /bin/true # to clear error code
19712 }
19713 run_test 184b "Forbidden layout swap (will generate errors)"
19714
19715 test_184c() {
19716         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19717         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19718         check_swap_layouts_support
19719         check_swap_layout_no_dom $DIR
19720
19721         local dir0=$DIR/$tdir/$testnum
19722         mkdir -p $dir0 || error "creating dir $dir0"
19723
19724         local ref1=$dir0/ref1
19725         local ref2=$dir0/ref2
19726         local file1=$dir0/file1
19727         local file2=$dir0/file2
19728         # create a file large enough for the concurrent test
19729         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19730         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19731         echo "ref file size: ref1($(stat -c %s $ref1))," \
19732              "ref2($(stat -c %s $ref2))"
19733
19734         cp $ref2 $file2
19735         dd if=$ref1 of=$file1 bs=16k &
19736         local DD_PID=$!
19737
19738         # Make sure dd starts to copy file, but wait at most 5 seconds
19739         local loops=0
19740         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19741
19742         $LFS swap_layouts $file1 $file2
19743         local rc=$?
19744         wait $DD_PID
19745         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19746         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19747
19748         # how many bytes copied before swapping layout
19749         local copied=$(stat -c %s $file2)
19750         local remaining=$(stat -c %s $ref1)
19751         remaining=$((remaining - copied))
19752         echo "Copied $copied bytes before swapping layout..."
19753
19754         cmp -n $copied $file1 $ref2 | grep differ &&
19755                 error "Content mismatch [0, $copied) of ref2 and file1"
19756         cmp -n $copied $file2 $ref1 ||
19757                 error "Content mismatch [0, $copied) of ref1 and file2"
19758         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19759                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19760
19761         # clean up
19762         rm -f $ref1 $ref2 $file1 $file2
19763 }
19764 run_test 184c "Concurrent write and layout swap"
19765
19766 test_184d() {
19767         check_swap_layouts_support
19768         check_swap_layout_no_dom $DIR
19769         [ -z "$(which getfattr 2>/dev/null)" ] &&
19770                 skip_env "no getfattr command"
19771
19772         local file1=$DIR/$tdir/$tfile-1
19773         local file2=$DIR/$tdir/$tfile-2
19774         local file3=$DIR/$tdir/$tfile-3
19775         local lovea1
19776         local lovea2
19777
19778         mkdir -p $DIR/$tdir
19779         touch $file1 || error "create $file1 failed"
19780         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19781                 error "create $file2 failed"
19782         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19783                 error "create $file3 failed"
19784         lovea1=$(get_layout_param $file1)
19785
19786         $LFS swap_layouts $file2 $file3 ||
19787                 error "swap $file2 $file3 layouts failed"
19788         $LFS swap_layouts $file1 $file2 ||
19789                 error "swap $file1 $file2 layouts failed"
19790
19791         lovea2=$(get_layout_param $file2)
19792         echo "$lovea1"
19793         echo "$lovea2"
19794         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19795
19796         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19797         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19798 }
19799 run_test 184d "allow stripeless layouts swap"
19800
19801 test_184e() {
19802         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19803                 skip "Need MDS version at least 2.6.94"
19804         check_swap_layouts_support
19805         check_swap_layout_no_dom $DIR
19806         [ -z "$(which getfattr 2>/dev/null)" ] &&
19807                 skip_env "no getfattr command"
19808
19809         local file1=$DIR/$tdir/$tfile-1
19810         local file2=$DIR/$tdir/$tfile-2
19811         local file3=$DIR/$tdir/$tfile-3
19812         local lovea
19813
19814         mkdir -p $DIR/$tdir
19815         touch $file1 || error "create $file1 failed"
19816         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19817                 error "create $file2 failed"
19818         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19819                 error "create $file3 failed"
19820
19821         $LFS swap_layouts $file1 $file2 ||
19822                 error "swap $file1 $file2 layouts failed"
19823
19824         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19825         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19826
19827         echo 123 > $file1 || error "Should be able to write into $file1"
19828
19829         $LFS swap_layouts $file1 $file3 ||
19830                 error "swap $file1 $file3 layouts failed"
19831
19832         echo 123 > $file1 || error "Should be able to write into $file1"
19833
19834         rm -rf $file1 $file2 $file3
19835 }
19836 run_test 184e "Recreate layout after stripeless layout swaps"
19837
19838 test_184f() {
19839         # Create a file with name longer than sizeof(struct stat) ==
19840         # 144 to see if we can get chars from the file name to appear
19841         # in the returned striping. Note that 'f' == 0x66.
19842         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19843
19844         mkdir -p $DIR/$tdir
19845         mcreate $DIR/$tdir/$file
19846         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19847                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19848         fi
19849 }
19850 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19851
19852 test_185() { # LU-2441
19853         # LU-3553 - no volatile file support in old servers
19854         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19855                 skip "Need MDS version at least 2.3.60"
19856
19857         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19858         touch $DIR/$tdir/spoo
19859         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19860         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19861                 error "cannot create/write a volatile file"
19862         [ "$FILESET" == "" ] &&
19863         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19864                 error "FID is still valid after close"
19865
19866         multiop_bg_pause $DIR/$tdir Vw4096_c
19867         local multi_pid=$!
19868
19869         local OLD_IFS=$IFS
19870         IFS=":"
19871         local fidv=($fid)
19872         IFS=$OLD_IFS
19873         # assume that the next FID for this client is sequential, since stdout
19874         # is unfortunately eaten by multiop_bg_pause
19875         local n=$((${fidv[1]} + 1))
19876         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19877         if [ "$FILESET" == "" ]; then
19878                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19879                         error "FID is missing before close"
19880         fi
19881         kill -USR1 $multi_pid
19882         # 1 second delay, so if mtime change we will see it
19883         sleep 1
19884         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19885         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19886 }
19887 run_test 185 "Volatile file support"
19888
19889 function create_check_volatile() {
19890         local idx=$1
19891         local tgt
19892
19893         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19894         local PID=$!
19895         sleep 1
19896         local FID=$(cat /tmp/${tfile}.fid)
19897         [ "$FID" == "" ] && error "can't get FID for volatile"
19898         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19899         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19900         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19901         kill -USR1 $PID
19902         wait
19903         sleep 1
19904         cancel_lru_locks mdc # flush opencache
19905         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19906         return 0
19907 }
19908
19909 test_185a(){
19910         # LU-12516 - volatile creation via .lustre
19911         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19912                 skip "Need MDS version at least 2.3.55"
19913
19914         create_check_volatile 0
19915         [ $MDSCOUNT -lt 2 ] && return 0
19916
19917         # DNE case
19918         create_check_volatile 1
19919
19920         return 0
19921 }
19922 run_test 185a "Volatile file creation in .lustre/fid/"
19923
19924 test_187a() {
19925         remote_mds_nodsh && skip "remote MDS with nodsh"
19926         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19927                 skip "Need MDS version at least 2.3.0"
19928
19929         local dir0=$DIR/$tdir/$testnum
19930         mkdir -p $dir0 || error "creating dir $dir0"
19931
19932         local file=$dir0/file1
19933         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19934         stack_trap "rm -f $file"
19935         local dv1=$($LFS data_version $file)
19936         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19937         local dv2=$($LFS data_version $file)
19938         [[ $dv1 != $dv2 ]] ||
19939                 error "data version did not change on write $dv1 == $dv2"
19940 }
19941 run_test 187a "Test data version change"
19942
19943 test_187b() {
19944         remote_mds_nodsh && skip "remote MDS with nodsh"
19945         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19946                 skip "Need MDS version at least 2.3.0"
19947
19948         local dir0=$DIR/$tdir/$testnum
19949         mkdir -p $dir0 || error "creating dir $dir0"
19950
19951         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19952         [[ ${DV[0]} != ${DV[1]} ]] ||
19953                 error "data version did not change on write"\
19954                       " ${DV[0]} == ${DV[1]}"
19955
19956         # clean up
19957         rm -f $file1
19958 }
19959 run_test 187b "Test data version change on volatile file"
19960
19961 test_200() {
19962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19963         remote_mgs_nodsh && skip "remote MGS with nodsh"
19964         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19965
19966         local POOL=${POOL:-cea1}
19967         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19968         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19969         # Pool OST targets
19970         local first_ost=0
19971         local last_ost=$(($OSTCOUNT - 1))
19972         local ost_step=2
19973         local ost_list=$(seq $first_ost $ost_step $last_ost)
19974         local ost_range="$first_ost $last_ost $ost_step"
19975         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19976         local file_dir=$POOL_ROOT/file_tst
19977         local subdir=$test_path/subdir
19978         local rc=0
19979
19980         while : ; do
19981                 # former test_200a test_200b
19982                 pool_add $POOL                          || { rc=$? ; break; }
19983                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19984                 # former test_200c test_200d
19985                 mkdir -p $test_path
19986                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19987                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19988                 mkdir -p $subdir
19989                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19990                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19991                                                         || { rc=$? ; break; }
19992                 # former test_200e test_200f
19993                 local files=$((OSTCOUNT*3))
19994                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19995                                                         || { rc=$? ; break; }
19996                 pool_create_files $POOL $file_dir $files "$ost_list" \
19997                                                         || { rc=$? ; break; }
19998                 # former test_200g test_200h
19999                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20000                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20001
20002                 # former test_201a test_201b test_201c
20003                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20004
20005                 local f=$test_path/$tfile
20006                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20007                 pool_remove $POOL $f                    || { rc=$? ; break; }
20008                 break
20009         done
20010
20011         destroy_test_pools
20012
20013         return $rc
20014 }
20015 run_test 200 "OST pools"
20016
20017 # usage: default_attr <count | size | offset>
20018 default_attr() {
20019         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20020 }
20021
20022 # usage: check_default_stripe_attr
20023 check_default_stripe_attr() {
20024         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20025         case $1 in
20026         --stripe-count|-c)
20027                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20028         --stripe-size|-S)
20029                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20030         --stripe-index|-i)
20031                 EXPECTED=-1;;
20032         *)
20033                 error "unknown getstripe attr '$1'"
20034         esac
20035
20036         [ $ACTUAL == $EXPECTED ] ||
20037                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20038 }
20039
20040 test_204a() {
20041         test_mkdir $DIR/$tdir
20042         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20043
20044         check_default_stripe_attr --stripe-count
20045         check_default_stripe_attr --stripe-size
20046         check_default_stripe_attr --stripe-index
20047 }
20048 run_test 204a "Print default stripe attributes"
20049
20050 test_204b() {
20051         test_mkdir $DIR/$tdir
20052         $LFS setstripe --stripe-count 1 $DIR/$tdir
20053
20054         check_default_stripe_attr --stripe-size
20055         check_default_stripe_attr --stripe-index
20056 }
20057 run_test 204b "Print default stripe size and offset"
20058
20059 test_204c() {
20060         test_mkdir $DIR/$tdir
20061         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20062
20063         check_default_stripe_attr --stripe-count
20064         check_default_stripe_attr --stripe-index
20065 }
20066 run_test 204c "Print default stripe count and offset"
20067
20068 test_204d() {
20069         test_mkdir $DIR/$tdir
20070         $LFS setstripe --stripe-index 0 $DIR/$tdir
20071
20072         check_default_stripe_attr --stripe-count
20073         check_default_stripe_attr --stripe-size
20074 }
20075 run_test 204d "Print default stripe count and size"
20076
20077 test_204e() {
20078         test_mkdir $DIR/$tdir
20079         $LFS setstripe -d $DIR/$tdir
20080
20081         # LU-16904 check if root is set as PFL layout
20082         local numcomp=$($LFS getstripe --component-count $MOUNT)
20083
20084         if [[ $numcomp -gt 0 ]]; then
20085                 check_default_stripe_attr --stripe-count
20086         else
20087                 check_default_stripe_attr --stripe-count --raw
20088         fi
20089         check_default_stripe_attr --stripe-size --raw
20090         check_default_stripe_attr --stripe-index --raw
20091 }
20092 run_test 204e "Print raw stripe attributes"
20093
20094 test_204f() {
20095         test_mkdir $DIR/$tdir
20096         $LFS setstripe --stripe-count 1 $DIR/$tdir
20097
20098         check_default_stripe_attr --stripe-size --raw
20099         check_default_stripe_attr --stripe-index --raw
20100 }
20101 run_test 204f "Print raw stripe size and offset"
20102
20103 test_204g() {
20104         test_mkdir $DIR/$tdir
20105         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20106
20107         check_default_stripe_attr --stripe-count --raw
20108         check_default_stripe_attr --stripe-index --raw
20109 }
20110 run_test 204g "Print raw stripe count and offset"
20111
20112 test_204h() {
20113         test_mkdir $DIR/$tdir
20114         $LFS setstripe --stripe-index 0 $DIR/$tdir
20115
20116         check_default_stripe_attr --stripe-count --raw
20117         check_default_stripe_attr --stripe-size --raw
20118 }
20119 run_test 204h "Print raw stripe count and size"
20120
20121 # Figure out which job scheduler is being used, if any,
20122 # or use a fake one
20123 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20124         JOBENV=SLURM_JOB_ID
20125 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20126         JOBENV=LSB_JOBID
20127 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20128         JOBENV=PBS_JOBID
20129 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20130         JOBENV=LOADL_STEP_ID
20131 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20132         JOBENV=JOB_ID
20133 else
20134         $LCTL list_param jobid_name > /dev/null 2>&1
20135         if [ $? -eq 0 ]; then
20136                 JOBENV=nodelocal
20137         else
20138                 JOBENV=FAKE_JOBID
20139         fi
20140 fi
20141 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20142
20143 verify_jobstats() {
20144         local cmd=($1)
20145         shift
20146         local facets="$@"
20147
20148 # we don't really need to clear the stats for this test to work, since each
20149 # command has a unique jobid, but it makes debugging easier if needed.
20150 #       for facet in $facets; do
20151 #               local dev=$(convert_facet2label $facet)
20152 #               # clear old jobstats
20153 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20154 #       done
20155
20156         # use a new JobID for each test, or we might see an old one
20157         [ "$JOBENV" = "FAKE_JOBID" ] &&
20158                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20159
20160         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20161
20162         [ "$JOBENV" = "nodelocal" ] && {
20163                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20164                 $LCTL set_param jobid_name=$FAKE_JOBID
20165                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20166         }
20167
20168         log "Test: ${cmd[*]}"
20169         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20170
20171         if [ $JOBENV = "FAKE_JOBID" ]; then
20172                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20173         else
20174                 ${cmd[*]}
20175         fi
20176
20177         # all files are created on OST0000
20178         for facet in $facets; do
20179                 local stats="*.$(convert_facet2label $facet).job_stats"
20180
20181                 # strip out libtool wrappers for in-tree executables
20182                 if (( $(do_facet $facet lctl get_param $stats |
20183                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20184                         do_facet $facet lctl get_param $stats
20185                         error "No jobstats for $JOBVAL found on $facet::$stats"
20186                 fi
20187         done
20188 }
20189
20190 jobstats_set() {
20191         local new_jobenv=$1
20192
20193         set_persistent_param_and_check client "jobid_var" \
20194                 "$FSNAME.sys.jobid_var" $new_jobenv
20195 }
20196
20197 test_205a() { # Job stats
20198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20199         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20200                 skip "Need MDS version with at least 2.7.1"
20201         remote_mgs_nodsh && skip "remote MGS with nodsh"
20202         remote_mds_nodsh && skip "remote MDS with nodsh"
20203         remote_ost_nodsh && skip "remote OST with nodsh"
20204         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20205                 skip "Server doesn't support jobstats"
20206         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20207
20208         local old_jobenv=$($LCTL get_param -n jobid_var)
20209         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20210         stack_trap "jobstats_set $old_jobenv" EXIT
20211
20212         changelog_register
20213
20214         local old_jobid_name=$($LCTL get_param jobid_name)
20215         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20216
20217         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20218                                 mdt.*.job_cleanup_interval | head -n 1)
20219         local new_interval=5
20220         do_facet $SINGLEMDS \
20221                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20222         stack_trap "do_facet $SINGLEMDS \
20223                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20224         local start=$SECONDS
20225
20226         local cmd
20227         # mkdir
20228         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20229         verify_jobstats "$cmd" "$SINGLEMDS"
20230         # rmdir
20231         cmd="rmdir $DIR/$tdir"
20232         verify_jobstats "$cmd" "$SINGLEMDS"
20233         # mkdir on secondary MDT
20234         if [ $MDSCOUNT -gt 1 ]; then
20235                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20236                 verify_jobstats "$cmd" "mds2"
20237         fi
20238         # mknod
20239         cmd="mknod $DIR/$tfile c 1 3"
20240         verify_jobstats "$cmd" "$SINGLEMDS"
20241         # unlink
20242         cmd="rm -f $DIR/$tfile"
20243         verify_jobstats "$cmd" "$SINGLEMDS"
20244         # create all files on OST0000 so verify_jobstats can find OST stats
20245         # open & close
20246         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20247         verify_jobstats "$cmd" "$SINGLEMDS"
20248         # setattr
20249         cmd="touch $DIR/$tfile"
20250         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20251         # write
20252         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20253         verify_jobstats "$cmd" "ost1"
20254         # read
20255         cancel_lru_locks osc
20256         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20257         verify_jobstats "$cmd" "ost1"
20258         # truncate
20259         cmd="$TRUNCATE $DIR/$tfile 0"
20260         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20261         # rename
20262         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20263         verify_jobstats "$cmd" "$SINGLEMDS"
20264         # jobstats expiry - sleep until old stats should be expired
20265         local left=$((new_interval + 5 - (SECONDS - start)))
20266         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20267                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20268                         "0" $left
20269         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20270         verify_jobstats "$cmd" "$SINGLEMDS"
20271         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20272             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20273
20274         # Ensure that jobid are present in changelog (if supported by MDS)
20275         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20276                 changelog_dump | tail -10
20277                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20278                 [ $jobids -eq 9 ] ||
20279                         error "Wrong changelog jobid count $jobids != 9"
20280
20281                 # LU-5862
20282                 JOBENV="disable"
20283                 jobstats_set $JOBENV
20284                 touch $DIR/$tfile
20285                 changelog_dump | grep $tfile
20286                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20287                 [ $jobids -eq 0 ] ||
20288                         error "Unexpected jobids when jobid_var=$JOBENV"
20289         fi
20290
20291         # test '%j' access to environment variable - if supported
20292         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20293                 JOBENV="JOBCOMPLEX"
20294                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20295
20296                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20297         fi
20298
20299         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20300                 JOBENV="JOBCOMPLEX"
20301                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20302
20303                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20304         fi
20305
20306         # test '%j' access to per-session jobid - if supported
20307         if lctl list_param jobid_this_session > /dev/null 2>&1
20308         then
20309                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20310                 lctl set_param jobid_this_session=$USER
20311
20312                 JOBENV="JOBCOMPLEX"
20313                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20314
20315                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20316         fi
20317 }
20318 run_test 205a "Verify job stats"
20319
20320 # LU-13117, LU-13597, LU-16599
20321 test_205b() {
20322         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20323                 skip "Need MDS version at least 2.13.54.91"
20324
20325         local job_stats="mdt.*.job_stats"
20326         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20327
20328         do_facet mds1 $LCTL set_param $job_stats=clear
20329
20330         # Setting jobid_var to USER might not be supported
20331         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20332         $LCTL set_param jobid_var=USER || true
20333         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20334         $LCTL set_param jobid_name="%j.%e.%u"
20335
20336         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20337         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20338                 { do_facet mds1 $LCTL get_param $job_stats;
20339                   error "Unexpected jobid found"; }
20340         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20341                 { do_facet mds1 $LCTL get_param $job_stats;
20342                   error "wrong job_stats format found"; }
20343
20344         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20345                 echo "MDS does not yet escape jobid" && return 0
20346
20347         mkdir_on_mdt0 $DIR/$tdir
20348         $LCTL set_param jobid_var=TEST205b
20349         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20350         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20351                       awk '/has\\x20sp/ {print $3}')
20352         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20353                   error "jobid not escaped"; }
20354
20355         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20356                 # need to run such a command on mds1:
20357                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20358                 #
20359                 # there might be multiple MDTs on single mds server, so need to
20360                 # specifiy MDT0000. Or the command will fail due to other MDTs
20361                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20362                         error "cannot clear escaped jobid in job_stats";
20363         else
20364                 echo "MDS does not support clearing escaped jobid"
20365         fi
20366 }
20367 run_test 205b "Verify job stats jobid and output format"
20368
20369 # LU-13733
20370 test_205c() {
20371         $LCTL set_param llite.*.stats=0
20372         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20373         $LCTL get_param llite.*.stats
20374         $LCTL get_param llite.*.stats | grep \
20375                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20376                         error "wrong client stats format found"
20377 }
20378 run_test 205c "Verify client stats format"
20379
20380 test_205d() {
20381         local file=$DIR/$tdir/$tfile
20382
20383         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20384                 skip "need lustre >= 2.15.53 for lljobstat"
20385         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20386                 skip "need lustre >= 2.15.53 for lljobstat"
20387         verify_yaml_available || skip_env "YAML verification not installed"
20388
20389         test_mkdir -i 0 $DIR/$tdir
20390         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20391         stack_trap "rm -rf $DIR/$tdir"
20392
20393         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20394                 error "failed to write data to $file"
20395         mv $file $file.2
20396
20397         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20398         echo -n 'verify rename_stats...'
20399         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20400                 verify_yaml || error "rename_stats is not valid YAML"
20401         echo " OK"
20402
20403         echo -n 'verify mdt job_stats...'
20404         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20405                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20406         echo " OK"
20407
20408         echo -n 'verify ost job_stats...'
20409         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20410                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20411         echo " OK"
20412 }
20413 run_test 205d "verify the format of some stats files"
20414
20415 test_205e() {
20416         local ops_comma
20417         local file=$DIR/$tdir/$tfile
20418         local -a cli_params
20419
20420         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20421                 skip "need lustre >= 2.15.53 for lljobstat"
20422         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20423                 skip "need lustre >= 2.15.53 for lljobstat"
20424         verify_yaml_available || skip_env "YAML verification not installed"
20425
20426         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20427         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20428         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20429
20430         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20431         stack_trap "rm -rf $DIR/$tdir"
20432
20433         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20434                 error "failed to create $file on ost1"
20435         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20436                 error "failed to write data to $file"
20437
20438         do_facet mds1 "$LCTL get_param *.*.job_stats"
20439         do_facet ost1 "$LCTL get_param *.*.job_stats"
20440
20441         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20442         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20443                 error "The output of lljobstat is not an valid YAML"
20444
20445         # verify that job dd.0 does exist and has some ops on ost1
20446         # typically this line is like:
20447         # - 205e.dd.0:            {ops: 20, ...}
20448         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20449                     awk '$2=="205e.dd.0:" {print $4}')
20450
20451         (( ${ops_comma%,} >= 10 )) ||
20452                 error "cannot find job 205e.dd.0 with ops >= 10"
20453 }
20454 run_test 205e "verify the output of lljobstat"
20455
20456 test_205f() {
20457         verify_yaml_available || skip_env "YAML verification not installed"
20458
20459         # check both qos_ost_weights and qos_mdt_weights
20460         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20461         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20462                 error "qos_ost_weights is not valid YAML"
20463 }
20464 run_test 205f "verify qos_ost_weights YAML format "
20465
20466 __test_205_jobstats_dump() {
20467         local -a pids
20468         local nbr_instance=$1
20469
20470         while true; do
20471                 if (( ${#pids[@]} >= nbr_instance )); then
20472                         wait ${pids[@]}
20473                         pids=()
20474                 fi
20475
20476                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20477                 pids+=( $! )
20478         done
20479 }
20480
20481 __test_205_cleanup() {
20482         kill $@
20483         # Clear all job entries
20484         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20485 }
20486
20487 test_205g() {
20488         local -a mds1_params
20489         local -a cli_params
20490         local pids
20491         local interval=5
20492
20493         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20494         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20495         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20496
20497         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20498         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20499         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20500
20501         # start jobs loop
20502         export TEST205G_ID=205g
20503         stack_trap "unset TEST205G_ID" EXIT
20504         while true; do
20505                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20506         done & pids="$! "
20507
20508         __test_205_jobstats_dump 4 & pids+="$! "
20509         stack_trap "__test_205_cleanup $pids" EXIT INT
20510
20511         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20512 }
20513 run_test 205g "stress test for job_stats procfile"
20514
20515 test_205h() {
20516         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20517                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20518         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20519
20520         local dir=$DIR/$tdir
20521         local f=$dir/$tfile
20522         local f2=$dir/$tfile-2
20523         local f3=$dir/$tfile-3
20524         local subdir=$DIR/dir
20525         local val
20526
20527         local mdts=$(comma_list $(mdts_nodes))
20528         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20529         local client_saved=$($LCTL get_param -n jobid_var)
20530
20531         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20532         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20533
20534         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20535                 error "failed to set job_xattr parameter to user.job"
20536         $LCTL set_param jobid_var=procname.uid ||
20537                 error "failed to set jobid_var parameter"
20538
20539         test_mkdir $dir
20540
20541         touch $f
20542         val=$(getfattr -n user.job $f | grep user.job)
20543         [[ $val = user.job=\"touch.0\" ]] ||
20544                 error "expected user.job=\"touch.0\", got '$val'"
20545
20546         mkdir $subdir
20547         val=$(getfattr -n user.job $subdir | grep user.job)
20548         [[ $val = user.job=\"mkdir.0\" ]] ||
20549                 error "expected user.job=\"mkdir.0\", got '$val'"
20550
20551         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20552                 error "failed to set job_xattr parameter to NONE"
20553
20554         touch $f2
20555         val=$(getfattr -d $f2)
20556         [[ -z $val ]] ||
20557                 error "expected no user xattr, got '$val'"
20558
20559         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20560                 error "failed to set job_xattr parameter to trusted.job"
20561
20562         touch $f3
20563         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20564         [[ $val = trusted.job=\"touch.0\" ]] ||
20565                 error "expected trusted.job=\"touch.0\", got '$val'"
20566 }
20567 run_test 205h "check jobid xattr is stored correctly"
20568
20569 test_205i() {
20570         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20571                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20572
20573         local mdts=$(comma_list $(mdts_nodes))
20574         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20575
20576         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20577
20578         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20579                 error "failed to set mdt.*.job_xattr to user.1234567"
20580
20581         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20582                 error "failed to reject too long job_xattr name"
20583
20584         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20585                 error "failed to reject job_xattr name in bad format"
20586
20587         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20588                 error "failed to reject job_xattr name with invalid character"
20589
20590         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20591                         xargs $LCTL set_param" &&
20592                 error "failed to reject job_xattr name with non-ascii character"
20593
20594         return 0
20595 }
20596 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20597
20598 # LU-1480, LU-1773 and LU-1657
20599 test_206() {
20600         mkdir -p $DIR/$tdir
20601         $LFS setstripe -c -1 $DIR/$tdir
20602 #define OBD_FAIL_LOV_INIT 0x1403
20603         $LCTL set_param fail_loc=0xa0001403
20604         $LCTL set_param fail_val=1
20605         touch $DIR/$tdir/$tfile || true
20606 }
20607 run_test 206 "fail lov_init_raid0() doesn't lbug"
20608
20609 test_207a() {
20610         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20611         local fsz=`stat -c %s $DIR/$tfile`
20612         cancel_lru_locks mdc
20613
20614         # do not return layout in getattr intent
20615 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20616         $LCTL set_param fail_loc=0x170
20617         local sz=`stat -c %s $DIR/$tfile`
20618
20619         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20620
20621         rm -rf $DIR/$tfile
20622 }
20623 run_test 207a "can refresh layout at glimpse"
20624
20625 test_207b() {
20626         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20627         local cksum=`md5sum $DIR/$tfile`
20628         local fsz=`stat -c %s $DIR/$tfile`
20629         cancel_lru_locks mdc
20630         cancel_lru_locks osc
20631
20632         # do not return layout in getattr intent
20633 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20634         $LCTL set_param fail_loc=0x171
20635
20636         # it will refresh layout after the file is opened but before read issues
20637         echo checksum is "$cksum"
20638         echo "$cksum" |md5sum -c --quiet || error "file differs"
20639
20640         rm -rf $DIR/$tfile
20641 }
20642 run_test 207b "can refresh layout at open"
20643
20644 test_208() {
20645         # FIXME: in this test suite, only RD lease is used. This is okay
20646         # for now as only exclusive open is supported. After generic lease
20647         # is done, this test suite should be revised. - Jinshan
20648
20649         remote_mds_nodsh && skip "remote MDS with nodsh"
20650         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20651                 skip "Need MDS version at least 2.4.52"
20652
20653         echo "==== test 1: verify get lease work"
20654         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20655
20656         echo "==== test 2: verify lease can be broken by upcoming open"
20657         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20658         local PID=$!
20659         sleep 2
20660
20661         $MULTIOP $DIR/$tfile oO_RDWR:c
20662         kill -USR1 $PID && wait $PID || error "break lease error"
20663
20664         echo "==== test 3: verify lease can't be granted if an open already exists"
20665         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20666         local PID=$!
20667         sleep 2
20668
20669         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20670         kill -USR1 $PID && wait $PID || error "open file error"
20671
20672         echo "==== test 4: lease can sustain over recovery"
20673         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20674         PID=$!
20675         sleep 2
20676
20677         fail mds1
20678
20679         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20680
20681         echo "==== test 5: lease broken can't be regained by replay"
20682         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20683         PID=$!
20684         sleep 2
20685
20686         # open file to break lease and then recovery
20687         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20688         fail mds1
20689
20690         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20691
20692         rm -f $DIR/$tfile
20693 }
20694 run_test 208 "Exclusive open"
20695
20696 test_209() {
20697         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20698                 skip_env "must have disp_stripe"
20699
20700         touch $DIR/$tfile
20701         sync; sleep 5; sync;
20702
20703         echo 3 > /proc/sys/vm/drop_caches
20704         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20705                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20706         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20707
20708         # open/close 500 times
20709         for i in $(seq 500); do
20710                 cat $DIR/$tfile
20711         done
20712
20713         echo 3 > /proc/sys/vm/drop_caches
20714         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20715                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20716         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20717
20718         echo "before: $req_before, after: $req_after"
20719         [ $((req_after - req_before)) -ge 300 ] &&
20720                 error "open/close requests are not freed"
20721         return 0
20722 }
20723 run_test 209 "read-only open/close requests should be freed promptly"
20724
20725 test_210() {
20726         local pid
20727
20728         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20729         pid=$!
20730         sleep 1
20731
20732         $LFS getstripe $DIR/$tfile
20733         kill -USR1 $pid
20734         wait $pid || error "multiop failed"
20735
20736         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20737         pid=$!
20738         sleep 1
20739
20740         $LFS getstripe $DIR/$tfile
20741         kill -USR1 $pid
20742         wait $pid || error "multiop failed"
20743 }
20744 run_test 210 "lfs getstripe does not break leases"
20745
20746 function test_211() {
20747         local PID
20748         local id
20749         local rc
20750
20751         stack_trap "rm -f $DIR/$tfile" EXIT
20752         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20753                 error "can't create file"
20754         $LFS mirror extend -N $DIR/$tfile ||
20755                 error "can't create a replica"
20756         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20757         $LFS getstripe $DIR/$tfile
20758         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20759         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20760
20761         $MULTIOP $DIR/$tfile OeW_E+eUc &
20762         PID=$!
20763         sleep 0.3
20764
20765         id=$($LFS getstripe $DIR/$tfile |
20766                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20767         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20768                 error "removed last in-sync replica?"
20769
20770         kill -USR1 $PID
20771         wait $PID
20772         (( $? == 0 )) || error "failed split broke the lease"
20773 }
20774 run_test 211 "failed mirror split doesn't break write lease"
20775
20776 test_212() {
20777         size=`date +%s`
20778         size=$((size % 8192 + 1))
20779         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20780         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20781         rm -f $DIR/f212 $DIR/f212.xyz
20782 }
20783 run_test 212 "Sendfile test ============================================"
20784
20785 test_213() {
20786         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20787         cancel_lru_locks osc
20788         lctl set_param fail_loc=0x8000040f
20789         # generate a read lock
20790         cat $DIR/$tfile > /dev/null
20791         # write to the file, it will try to cancel the above read lock.
20792         cat /etc/hosts >> $DIR/$tfile
20793 }
20794 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20795
20796 test_214() { # for bug 20133
20797         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20798         for (( i=0; i < 340; i++ )) ; do
20799                 touch $DIR/$tdir/d214c/a$i
20800         done
20801
20802         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20803         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20804         ls $DIR/d214c || error "ls $DIR/d214c failed"
20805         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20806         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20807 }
20808 run_test 214 "hash-indexed directory test - bug 20133"
20809
20810 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20811 create_lnet_proc_files() {
20812         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20813 }
20814
20815 # counterpart of create_lnet_proc_files
20816 remove_lnet_proc_files() {
20817         rm -f $TMP/lnet_$1.sys
20818 }
20819
20820 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20821 # 3rd arg as regexp for body
20822 check_lnet_proc_stats() {
20823         local l=$(cat "$TMP/lnet_$1" |wc -l)
20824         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20825
20826         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20827 }
20828
20829 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20830 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20831 # optional and can be regexp for 2nd line (lnet.routes case)
20832 check_lnet_proc_entry() {
20833         local blp=2          # blp stands for 'position of 1st line of body'
20834         [ -z "$5" ] || blp=3 # lnet.routes case
20835
20836         local l=$(cat "$TMP/lnet_$1" |wc -l)
20837         # subtracting one from $blp because the body can be empty
20838         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20839
20840         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20841                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20842
20843         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20844                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20845
20846         # bail out if any unexpected line happened
20847         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20848         [ "$?" != 0 ] || error "$2 misformatted"
20849 }
20850
20851 test_215() { # for bugs 18102, 21079, 21517
20852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20853
20854         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20855         local P='[1-9][0-9]*'           # positive numeric
20856         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20857         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20858         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20859         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20860
20861         local L1 # regexp for 1st line
20862         local L2 # regexp for 2nd line (optional)
20863         local BR # regexp for the rest (body)
20864
20865         # lnet.stats should look as 11 space-separated non-negative numerics
20866         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20867         create_lnet_proc_files "stats"
20868         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20869         remove_lnet_proc_files "stats"
20870
20871         # lnet.routes should look like this:
20872         # Routing disabled/enabled
20873         # net hops priority state router
20874         # where net is a string like tcp0, hops > 0, priority >= 0,
20875         # state is up/down,
20876         # router is a string like 192.168.1.1@tcp2
20877         L1="^Routing (disabled|enabled)$"
20878         L2="^net +hops +priority +state +router$"
20879         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20880         create_lnet_proc_files "routes"
20881         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20882         remove_lnet_proc_files "routes"
20883
20884         # lnet.routers should look like this:
20885         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20886         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20887         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20888         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20889         L1="^ref +rtr_ref +alive +router$"
20890         BR="^$P +$P +(up|down) +$NID$"
20891         create_lnet_proc_files "routers"
20892         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20893         remove_lnet_proc_files "routers"
20894
20895         # lnet.peers should look like this:
20896         # nid refs state last max rtr min tx min queue
20897         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20898         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20899         # numeric (0 or >0 or <0), queue >= 0.
20900         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20901         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20902         create_lnet_proc_files "peers"
20903         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20904         remove_lnet_proc_files "peers"
20905
20906         # lnet.buffers  should look like this:
20907         # pages count credits min
20908         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20909         L1="^pages +count +credits +min$"
20910         BR="^ +$N +$N +$I +$I$"
20911         create_lnet_proc_files "buffers"
20912         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20913         remove_lnet_proc_files "buffers"
20914
20915         # lnet.nis should look like this:
20916         # nid status alive refs peer rtr max tx min
20917         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20918         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20919         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20920         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20921         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20922         create_lnet_proc_files "nis"
20923         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20924         remove_lnet_proc_files "nis"
20925
20926         # can we successfully write to lnet.stats?
20927         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20928 }
20929 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20930
20931 test_216() { # bug 20317
20932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20933         remote_ost_nodsh && skip "remote OST with nodsh"
20934
20935         local node
20936         local facets=$(get_facets OST)
20937         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20938
20939         save_lustre_params client "osc.*.contention_seconds" > $p
20940         save_lustre_params $facets \
20941                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20942         save_lustre_params $facets \
20943                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20944         save_lustre_params $facets \
20945                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20946         clear_stats osc.*.osc_stats
20947
20948         # agressive lockless i/o settings
20949         do_nodes $(comma_list $(osts_nodes)) \
20950                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20951                         ldlm.namespaces.filter-*.contended_locks=0 \
20952                         ldlm.namespaces.filter-*.contention_seconds=60"
20953         lctl set_param -n osc.*.contention_seconds=60
20954
20955         $DIRECTIO write $DIR/$tfile 0 10 4096
20956         $CHECKSTAT -s 40960 $DIR/$tfile
20957
20958         # disable lockless i/o
20959         do_nodes $(comma_list $(osts_nodes)) \
20960                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20961                         ldlm.namespaces.filter-*.contended_locks=32 \
20962                         ldlm.namespaces.filter-*.contention_seconds=0"
20963         lctl set_param -n osc.*.contention_seconds=0
20964         clear_stats osc.*.osc_stats
20965
20966         dd if=/dev/zero of=$DIR/$tfile count=0
20967         $CHECKSTAT -s 0 $DIR/$tfile
20968
20969         restore_lustre_params <$p
20970         rm -f $p
20971         rm $DIR/$tfile
20972 }
20973 run_test 216 "check lockless direct write updates file size and kms correctly"
20974
20975 test_217() { # bug 22430
20976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20977
20978         local node
20979
20980         for node in $(nodes_list); do
20981                 local nid=$(host_nids_address $node $NETTYPE)
20982                 local node_ip=$(do_node $node getent ahostsv4 $node |
20983                                 awk '{ print $1; exit; }')
20984
20985                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20986                 # if hostname matches any NID, use hostname for better testing
20987                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20988                         echo "lctl ping node $node@$NETTYPE"
20989                         lctl ping $node@$NETTYPE
20990                 else # otherwise, at least test 'lctl ping' is working
20991                         echo "lctl ping nid $(h2nettype $nid)"
20992                         lctl ping $(h2nettype $nid)
20993                         echo "skipping $node (no hyphen detected)"
20994                 fi
20995         done
20996 }
20997 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20998
20999 test_218() {
21000         # do directio so as not to populate the page cache
21001         log "creating a 10 Mb file"
21002         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21003                 error "multiop failed while creating a file"
21004         log "starting reads"
21005         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21006         log "truncating the file"
21007         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21008                 error "multiop failed while truncating the file"
21009         log "killing dd"
21010         kill %+ || true # reads might have finished
21011         echo "wait until dd is finished"
21012         wait
21013         log "removing the temporary file"
21014         rm -rf $DIR/$tfile || error "tmp file removal failed"
21015 }
21016 run_test 218 "parallel read and truncate should not deadlock"
21017
21018 test_219() {
21019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21020
21021         # write one partial page
21022         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21023         # set no grant so vvp_io_commit_write will do sync write
21024         $LCTL set_param fail_loc=0x411
21025         # write a full page at the end of file
21026         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21027
21028         $LCTL set_param fail_loc=0
21029         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21030         $LCTL set_param fail_loc=0x411
21031         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21032
21033         # LU-4201
21034         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21035         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21036 }
21037 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21038
21039 test_220() { #LU-325
21040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21041         remote_ost_nodsh && skip "remote OST with nodsh"
21042         remote_mds_nodsh && skip "remote MDS with nodsh"
21043         remote_mgs_nodsh && skip "remote MGS with nodsh"
21044
21045         local OSTIDX=0
21046
21047         # create on MDT0000 so the last_id and next_id are correct
21048         mkdir_on_mdt0 $DIR/$tdir
21049         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21050         OST=${OST%_UUID}
21051
21052         # on the mdt's osc
21053         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21054         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21055                         osp.$mdtosc_proc1.prealloc_last_id)
21056         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21057                         osp.$mdtosc_proc1.prealloc_next_id)
21058
21059         $LFS df -i
21060
21061         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21062         #define OBD_FAIL_OST_ENOINO              0x229
21063         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21064         create_pool $FSNAME.$TESTNAME || return 1
21065         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21066
21067         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21068
21069         MDSOBJS=$((last_id - next_id))
21070         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21071
21072         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21073         echo "OST still has $count kbytes free"
21074
21075         echo "create $MDSOBJS files @next_id..."
21076         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21077
21078         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21079                         osp.$mdtosc_proc1.prealloc_last_id)
21080         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21081                         osp.$mdtosc_proc1.prealloc_next_id)
21082
21083         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21084         $LFS df -i
21085
21086         echo "cleanup..."
21087
21088         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21089         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21090
21091         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21092                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21093         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21094                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21095         echo "unlink $MDSOBJS files @$next_id..."
21096         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21097 }
21098 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21099
21100 test_221() {
21101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21102
21103         dd if=`which date` of=$MOUNT/date oflag=sync
21104         chmod +x $MOUNT/date
21105
21106         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21107         $LCTL set_param fail_loc=0x80001401
21108
21109         $MOUNT/date > /dev/null
21110         rm -f $MOUNT/date
21111 }
21112 run_test 221 "make sure fault and truncate race to not cause OOM"
21113
21114 test_222a () {
21115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21116
21117         rm -rf $DIR/$tdir
21118         test_mkdir $DIR/$tdir
21119         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21120         createmany -o $DIR/$tdir/$tfile 10
21121         cancel_lru_locks mdc
21122         cancel_lru_locks osc
21123         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21124         $LCTL set_param fail_loc=0x31a
21125         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21126         $LCTL set_param fail_loc=0
21127         rm -r $DIR/$tdir
21128 }
21129 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21130
21131 test_222b () {
21132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21133
21134         rm -rf $DIR/$tdir
21135         test_mkdir $DIR/$tdir
21136         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21137         createmany -o $DIR/$tdir/$tfile 10
21138         cancel_lru_locks mdc
21139         cancel_lru_locks osc
21140         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21141         $LCTL set_param fail_loc=0x31a
21142         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21143         $LCTL set_param fail_loc=0
21144 }
21145 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21146
21147 test_223 () {
21148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21149
21150         rm -rf $DIR/$tdir
21151         test_mkdir $DIR/$tdir
21152         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21153         createmany -o $DIR/$tdir/$tfile 10
21154         cancel_lru_locks mdc
21155         cancel_lru_locks osc
21156         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21157         $LCTL set_param fail_loc=0x31b
21158         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21159         $LCTL set_param fail_loc=0
21160         rm -r $DIR/$tdir
21161 }
21162 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21163
21164 test_224a() { # LU-1039, MRP-303
21165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21166         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21167         $LCTL set_param fail_loc=0x508
21168         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21169         $LCTL set_param fail_loc=0
21170         df $DIR
21171 }
21172 run_test 224a "Don't panic on bulk IO failure"
21173
21174 test_224bd_sub() { # LU-1039, MRP-303
21175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21176         local timeout=$1
21177
21178         shift
21179         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21180
21181         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21182
21183         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21184         cancel_lru_locks osc
21185         set_checksums 0
21186         stack_trap "set_checksums $ORIG_CSUM" EXIT
21187         local at_max_saved=0
21188
21189         # adaptive timeouts may prevent seeing the issue
21190         if at_is_enabled; then
21191                 at_max_saved=$(at_max_get mds)
21192                 at_max_set 0 mds client
21193                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21194         fi
21195
21196         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21197         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21198         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21199
21200         do_facet ost1 $LCTL set_param fail_loc=0
21201         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21202         df $DIR
21203 }
21204
21205 test_224b() {
21206         test_224bd_sub 3 error "dd failed"
21207 }
21208 run_test 224b "Don't panic on bulk IO failure"
21209
21210 test_224c() { # LU-6441
21211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21212         remote_mds_nodsh && skip "remote MDS with nodsh"
21213
21214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21215         save_writethrough $p
21216         set_cache writethrough on
21217
21218         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21219         local at_max=$($LCTL get_param -n at_max)
21220         local timeout=$($LCTL get_param -n timeout)
21221         local test_at="at_max"
21222         local param_at="$FSNAME.sys.at_max"
21223         local test_timeout="timeout"
21224         local param_timeout="$FSNAME.sys.timeout"
21225
21226         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21227
21228         set_persistent_param_and_check client "$test_at" "$param_at" 0
21229         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21230
21231         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21232         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21233         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21234         stack_trap "rm -f $DIR/$tfile"
21235         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21236         sync
21237         do_facet ost1 "$LCTL set_param fail_loc=0"
21238
21239         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21240         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21241                 $timeout
21242
21243         $LCTL set_param -n $pages_per_rpc
21244         restore_lustre_params < $p
21245         rm -f $p
21246 }
21247 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21248
21249 test_224d() { # LU-11169
21250         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21251 }
21252 run_test 224d "Don't corrupt data on bulk IO timeout"
21253
21254 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21255 test_225a () {
21256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21257         if [ -z ${MDSSURVEY} ]; then
21258                 skip_env "mds-survey not found"
21259         fi
21260         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21261                 skip "Need MDS version at least 2.2.51"
21262
21263         local mds=$(facet_host $SINGLEMDS)
21264         local target=$(do_nodes $mds 'lctl dl' |
21265                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21266
21267         local cmd1="file_count=1000 thrhi=4"
21268         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21269         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21270         local cmd="$cmd1 $cmd2 $cmd3"
21271
21272         rm -f ${TMP}/mds_survey*
21273         echo + $cmd
21274         eval $cmd || error "mds-survey with zero-stripe failed"
21275         cat ${TMP}/mds_survey*
21276         rm -f ${TMP}/mds_survey*
21277 }
21278 run_test 225a "Metadata survey sanity with zero-stripe"
21279
21280 test_225b () {
21281         if [ -z ${MDSSURVEY} ]; then
21282                 skip_env "mds-survey not found"
21283         fi
21284         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21285                 skip "Need MDS version at least 2.2.51"
21286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21287         remote_mds_nodsh && skip "remote MDS with nodsh"
21288         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21289                 skip_env "Need to mount OST to test"
21290         fi
21291
21292         local mds=$(facet_host $SINGLEMDS)
21293         local target=$(do_nodes $mds 'lctl dl' |
21294                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21295
21296         local cmd1="file_count=1000 thrhi=4"
21297         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21298         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21299         local cmd="$cmd1 $cmd2 $cmd3"
21300
21301         rm -f ${TMP}/mds_survey*
21302         echo + $cmd
21303         eval $cmd || error "mds-survey with stripe_count failed"
21304         cat ${TMP}/mds_survey*
21305         rm -f ${TMP}/mds_survey*
21306 }
21307 run_test 225b "Metadata survey sanity with stripe_count = 1"
21308
21309 mcreate_path2fid () {
21310         local mode=$1
21311         local major=$2
21312         local minor=$3
21313         local name=$4
21314         local desc=$5
21315         local path=$DIR/$tdir/$name
21316         local fid
21317         local rc
21318         local fid_path
21319
21320         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21321                 error "cannot create $desc"
21322
21323         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21324         rc=$?
21325         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21326
21327         fid_path=$($LFS fid2path $MOUNT $fid)
21328         rc=$?
21329         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21330
21331         [ "$path" == "$fid_path" ] ||
21332                 error "fid2path returned $fid_path, expected $path"
21333
21334         echo "pass with $path and $fid"
21335 }
21336
21337 test_226a () {
21338         rm -rf $DIR/$tdir
21339         mkdir -p $DIR/$tdir
21340
21341         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21342         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21343         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21344         mcreate_path2fid 0040666 0 0 dir "directory"
21345         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21346         mcreate_path2fid 0100666 0 0 file "regular file"
21347         mcreate_path2fid 0120666 0 0 link "symbolic link"
21348         mcreate_path2fid 0140666 0 0 sock "socket"
21349 }
21350 run_test 226a "call path2fid and fid2path on files of all type"
21351
21352 test_226b () {
21353         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21354
21355         local MDTIDX=1
21356
21357         rm -rf $DIR/$tdir
21358         mkdir -p $DIR/$tdir
21359         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21360                 error "create remote directory failed"
21361         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21362         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21363                                 "character special file (null)"
21364         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21365                                 "character special file (no device)"
21366         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21367         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21368                                 "block special file (loop)"
21369         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21370         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21371         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21372 }
21373 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21374
21375 test_226c () {
21376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21377         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21378                 skip "Need MDS version at least 2.13.55"
21379
21380         local submnt=/mnt/submnt
21381         local srcfile=/etc/passwd
21382         local dstfile=$submnt/passwd
21383         local path
21384         local fid
21385
21386         rm -rf $DIR/$tdir
21387         rm -rf $submnt
21388         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21389                 error "create remote directory failed"
21390         mkdir -p $submnt || error "create $submnt failed"
21391         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21392                 error "mount $submnt failed"
21393         stack_trap "umount $submnt" EXIT
21394
21395         cp $srcfile $dstfile
21396         fid=$($LFS path2fid $dstfile)
21397         path=$($LFS fid2path $submnt "$fid")
21398         [ "$path" = "$dstfile" ] ||
21399                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21400 }
21401 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21402
21403 test_226d () {
21404         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21405                 skip "Need client at least version 2.15.57"
21406
21407         # Define First test dataset
21408         local testdirs_01=$DIR/$tdir
21409         local testdata_01=$testdirs_01/${tdir}_01
21410         local testresult_01=${tdir}_01
21411         # Define Second test dataset
21412         local testdirs_02=$DIR/$tdir/$tdir
21413         local testdata_02=$testdirs_02/${tdir}_02
21414         local testresult_02=${tdir}_02
21415         # Define third test dataset (top level)
21416         local testdata_03=$DIR/${tdir}_03
21417         local testresult_03=${tdir}_03
21418
21419         # Create first test dataset
21420         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21421         touch $testdata_01 || error "cannot create file $testdata_01"
21422
21423         # Create second test dataset
21424         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21425         touch $testdata_02 || error "cannot create file $testdata_02"
21426
21427         # Create third test dataset
21428         touch $testdata_03 || error "cannot create file $testdata_03"
21429
21430         local fid01=$($LFS getstripe -F "$testdata_01") ||
21431                 error "getstripe failed on $testdata_01"
21432         local fid02=$($LFS getstripe -F "$testdata_02") ||
21433                 error "getstripe failed on $testdata_01"
21434         local fid03=$($LFS getstripe -F "$testdata_03") ||
21435                 error "getstripe failed on $testdata_03"
21436
21437         # Verify only -n option
21438         local out1=$($LFS fid2path -n $DIR $fid01) ||
21439                 error "fid2path failed on $fid01"
21440         local out2=$($LFS fid2path -n $DIR $fid02) ||
21441                 error "fid2path failed on $fid02"
21442         local out3=$($LFS fid2path -n $DIR $fid03) ||
21443                 error "fid2path failed on $fid03"
21444
21445         [[ "$out1" == "$testresult_01" ]] ||
21446                 error "fid2path failed: Expected $testresult_01 got $out1"
21447         [[ "$out2" == "$testresult_02" ]] ||
21448                 error "fid2path failed: Expected $testresult_02 got $out2"
21449         [[ "$out3" == "$testresult_03" ]] ||
21450                 error "fid2path failed: Expected $testresult_03 got $out3"
21451
21452         # Verify with option -fn together
21453         out1=$($LFS fid2path -fn $DIR $fid01) ||
21454                 error "fid2path -fn failed on $fid01"
21455         out2=$($LFS fid2path -fn $DIR $fid02) ||
21456                 error "fid2path -fn failed on $fid02"
21457         out3=$($LFS fid2path -fn $DIR $fid03) ||
21458                 error "fid2path -fn failed on $fid03"
21459
21460         local tmpout=$(echo $out1 | cut -d" " -f2)
21461         [[ "$tmpout" == "$testresult_01" ]] ||
21462                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21463
21464         tmpout=$(echo $out2 | cut -d" " -f2)
21465         [[ "$tmpout" == "$testresult_02" ]] ||
21466                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21467
21468         tmpout=$(echo $out3 | cut -d" " -f2)
21469         [[ "$tmpout" == "$testresult_03" ]] ||
21470                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21471 }
21472 run_test 226d "verify fid2path with -n and -fn option"
21473
21474 test_226e () {
21475         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21476                 skip "Need client at least version 2.15.56"
21477
21478         # Define filename with 'newline' and a space
21479         local testfile="Test"$'\n'"file 01"
21480         # Define link name with multiple 'newline' and a space
21481         local linkfile="Link"$'\n'"file "$'\n'"01"
21482         # Remove prior hard link
21483         rm -f $DIR/"$linkfile"
21484
21485         # Create file
21486         touch $DIR/"$testfile"
21487         # Create link
21488         ln $DIR/"$testfile" $DIR/"$linkfile"
21489
21490         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21491                 error "getstripe failed on $DIR/$testfile"
21492
21493         # Call with -0 option
21494         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21495                 echo "FILE:" | grep -c "FILE:")
21496
21497         # With -0 option the output should be exactly 2 lines.
21498         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21499 }
21500 run_test 226e "Verify path2fid -0 option with newline and space"
21501
21502 # LU-1299 Executing or running ldd on a truncated executable does not
21503 # cause an out-of-memory condition.
21504 test_227() {
21505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21506         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21507
21508         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21509         chmod +x $MOUNT/date
21510
21511         $MOUNT/date > /dev/null
21512         ldd $MOUNT/date > /dev/null
21513         rm -f $MOUNT/date
21514 }
21515 run_test 227 "running truncated executable does not cause OOM"
21516
21517 # LU-1512 try to reuse idle OI blocks
21518 test_228a() {
21519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21520         remote_mds_nodsh && skip "remote MDS with nodsh"
21521         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21522
21523         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21524         local myDIR=$DIR/$tdir
21525
21526         mkdir -p $myDIR
21527         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21528         $LCTL set_param fail_loc=0x80001002
21529         createmany -o $myDIR/t- 10000
21530         $LCTL set_param fail_loc=0
21531         # The guard is current the largest FID holder
21532         touch $myDIR/guard
21533         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21534                     tr -d '[')
21535         local IDX=$(($SEQ % 64))
21536
21537         do_facet $SINGLEMDS sync
21538         # Make sure journal flushed.
21539         sleep 6
21540         local blk1=$(do_facet $SINGLEMDS \
21541                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21542                      grep Blockcount | awk '{print $4}')
21543
21544         # Remove old files, some OI blocks will become idle.
21545         unlinkmany $myDIR/t- 10000
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 228a "try to reuse idle OI blocks"
21558
21559 test_228b() {
21560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21561         remote_mds_nodsh && skip "remote MDS with nodsh"
21562         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21563
21564         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21565         local myDIR=$DIR/$tdir
21566
21567         mkdir -p $myDIR
21568         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21569         $LCTL set_param fail_loc=0x80001002
21570         createmany -o $myDIR/t- 10000
21571         $LCTL set_param fail_loc=0
21572         # The guard is current the largest FID holder
21573         touch $myDIR/guard
21574         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21575                     tr -d '[')
21576         local IDX=$(($SEQ % 64))
21577
21578         do_facet $SINGLEMDS sync
21579         # Make sure journal flushed.
21580         sleep 6
21581         local blk1=$(do_facet $SINGLEMDS \
21582                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21583                      grep Blockcount | awk '{print $4}')
21584
21585         # Remove old files, some OI blocks will become idle.
21586         unlinkmany $myDIR/t- 10000
21587
21588         # stop the MDT
21589         stop $SINGLEMDS || error "Fail to stop MDT."
21590         # remount the MDT
21591         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21592                 error "Fail to start MDT."
21593
21594         client_up || error "Fail to df."
21595         # Create new files, idle OI blocks should be reused.
21596         createmany -o $myDIR/t- 2000
21597         do_facet $SINGLEMDS sync
21598         # Make sure journal flushed.
21599         sleep 6
21600         local blk2=$(do_facet $SINGLEMDS \
21601                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21602                      grep Blockcount | awk '{print $4}')
21603
21604         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21605 }
21606 run_test 228b "idle OI blocks can be reused after MDT restart"
21607
21608 #LU-1881
21609 test_228c() {
21610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21611         remote_mds_nodsh && skip "remote MDS with nodsh"
21612         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21613
21614         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21615         local myDIR=$DIR/$tdir
21616
21617         mkdir -p $myDIR
21618         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21619         $LCTL set_param fail_loc=0x80001002
21620         # 20000 files can guarantee there are index nodes in the OI file
21621         createmany -o $myDIR/t- 20000
21622         $LCTL set_param fail_loc=0
21623         # The guard is current the largest FID holder
21624         touch $myDIR/guard
21625         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21626                     tr -d '[')
21627         local IDX=$(($SEQ % 64))
21628
21629         do_facet $SINGLEMDS sync
21630         # Make sure journal flushed.
21631         sleep 6
21632         local blk1=$(do_facet $SINGLEMDS \
21633                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21634                      grep Blockcount | awk '{print $4}')
21635
21636         # Remove old files, some OI blocks will become idle.
21637         unlinkmany $myDIR/t- 20000
21638         rm -f $myDIR/guard
21639         # The OI file should become empty now
21640
21641         # Create new files, idle OI blocks should be reused.
21642         createmany -o $myDIR/t- 2000
21643         do_facet $SINGLEMDS sync
21644         # Make sure journal flushed.
21645         sleep 6
21646         local blk2=$(do_facet $SINGLEMDS \
21647                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21648                      grep Blockcount | awk '{print $4}')
21649
21650         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21651 }
21652 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21653
21654 test_229() { # LU-2482, LU-3448
21655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21656         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21657         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21658                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21659
21660         rm -f $DIR/$tfile
21661
21662         # Create a file with a released layout and stripe count 2.
21663         $MULTIOP $DIR/$tfile H2c ||
21664                 error "failed to create file with released layout"
21665
21666         $LFS getstripe -v $DIR/$tfile
21667
21668         local pattern=$($LFS getstripe -L $DIR/$tfile)
21669         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21670
21671         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21672                 error "getstripe"
21673         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21674         stat $DIR/$tfile || error "failed to stat released file"
21675
21676         chown $RUNAS_ID $DIR/$tfile ||
21677                 error "chown $RUNAS_ID $DIR/$tfile failed"
21678
21679         chgrp $RUNAS_ID $DIR/$tfile ||
21680                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21681
21682         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21683         rm $DIR/$tfile || error "failed to remove released file"
21684 }
21685 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21686
21687 test_230a() {
21688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21689         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21690         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21691                 skip "Need MDS version at least 2.11.52"
21692
21693         local MDTIDX=1
21694
21695         test_mkdir $DIR/$tdir
21696         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21697         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21698         [ $mdt_idx -ne 0 ] &&
21699                 error "create local directory on wrong MDT $mdt_idx"
21700
21701         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21702                         error "create remote directory failed"
21703         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21704         [ $mdt_idx -ne $MDTIDX ] &&
21705                 error "create remote directory on wrong MDT $mdt_idx"
21706
21707         createmany -o $DIR/$tdir/test_230/t- 10 ||
21708                 error "create files on remote directory failed"
21709         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21710         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21711         rm -r $DIR/$tdir || error "unlink remote directory failed"
21712 }
21713 run_test 230a "Create remote directory and files under the remote directory"
21714
21715 test_230b() {
21716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21717         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21718         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21719                 skip "Need MDS version at least 2.11.52"
21720
21721         local MDTIDX=1
21722         local mdt_index
21723         local i
21724         local file
21725         local pid
21726         local stripe_count
21727         local migrate_dir=$DIR/$tdir/migrate_dir
21728         local other_dir=$DIR/$tdir/other_dir
21729
21730         test_mkdir $DIR/$tdir
21731         test_mkdir -i0 -c1 $migrate_dir
21732         test_mkdir -i0 -c1 $other_dir
21733         for ((i=0; i<10; i++)); do
21734                 mkdir -p $migrate_dir/dir_${i}
21735                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21736                         error "create files under remote dir failed $i"
21737         done
21738
21739         cp /etc/passwd $migrate_dir/$tfile
21740         cp /etc/passwd $other_dir/$tfile
21741         chattr +SAD $migrate_dir
21742         chattr +SAD $migrate_dir/$tfile
21743
21744         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21745         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21746         local old_dir_mode=$(stat -c%f $migrate_dir)
21747         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21748
21749         mkdir -p $migrate_dir/dir_default_stripe2
21750         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21751         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21752
21753         mkdir -p $other_dir
21754         ln $migrate_dir/$tfile $other_dir/luna
21755         ln $migrate_dir/$tfile $migrate_dir/sofia
21756         ln $other_dir/$tfile $migrate_dir/david
21757         ln -s $migrate_dir/$tfile $other_dir/zachary
21758         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21759         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21760
21761         local len
21762         local lnktgt
21763
21764         # inline symlink
21765         for len in 58 59 60; do
21766                 lnktgt=$(str_repeat 'l' $len)
21767                 touch $migrate_dir/$lnktgt
21768                 ln -s $lnktgt $migrate_dir/${len}char_ln
21769         done
21770
21771         # PATH_MAX
21772         for len in 4094 4095; do
21773                 lnktgt=$(str_repeat 'l' $len)
21774                 ln -s $lnktgt $migrate_dir/${len}char_ln
21775         done
21776
21777         # NAME_MAX
21778         for len in 254 255; do
21779                 touch $migrate_dir/$(str_repeat 'l' $len)
21780         done
21781
21782         $LFS migrate -m $MDTIDX $migrate_dir ||
21783                 error "fails on migrating remote dir to MDT1"
21784
21785         echo "migratate to MDT1, then checking.."
21786         for ((i = 0; i < 10; i++)); do
21787                 for file in $(find $migrate_dir/dir_${i}); do
21788                         mdt_index=$($LFS getstripe -m $file)
21789                         # broken symlink getstripe will fail
21790                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21791                                 error "$file is not on MDT${MDTIDX}"
21792                 done
21793         done
21794
21795         # the multiple link file should still in MDT0
21796         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21797         [ $mdt_index == 0 ] ||
21798                 error "$file is not on MDT${MDTIDX}"
21799
21800         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21801         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21802                 error " expect $old_dir_flag get $new_dir_flag"
21803
21804         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21805         [ "$old_file_flag" = "$new_file_flag" ] ||
21806                 error " expect $old_file_flag get $new_file_flag"
21807
21808         local new_dir_mode=$(stat -c%f $migrate_dir)
21809         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21810                 error "expect mode $old_dir_mode get $new_dir_mode"
21811
21812         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21813         [ "$old_file_mode" = "$new_file_mode" ] ||
21814                 error "expect mode $old_file_mode get $new_file_mode"
21815
21816         diff /etc/passwd $migrate_dir/$tfile ||
21817                 error "$tfile different after migration"
21818
21819         diff /etc/passwd $other_dir/luna ||
21820                 error "luna different after migration"
21821
21822         diff /etc/passwd $migrate_dir/sofia ||
21823                 error "sofia different after migration"
21824
21825         diff /etc/passwd $migrate_dir/david ||
21826                 error "david different after migration"
21827
21828         diff /etc/passwd $other_dir/zachary ||
21829                 error "zachary different after migration"
21830
21831         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21832                 error "${tfile}_ln different after migration"
21833
21834         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21835                 error "${tfile}_ln_other different after migration"
21836
21837         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21838         [ $stripe_count = 2 ] ||
21839                 error "dir strpe_count $d != 2 after migration."
21840
21841         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21842         [ $stripe_count = 2 ] ||
21843                 error "file strpe_count $d != 2 after migration."
21844
21845         #migrate back to MDT0
21846         MDTIDX=0
21847
21848         $LFS migrate -m $MDTIDX $migrate_dir ||
21849                 error "fails on migrating remote dir to MDT0"
21850
21851         echo "migrate back to MDT0, checking.."
21852         for file in $(find $migrate_dir); do
21853                 mdt_index=$($LFS getstripe -m $file)
21854                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21855                         error "$file is not on MDT${MDTIDX}"
21856         done
21857
21858         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21859         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21860                 error " expect $old_dir_flag get $new_dir_flag"
21861
21862         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21863         [ "$old_file_flag" = "$new_file_flag" ] ||
21864                 error " expect $old_file_flag get $new_file_flag"
21865
21866         local new_dir_mode=$(stat -c%f $migrate_dir)
21867         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21868                 error "expect mode $old_dir_mode get $new_dir_mode"
21869
21870         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21871         [ "$old_file_mode" = "$new_file_mode" ] ||
21872                 error "expect mode $old_file_mode get $new_file_mode"
21873
21874         diff /etc/passwd ${migrate_dir}/$tfile ||
21875                 error "$tfile different after migration"
21876
21877         diff /etc/passwd ${other_dir}/luna ||
21878                 error "luna different after migration"
21879
21880         diff /etc/passwd ${migrate_dir}/sofia ||
21881                 error "sofia different after migration"
21882
21883         diff /etc/passwd ${other_dir}/zachary ||
21884                 error "zachary different after migration"
21885
21886         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21887                 error "${tfile}_ln different after migration"
21888
21889         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21890                 error "${tfile}_ln_other different after migration"
21891
21892         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21893         [ $stripe_count = 2 ] ||
21894                 error "dir strpe_count $d != 2 after migration."
21895
21896         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21897         [ $stripe_count = 2 ] ||
21898                 error "file strpe_count $d != 2 after migration."
21899
21900         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21901 }
21902 run_test 230b "migrate directory"
21903
21904 test_230c() {
21905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21907         remote_mds_nodsh && skip "remote MDS with nodsh"
21908         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21909                 skip "Need MDS version at least 2.11.52"
21910
21911         local MDTIDX=1
21912         local total=3
21913         local mdt_index
21914         local file
21915         local migrate_dir=$DIR/$tdir/migrate_dir
21916
21917         #If migrating directory fails in the middle, all entries of
21918         #the directory is still accessiable.
21919         test_mkdir $DIR/$tdir
21920         test_mkdir -i0 -c1 $migrate_dir
21921         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21922         stat $migrate_dir
21923         createmany -o $migrate_dir/f $total ||
21924                 error "create files under ${migrate_dir} failed"
21925
21926         # fail after migrating top dir, and this will fail only once, so the
21927         # first sub file migration will fail (currently f3), others succeed.
21928         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21929         do_facet mds1 lctl set_param fail_loc=0x1801
21930         local t=$(ls $migrate_dir | wc -l)
21931         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21932                 error "migrate should fail"
21933         local u=$(ls $migrate_dir | wc -l)
21934         [ "$u" == "$t" ] || error "$u != $t during migration"
21935
21936         # add new dir/file should succeed
21937         mkdir $migrate_dir/dir ||
21938                 error "mkdir failed under migrating directory"
21939         touch $migrate_dir/file ||
21940                 error "create file failed under migrating directory"
21941
21942         # add file with existing name should fail
21943         for file in $migrate_dir/f*; do
21944                 stat $file > /dev/null || error "stat $file failed"
21945                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21946                         error "open(O_CREAT|O_EXCL) $file should fail"
21947                 $MULTIOP $file m && error "create $file should fail"
21948                 touch $DIR/$tdir/remote_dir/$tfile ||
21949                         error "touch $tfile failed"
21950                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21951                         error "link $file should fail"
21952                 mdt_index=$($LFS getstripe -m $file)
21953                 if [ $mdt_index == 0 ]; then
21954                         # file failed to migrate is not allowed to rename to
21955                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21956                                 error "rename to $file should fail"
21957                 else
21958                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21959                                 error "rename to $file failed"
21960                 fi
21961                 echo hello >> $file || error "write $file failed"
21962         done
21963
21964         # resume migration with different options should fail
21965         $LFS migrate -m 0 $migrate_dir &&
21966                 error "migrate -m 0 $migrate_dir should fail"
21967
21968         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21969                 error "migrate -c 2 $migrate_dir should fail"
21970
21971         # resume migration should succeed
21972         $LFS migrate -m $MDTIDX $migrate_dir ||
21973                 error "migrate $migrate_dir failed"
21974
21975         echo "Finish migration, then checking.."
21976         for file in $(find $migrate_dir); do
21977                 mdt_index=$($LFS getstripe -m $file)
21978                 [ $mdt_index == $MDTIDX ] ||
21979                         error "$file is not on MDT${MDTIDX}"
21980         done
21981
21982         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21983 }
21984 run_test 230c "check directory accessiblity if migration failed"
21985
21986 test_230d() {
21987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21989         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21990                 skip "Need MDS version at least 2.11.52"
21991         # LU-11235
21992         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21993
21994         local migrate_dir=$DIR/$tdir/migrate_dir
21995         local old_index
21996         local new_index
21997         local old_count
21998         local new_count
21999         local new_hash
22000         local mdt_index
22001         local i
22002         local j
22003
22004         old_index=$((RANDOM % MDSCOUNT))
22005         old_count=$((MDSCOUNT - old_index))
22006         new_index=$((RANDOM % MDSCOUNT))
22007         new_count=$((MDSCOUNT - new_index))
22008         new_hash=1 # for all_char
22009
22010         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22011         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22012
22013         test_mkdir $DIR/$tdir
22014         test_mkdir -i $old_index -c $old_count $migrate_dir
22015
22016         for ((i=0; i<100; i++)); do
22017                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22018                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22019                         error "create files under remote dir failed $i"
22020         done
22021
22022         echo -n "Migrate from MDT$old_index "
22023         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22024         echo -n "to MDT$new_index"
22025         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22026         echo
22027
22028         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22029         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22030                 error "migrate remote dir error"
22031
22032         echo "Finish migration, then checking.."
22033         for file in $(find $migrate_dir -maxdepth 1); do
22034                 mdt_index=$($LFS getstripe -m $file)
22035                 if [ $mdt_index -lt $new_index ] ||
22036                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22037                         error "$file is on MDT$mdt_index"
22038                 fi
22039         done
22040
22041         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22042 }
22043 run_test 230d "check migrate big directory"
22044
22045 test_230e() {
22046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22048         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22049                 skip "Need MDS version at least 2.11.52"
22050
22051         local i
22052         local j
22053         local a_fid
22054         local b_fid
22055
22056         mkdir_on_mdt0 $DIR/$tdir
22057         mkdir $DIR/$tdir/migrate_dir
22058         mkdir $DIR/$tdir/other_dir
22059         touch $DIR/$tdir/migrate_dir/a
22060         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22061         ls $DIR/$tdir/other_dir
22062
22063         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22064                 error "migrate dir fails"
22065
22066         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22067         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22068
22069         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22070         [ $mdt_index == 0 ] || error "a is not on MDT0"
22071
22072         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22073                 error "migrate dir fails"
22074
22075         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22076         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22077
22078         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22079         [ $mdt_index == 1 ] || error "a is not on MDT1"
22080
22081         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22082         [ $mdt_index == 1 ] || error "b is not on MDT1"
22083
22084         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22085         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22086
22087         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22088
22089         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22090 }
22091 run_test 230e "migrate mulitple local link files"
22092
22093 test_230f() {
22094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22095         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22096         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22097                 skip "Need MDS version at least 2.11.52"
22098
22099         local a_fid
22100         local ln_fid
22101
22102         mkdir -p $DIR/$tdir
22103         mkdir $DIR/$tdir/migrate_dir
22104         $LFS mkdir -i1 $DIR/$tdir/other_dir
22105         touch $DIR/$tdir/migrate_dir/a
22106         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22107         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22108         ls $DIR/$tdir/other_dir
22109
22110         # a should be migrated to MDT1, since no other links on MDT0
22111         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22112                 error "#1 migrate dir fails"
22113         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22114         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22115         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22116         [ $mdt_index == 1 ] || error "a is not on MDT1"
22117
22118         # a should stay on MDT1, because it is a mulitple link file
22119         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22120                 error "#2 migrate dir fails"
22121         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22122         [ $mdt_index == 1 ] || error "a is not on MDT1"
22123
22124         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22125                 error "#3 migrate dir fails"
22126
22127         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22128         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22129         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22130
22131         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22132         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22133
22134         # a should be migrated to MDT0, since no other links on MDT1
22135         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22136                 error "#4 migrate dir fails"
22137         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22138         [ $mdt_index == 0 ] || error "a is not on MDT0"
22139
22140         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22141 }
22142 run_test 230f "migrate mulitple remote link files"
22143
22144 test_230g() {
22145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22147         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22148                 skip "Need MDS version at least 2.11.52"
22149
22150         mkdir -p $DIR/$tdir/migrate_dir
22151
22152         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22153                 error "migrating dir to non-exist MDT succeeds"
22154         true
22155 }
22156 run_test 230g "migrate dir to non-exist MDT"
22157
22158 test_230h() {
22159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22161         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22162                 skip "Need MDS version at least 2.11.52"
22163
22164         local mdt_index
22165
22166         mkdir -p $DIR/$tdir/migrate_dir
22167
22168         $LFS migrate -m1 $DIR &&
22169                 error "migrating mountpoint1 should fail"
22170
22171         $LFS migrate -m1 $DIR/$tdir/.. &&
22172                 error "migrating mountpoint2 should fail"
22173
22174         # same as mv
22175         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22176                 error "migrating $tdir/migrate_dir/.. should fail"
22177
22178         true
22179 }
22180 run_test 230h "migrate .. and root"
22181
22182 test_230i() {
22183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22184         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22185         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22186                 skip "Need MDS version at least 2.11.52"
22187
22188         mkdir -p $DIR/$tdir/migrate_dir
22189
22190         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22191                 error "migration fails with a tailing slash"
22192
22193         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22194                 error "migration fails with two tailing slashes"
22195 }
22196 run_test 230i "lfs migrate -m tolerates trailing slashes"
22197
22198 test_230j() {
22199         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22200         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22201                 skip "Need MDS version at least 2.11.52"
22202
22203         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22204         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22205                 error "create $tfile failed"
22206         cat /etc/passwd > $DIR/$tdir/$tfile
22207
22208         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22209
22210         cmp /etc/passwd $DIR/$tdir/$tfile ||
22211                 error "DoM file mismatch after migration"
22212 }
22213 run_test 230j "DoM file data not changed after dir migration"
22214
22215 test_230k() {
22216         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22217         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22218                 skip "Need MDS version at least 2.11.56"
22219
22220         local total=20
22221         local files_on_starting_mdt=0
22222
22223         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22224         $LFS getdirstripe $DIR/$tdir
22225         for i in $(seq $total); do
22226                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22227                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22228                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22229         done
22230
22231         echo "$files_on_starting_mdt files on MDT0"
22232
22233         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22234         $LFS getdirstripe $DIR/$tdir
22235
22236         files_on_starting_mdt=0
22237         for i in $(seq $total); do
22238                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22239                         error "file $tfile.$i mismatch after migration"
22240                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22241                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22242         done
22243
22244         echo "$files_on_starting_mdt files on MDT1 after migration"
22245         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22246
22247         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22248         $LFS getdirstripe $DIR/$tdir
22249
22250         files_on_starting_mdt=0
22251         for i in $(seq $total); do
22252                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22253                         error "file $tfile.$i mismatch after 2nd migration"
22254                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22255                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22256         done
22257
22258         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22259         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22260
22261         true
22262 }
22263 run_test 230k "file data not changed after dir migration"
22264
22265 test_230l() {
22266         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22267         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22268                 skip "Need MDS version at least 2.11.56"
22269
22270         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22271         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22272                 error "create files under remote dir failed $i"
22273         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22274 }
22275 run_test 230l "readdir between MDTs won't crash"
22276
22277 test_230m() {
22278         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22279         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22280                 skip "Need MDS version at least 2.11.56"
22281
22282         local MDTIDX=1
22283         local mig_dir=$DIR/$tdir/migrate_dir
22284         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22285         local shortstr="b"
22286         local val
22287
22288         echo "Creating files and dirs with xattrs"
22289         test_mkdir $DIR/$tdir
22290         test_mkdir -i0 -c1 $mig_dir
22291         mkdir $mig_dir/dir
22292         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22293                 error "cannot set xattr attr1 on dir"
22294         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22295                 error "cannot set xattr attr2 on dir"
22296         touch $mig_dir/dir/f0
22297         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22298                 error "cannot set xattr attr1 on file"
22299         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22300                 error "cannot set xattr attr2 on file"
22301         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22302         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22303         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22304         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22305         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22306         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22307         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22308         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22309         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22310
22311         echo "Migrating to MDT1"
22312         $LFS migrate -m $MDTIDX $mig_dir ||
22313                 error "fails on migrating dir to MDT1"
22314
22315         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22316         echo "Checking xattrs"
22317         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22318         [ "$val" = $longstr ] ||
22319                 error "expecting xattr1 $longstr on dir, found $val"
22320         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22321         [ "$val" = $shortstr ] ||
22322                 error "expecting xattr2 $shortstr on dir, found $val"
22323         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22324         [ "$val" = $longstr ] ||
22325                 error "expecting xattr1 $longstr on file, found $val"
22326         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22327         [ "$val" = $shortstr ] ||
22328                 error "expecting xattr2 $shortstr on file, found $val"
22329 }
22330 run_test 230m "xattrs not changed after dir migration"
22331
22332 test_230n() {
22333         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22334         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22335                 skip "Need MDS version at least 2.13.53"
22336
22337         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22338         cat /etc/hosts > $DIR/$tdir/$tfile
22339         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22340         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22341
22342         cmp /etc/hosts $DIR/$tdir/$tfile ||
22343                 error "File data mismatch after migration"
22344 }
22345 run_test 230n "Dir migration with mirrored file"
22346
22347 test_230o() {
22348         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22349         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22350                 skip "Need MDS version at least 2.13.52"
22351
22352         local mdts=$(comma_list $(mdts_nodes))
22353         local timeout=100
22354         local restripe_status
22355         local delta
22356         local i
22357
22358         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22359
22360         # in case "crush" hash type is not set
22361         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22362
22363         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22364                            mdt.*MDT0000.enable_dir_restripe)
22365         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22366         stack_trap "do_nodes $mdts $LCTL set_param \
22367                     mdt.*.enable_dir_restripe=$restripe_status"
22368
22369         mkdir $DIR/$tdir
22370         createmany -m $DIR/$tdir/f 100 ||
22371                 error "create files under remote dir failed $i"
22372         createmany -d $DIR/$tdir/d 100 ||
22373                 error "create dirs under remote dir failed $i"
22374
22375         for i in $(seq 2 $MDSCOUNT); do
22376                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22377                 $LFS setdirstripe -c $i $DIR/$tdir ||
22378                         error "split -c $i $tdir failed"
22379                 wait_update $HOSTNAME \
22380                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22381                         error "dir split not finished"
22382                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22383                         awk '/migrate/ {sum += $2} END { print sum }')
22384                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22385                 # delta is around total_files/stripe_count
22386                 (( $delta < 200 / (i - 1) + 4 )) ||
22387                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22388         done
22389 }
22390 run_test 230o "dir split"
22391
22392 test_230p() {
22393         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22394         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22395                 skip "Need MDS version at least 2.13.52"
22396
22397         local mdts=$(comma_list $(mdts_nodes))
22398         local timeout=100
22399         local restripe_status
22400         local delta
22401         local c
22402
22403         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22404
22405         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22406
22407         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22408                            mdt.*MDT0000.enable_dir_restripe)
22409         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22410         stack_trap "do_nodes $mdts $LCTL set_param \
22411                     mdt.*.enable_dir_restripe=$restripe_status"
22412
22413         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22414         createmany -m $DIR/$tdir/f 100 ||
22415                 error "create files under remote dir failed"
22416         createmany -d $DIR/$tdir/d 100 ||
22417                 error "create dirs under remote dir failed"
22418
22419         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22420                 local mdt_hash="crush"
22421
22422                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22423                 $LFS setdirstripe -c $c $DIR/$tdir ||
22424                         error "split -c $c $tdir failed"
22425                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22426                         mdt_hash="$mdt_hash,fixed"
22427                 elif [ $c -eq 1 ]; then
22428                         mdt_hash="none"
22429                 fi
22430                 wait_update $HOSTNAME \
22431                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22432                         error "dir merge not finished"
22433                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22434                         awk '/migrate/ {sum += $2} END { print sum }')
22435                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22436                 # delta is around total_files/stripe_count
22437                 (( delta < 200 / c + 4 )) ||
22438                         error "$delta files migrated >= $((200 / c + 4))"
22439         done
22440 }
22441 run_test 230p "dir merge"
22442
22443 test_230q() {
22444         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22445         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22446                 skip "Need MDS version at least 2.13.52"
22447
22448         local mdts=$(comma_list $(mdts_nodes))
22449         local saved_threshold=$(do_facet mds1 \
22450                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22451         local saved_delta=$(do_facet mds1 \
22452                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22453         local threshold=100
22454         local delta=2
22455         local total=0
22456         local stripe_count=0
22457         local stripe_index
22458         local nr_files
22459         local create
22460
22461         # test with fewer files on ZFS
22462         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22463
22464         stack_trap "do_nodes $mdts $LCTL set_param \
22465                     mdt.*.dir_split_count=$saved_threshold"
22466         stack_trap "do_nodes $mdts $LCTL set_param \
22467                     mdt.*.dir_split_delta=$saved_delta"
22468         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22469         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22470         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22471         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22472         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22473         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22474
22475         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22476         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22477
22478         create=$((threshold * 3 / 2))
22479         while [ $stripe_count -lt $MDSCOUNT ]; do
22480                 createmany -m $DIR/$tdir/f $total $create ||
22481                         error "create sub files failed"
22482                 stat $DIR/$tdir > /dev/null
22483                 total=$((total + create))
22484                 stripe_count=$((stripe_count + delta))
22485                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22486
22487                 wait_update $HOSTNAME \
22488                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22489                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22490
22491                 wait_update $HOSTNAME \
22492                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22493                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22494
22495                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22496                 echo "$nr_files/$total files on MDT$stripe_index after split"
22497                 # allow 10% margin of imbalance with crush hash
22498                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22499                         error "$nr_files files on MDT$stripe_index after split"
22500
22501                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22502                 [ $nr_files -eq $total ] ||
22503                         error "total sub files $nr_files != $total"
22504         done
22505
22506         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22507
22508         echo "fixed layout directory won't auto split"
22509         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22510         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22511                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22512         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22513                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22514 }
22515 run_test 230q "dir auto split"
22516
22517 test_230r() {
22518         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22519         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22520         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22521                 skip "Need MDS version at least 2.13.54"
22522
22523         # maximum amount of local locks:
22524         # parent striped dir - 2 locks
22525         # new stripe in parent to migrate to - 1 lock
22526         # source and target - 2 locks
22527         # Total 5 locks for regular file
22528         mkdir -p $DIR/$tdir
22529         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22530         touch $DIR/$tdir/dir1/eee
22531
22532         # create 4 hardlink for 4 more locks
22533         # Total: 9 locks > RS_MAX_LOCKS (8)
22534         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22535         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22536         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22537         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22538         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22539         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22540         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22541         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22542
22543         cancel_lru_locks mdc
22544
22545         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22546                 error "migrate dir fails"
22547
22548         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22549 }
22550 run_test 230r "migrate with too many local locks"
22551
22552 test_230s() {
22553         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22554                 skip "Need MDS version at least 2.14.52"
22555
22556         local mdts=$(comma_list $(mdts_nodes))
22557         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22558                                 mdt.*MDT0000.enable_dir_restripe)
22559
22560         stack_trap "do_nodes $mdts $LCTL set_param \
22561                     mdt.*.enable_dir_restripe=$restripe_status"
22562
22563         local st
22564         for st in 0 1; do
22565                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22566                 test_mkdir $DIR/$tdir
22567                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22568                         error "$LFS mkdir should return EEXIST if target exists"
22569                 rmdir $DIR/$tdir
22570         done
22571 }
22572 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22573
22574 test_230t()
22575 {
22576         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22577         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22578                 skip "Need MDS version at least 2.14.50"
22579
22580         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22581         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22582         $LFS project -p 1 -s $DIR/$tdir ||
22583                 error "set $tdir project id failed"
22584         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22585                 error "set subdir project id failed"
22586         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22587 }
22588 run_test 230t "migrate directory with project ID set"
22589
22590 test_230u()
22591 {
22592         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22593         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22594                 skip "Need MDS version at least 2.14.53"
22595
22596         local count
22597
22598         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22599         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22600         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22601         for i in $(seq 0 $((MDSCOUNT - 1))); do
22602                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22603                 echo "$count dirs migrated to MDT$i"
22604         done
22605         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22606         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22607 }
22608 run_test 230u "migrate directory by QOS"
22609
22610 test_230v()
22611 {
22612         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22613         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22614                 skip "Need MDS version at least 2.14.53"
22615
22616         local count
22617
22618         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22619         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22620         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22621         for i in $(seq 0 $((MDSCOUNT - 1))); do
22622                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22623                 echo "$count subdirs migrated to MDT$i"
22624                 (( i == 3 )) && (( count > 0 )) &&
22625                         error "subdir shouldn't be migrated to MDT3"
22626         done
22627         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22628         (( count == 3 )) || error "dirs migrated to $count MDTs"
22629 }
22630 run_test 230v "subdir migrated to the MDT where its parent is located"
22631
22632 test_230w() {
22633         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22634         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22635                 skip "Need MDS version at least 2.15.0"
22636
22637         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22638         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22639         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22640
22641         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22642                 error "migrate failed"
22643
22644         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22645                 error "$tdir stripe count mismatch"
22646
22647         for i in $(seq 0 9); do
22648                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22649                         error "d$i is striped"
22650         done
22651 }
22652 run_test 230w "non-recursive mode dir migration"
22653
22654 test_230x() {
22655         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22656         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22657                 skip "Need MDS version at least 2.15.0"
22658
22659         mkdir -p $DIR/$tdir || error "mkdir failed"
22660         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22661
22662         local mdt_name=$(mdtname_from_index 0)
22663         local low=$(do_facet mds2 $LCTL get_param -n \
22664                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22665         local high=$(do_facet mds2 $LCTL get_param -n \
22666                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22667         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22668         local maxage=$(do_facet mds2 $LCTL get_param -n \
22669                 osp.*$mdt_name-osp-MDT0001.maxage)
22670
22671         stack_trap "do_facet mds2 $LCTL set_param -n \
22672                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22673                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22674         stack_trap "do_facet mds2 $LCTL set_param -n \
22675                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22676
22677         do_facet mds2 $LCTL set_param -n \
22678                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22679         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22680         sleep 4
22681         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22682                 error "migrate $tdir should fail"
22683
22684         do_facet mds2 $LCTL set_param -n \
22685                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22686         do_facet mds2 $LCTL set_param -n \
22687                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22688         sleep 4
22689         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22690                 error "migrate failed"
22691         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22692                 error "$tdir stripe count mismatch"
22693 }
22694 run_test 230x "dir migration check space"
22695
22696 test_230y() {
22697         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22698         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22699                 skip "Need MDS version at least 2.15.55.45"
22700
22701         local pid
22702
22703         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22704         $LFS getdirstripe $DIR/$tdir
22705         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22706         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22707         pid=$!
22708         sleep 1
22709
22710         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22711         do_facet mds2 lctl set_param fail_loc=0x1802
22712
22713         wait $pid
22714         do_facet mds2 lctl set_param fail_loc=0
22715         $LFS getdirstripe $DIR/$tdir
22716         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22717         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22718 }
22719 run_test 230y "unlink dir with bad hash type"
22720
22721 test_230z() {
22722         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22723         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22724                 skip "Need MDS version at least 2.15.55.45"
22725
22726         local pid
22727
22728         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22729         $LFS getdirstripe $DIR/$tdir
22730         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22731         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22732         pid=$!
22733         sleep 1
22734
22735         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22736         do_facet mds2 lctl set_param fail_loc=0x1802
22737
22738         wait $pid
22739         do_facet mds2 lctl set_param fail_loc=0
22740         $LFS getdirstripe $DIR/$tdir
22741
22742         # resume migration
22743         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22744                 error "resume migration failed"
22745         $LFS getdirstripe $DIR/$tdir
22746         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22747                 error "migration is not finished"
22748 }
22749 run_test 230z "resume dir migration with bad hash type"
22750
22751 test_231a()
22752 {
22753         # For simplicity this test assumes that max_pages_per_rpc
22754         # is the same across all OSCs
22755         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22756         local bulk_size=$((max_pages * PAGE_SIZE))
22757         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22758                                        head -n 1)
22759
22760         mkdir -p $DIR/$tdir
22761         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22762                 error "failed to set stripe with -S ${brw_size}M option"
22763         stack_trap "rm -rf $DIR/$tdir"
22764
22765         # clear the OSC stats
22766         $LCTL set_param osc.*.stats=0 &>/dev/null
22767         stop_writeback
22768
22769         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22770         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22771                 oflag=direct &>/dev/null || error "dd failed"
22772
22773         sync; sleep 1; sync # just to be safe
22774         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22775         if [ x$nrpcs != "x1" ]; then
22776                 $LCTL get_param osc.*.stats
22777                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22778         fi
22779
22780         start_writeback
22781         # Drop the OSC cache, otherwise we will read from it
22782         cancel_lru_locks osc
22783
22784         # clear the OSC stats
22785         $LCTL set_param osc.*.stats=0 &>/dev/null
22786
22787         # Client reads $bulk_size.
22788         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22789                 iflag=direct &>/dev/null || error "dd failed"
22790
22791         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22792         if [ x$nrpcs != "x1" ]; then
22793                 $LCTL get_param osc.*.stats
22794                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22795         fi
22796 }
22797 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22798
22799 test_231b() {
22800         mkdir -p $DIR/$tdir
22801         stack_trap "rm -rf $DIR/$tdir"
22802         local i
22803         for i in {0..1023}; do
22804                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22805                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22806                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22807         done
22808         sync
22809 }
22810 run_test 231b "must not assert on fully utilized OST request buffer"
22811
22812 test_232a() {
22813         mkdir -p $DIR/$tdir
22814         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22815
22816         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22817         do_facet ost1 $LCTL set_param fail_loc=0x31c
22818
22819         # ignore dd failure
22820         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22821         stack_trap "rm -f $DIR/$tdir/$tfile"
22822
22823         do_facet ost1 $LCTL set_param fail_loc=0
22824         umount_client $MOUNT || error "umount failed"
22825         mount_client $MOUNT || error "mount failed"
22826         stop ost1 || error "cannot stop ost1"
22827         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22828 }
22829 run_test 232a "failed lock should not block umount"
22830
22831 test_232b() {
22832         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22833                 skip "Need MDS version at least 2.10.58"
22834
22835         mkdir -p $DIR/$tdir
22836         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22837         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22838         stack_trap "rm -f $DIR/$tdir/$tfile"
22839         sync
22840         cancel_lru_locks osc
22841
22842         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22843         do_facet ost1 $LCTL set_param fail_loc=0x31c
22844
22845         # ignore failure
22846         $LFS data_version $DIR/$tdir/$tfile || true
22847
22848         do_facet ost1 $LCTL set_param fail_loc=0
22849         umount_client $MOUNT || error "umount failed"
22850         mount_client $MOUNT || error "mount failed"
22851         stop ost1 || error "cannot stop ost1"
22852         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22853 }
22854 run_test 232b "failed data version lock should not block umount"
22855
22856 test_233a() {
22857         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22858                 skip "Need MDS version at least 2.3.64"
22859         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22860
22861         local fid=$($LFS path2fid $MOUNT)
22862
22863         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22864                 error "cannot access $MOUNT using its FID '$fid'"
22865 }
22866 run_test 233a "checking that OBF of the FS root succeeds"
22867
22868 test_233b() {
22869         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22870                 skip "Need MDS version at least 2.5.90"
22871         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22872
22873         local fid=$($LFS path2fid $MOUNT/.lustre)
22874
22875         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22876                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22877
22878         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22879         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22880                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22881 }
22882 run_test 233b "checking that OBF of the FS .lustre succeeds"
22883
22884 test_234() {
22885         local p="$TMP/sanityN-$TESTNAME.parameters"
22886         save_lustre_params client "llite.*.xattr_cache" > $p
22887         lctl set_param llite.*.xattr_cache 1 ||
22888                 skip_env "xattr cache is not supported"
22889
22890         mkdir -p $DIR/$tdir || error "mkdir failed"
22891         touch $DIR/$tdir/$tfile || error "touch failed"
22892         # OBD_FAIL_LLITE_XATTR_ENOMEM
22893         $LCTL set_param fail_loc=0x1405
22894         getfattr -n user.attr $DIR/$tdir/$tfile &&
22895                 error "getfattr should have failed with ENOMEM"
22896         $LCTL set_param fail_loc=0x0
22897         rm -rf $DIR/$tdir
22898
22899         restore_lustre_params < $p
22900         rm -f $p
22901 }
22902 run_test 234 "xattr cache should not crash on ENOMEM"
22903
22904 test_235() {
22905         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22906                 skip "Need MDS version at least 2.4.52"
22907
22908         flock_deadlock $DIR/$tfile
22909         local RC=$?
22910         case $RC in
22911                 0)
22912                 ;;
22913                 124) error "process hangs on a deadlock"
22914                 ;;
22915                 *) error "error executing flock_deadlock $DIR/$tfile"
22916                 ;;
22917         esac
22918 }
22919 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22920
22921 #LU-2935
22922 test_236() {
22923         check_swap_layouts_support
22924
22925         local ref1=/etc/passwd
22926         local ref2=/etc/group
22927         local file1=$DIR/$tdir/f1
22928         local file2=$DIR/$tdir/f2
22929
22930         test_mkdir -c1 $DIR/$tdir
22931         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22932         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22933         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22934         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22935         local fd=$(free_fd)
22936         local cmd="exec $fd<>$file2"
22937         eval $cmd
22938         rm $file2
22939         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22940                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22941         cmd="exec $fd>&-"
22942         eval $cmd
22943         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22944
22945         #cleanup
22946         rm -rf $DIR/$tdir
22947 }
22948 run_test 236 "Layout swap on open unlinked file"
22949
22950 # LU-4659 linkea consistency
22951 test_238() {
22952         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22953                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22954                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22955                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22956
22957         touch $DIR/$tfile
22958         ln $DIR/$tfile $DIR/$tfile.lnk
22959         touch $DIR/$tfile.new
22960         mv $DIR/$tfile.new $DIR/$tfile
22961         local fid1=$($LFS path2fid $DIR/$tfile)
22962         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22963         local path1=$($LFS fid2path $FSNAME "$fid1")
22964         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22965         local path2=$($LFS fid2path $FSNAME "$fid2")
22966         [ $tfile.lnk == $path2 ] ||
22967                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22968         rm -f $DIR/$tfile*
22969 }
22970 run_test 238 "Verify linkea consistency"
22971
22972 test_239A() { # was test_239
22973         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22974                 skip "Need MDS version at least 2.5.60"
22975
22976         local list=$(comma_list $(mdts_nodes))
22977
22978         mkdir -p $DIR/$tdir
22979         createmany -o $DIR/$tdir/f- 5000
22980         unlinkmany $DIR/$tdir/f- 5000
22981         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22982                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22983         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22984                         osp.*MDT*.sync_in_flight" | calc_sum)
22985         [ "$changes" -eq 0 ] || error "$changes not synced"
22986 }
22987 run_test 239A "osp_sync test"
22988
22989 test_239a() { #LU-5297
22990         remote_mds_nodsh && skip "remote MDS with nodsh"
22991
22992         touch $DIR/$tfile
22993         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22994         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22995         chgrp $RUNAS_GID $DIR/$tfile
22996         wait_delete_completed
22997 }
22998 run_test 239a "process invalid osp sync record correctly"
22999
23000 test_239b() { #LU-5297
23001         remote_mds_nodsh && skip "remote MDS with nodsh"
23002
23003         touch $DIR/$tfile1
23004         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23005         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23006         chgrp $RUNAS_GID $DIR/$tfile1
23007         wait_delete_completed
23008         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23009         touch $DIR/$tfile2
23010         chgrp $RUNAS_GID $DIR/$tfile2
23011         wait_delete_completed
23012 }
23013 run_test 239b "process osp sync record with ENOMEM error correctly"
23014
23015 test_240() {
23016         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23017         remote_mds_nodsh && skip "remote MDS with nodsh"
23018
23019         mkdir -p $DIR/$tdir
23020
23021         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23022                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23023         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23024                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23025
23026         umount_client $MOUNT || error "umount failed"
23027         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23028         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23029         mount_client $MOUNT || error "failed to mount client"
23030
23031         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23032         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23033 }
23034 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23035
23036 test_241_bio() {
23037         local count=$1
23038         local bsize=$2
23039
23040         for LOOP in $(seq $count); do
23041                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23042                 cancel_lru_locks $OSC || true
23043         done
23044 }
23045
23046 test_241_dio() {
23047         local count=$1
23048         local bsize=$2
23049
23050         for LOOP in $(seq $1); do
23051                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23052                         2>/dev/null
23053         done
23054 }
23055
23056 test_241a() { # was test_241
23057         local bsize=$PAGE_SIZE
23058
23059         (( bsize < 40960 )) && bsize=40960
23060         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23061         ls -la $DIR/$tfile
23062         cancel_lru_locks $OSC
23063         test_241_bio 1000 $bsize &
23064         PID=$!
23065         test_241_dio 1000 $bsize
23066         wait $PID
23067 }
23068 run_test 241a "bio vs dio"
23069
23070 test_241b() {
23071         local bsize=$PAGE_SIZE
23072
23073         (( bsize < 40960 )) && bsize=40960
23074         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23075         ls -la $DIR/$tfile
23076         test_241_dio 1000 $bsize &
23077         PID=$!
23078         test_241_dio 1000 $bsize
23079         wait $PID
23080 }
23081 run_test 241b "dio vs dio"
23082
23083 test_242() {
23084         remote_mds_nodsh && skip "remote MDS with nodsh"
23085
23086         mkdir_on_mdt0 $DIR/$tdir
23087         touch $DIR/$tdir/$tfile
23088
23089         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23090         do_facet mds1 lctl set_param fail_loc=0x105
23091         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23092
23093         do_facet mds1 lctl set_param fail_loc=0
23094         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23095 }
23096 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23097
23098 test_243()
23099 {
23100         test_mkdir $DIR/$tdir
23101         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23102 }
23103 run_test 243 "various group lock tests"
23104
23105 test_244a()
23106 {
23107         test_mkdir $DIR/$tdir
23108         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23109         sendfile_grouplock $DIR/$tdir/$tfile || \
23110                 error "sendfile+grouplock failed"
23111         rm -rf $DIR/$tdir
23112 }
23113 run_test 244a "sendfile with group lock tests"
23114
23115 test_244b()
23116 {
23117         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23118
23119         local threads=50
23120         local size=$((1024*1024))
23121
23122         test_mkdir $DIR/$tdir
23123         for i in $(seq 1 $threads); do
23124                 local file=$DIR/$tdir/file_$((i / 10))
23125                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23126                 local pids[$i]=$!
23127         done
23128         for i in $(seq 1 $threads); do
23129                 wait ${pids[$i]}
23130         done
23131 }
23132 run_test 244b "multi-threaded write with group lock"
23133
23134 test_245a() {
23135         local flagname="multi_mod_rpcs"
23136         local connect_data_name="max_mod_rpcs"
23137         local out
23138
23139         # check if multiple modify RPCs flag is set
23140         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23141                 grep "connect_flags:")
23142         echo "$out"
23143
23144         echo "$out" | grep -qw $flagname
23145         if [ $? -ne 0 ]; then
23146                 echo "connect flag $flagname is not set"
23147                 return
23148         fi
23149
23150         # check if multiple modify RPCs data is set
23151         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23152         echo "$out"
23153
23154         echo "$out" | grep -qw $connect_data_name ||
23155                 error "import should have connect data $connect_data_name"
23156 }
23157 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23158
23159 test_245b() {
23160         local flagname="multi_mod_rpcs"
23161         local connect_data_name="max_mod_rpcs"
23162         local out
23163
23164         remote_mds_nodsh && skip "remote MDS with nodsh"
23165         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23166
23167         # check if multiple modify RPCs flag is set
23168         out=$(do_facet mds1 \
23169               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23170               grep "connect_flags:")
23171         echo "$out"
23172
23173         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23174
23175         # check if multiple modify RPCs data is set
23176         out=$(do_facet mds1 \
23177               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23178
23179         [[ "$out" =~ $connect_data_name ]] ||
23180                 {
23181                         echo "$out"
23182                         error "missing connect data $connect_data_name"
23183                 }
23184 }
23185 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23186
23187 cleanup_247() {
23188         local submount=$1
23189
23190         trap 0
23191         umount_client $submount
23192         rmdir $submount
23193 }
23194
23195 test_247a() {
23196         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23197                 grep -q subtree ||
23198                 skip_env "Fileset feature is not supported"
23199
23200         local submount=${MOUNT}_$tdir
23201
23202         mkdir $MOUNT/$tdir
23203         mkdir -p $submount || error "mkdir $submount failed"
23204         FILESET="$FILESET/$tdir" mount_client $submount ||
23205                 error "mount $submount failed"
23206         trap "cleanup_247 $submount" EXIT
23207         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23208         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23209                 error "read $MOUNT/$tdir/$tfile failed"
23210         cleanup_247 $submount
23211 }
23212 run_test 247a "mount subdir as fileset"
23213
23214 test_247b() {
23215         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23216                 skip_env "Fileset feature is not supported"
23217
23218         local submount=${MOUNT}_$tdir
23219
23220         rm -rf $MOUNT/$tdir
23221         mkdir -p $submount || error "mkdir $submount failed"
23222         SKIP_FILESET=1
23223         FILESET="$FILESET/$tdir" mount_client $submount &&
23224                 error "mount $submount should fail"
23225         rmdir $submount
23226 }
23227 run_test 247b "mount subdir that dose not exist"
23228
23229 test_247c() {
23230         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23231                 skip_env "Fileset feature is not supported"
23232
23233         local submount=${MOUNT}_$tdir
23234
23235         mkdir -p $MOUNT/$tdir/dir1
23236         mkdir -p $submount || error "mkdir $submount failed"
23237         trap "cleanup_247 $submount" EXIT
23238         FILESET="$FILESET/$tdir" mount_client $submount ||
23239                 error "mount $submount failed"
23240         local fid=$($LFS path2fid $MOUNT/)
23241         $LFS fid2path $submount $fid && error "fid2path should fail"
23242         cleanup_247 $submount
23243 }
23244 run_test 247c "running fid2path outside subdirectory root"
23245
23246 test_247d() {
23247         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23248                 skip "Fileset feature is not supported"
23249
23250         local submount=${MOUNT}_$tdir
23251
23252         mkdir -p $MOUNT/$tdir/dir1
23253         mkdir -p $submount || error "mkdir $submount failed"
23254         FILESET="$FILESET/$tdir" mount_client $submount ||
23255                 error "mount $submount failed"
23256         trap "cleanup_247 $submount" EXIT
23257
23258         local td=$submount/dir1
23259         local fid=$($LFS path2fid $td)
23260         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23261
23262         # check that we get the same pathname back
23263         local rootpath
23264         local found
23265         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23266                 echo "$rootpath $fid"
23267                 found=$($LFS fid2path $rootpath "$fid")
23268                 [ -n "$found" ] || error "fid2path should succeed"
23269                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23270         done
23271         # check wrong root path format
23272         rootpath=$submount"_wrong"
23273         found=$($LFS fid2path $rootpath "$fid")
23274         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23275
23276         cleanup_247 $submount
23277 }
23278 run_test 247d "running fid2path inside subdirectory root"
23279
23280 # LU-8037
23281 test_247e() {
23282         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23283                 grep -q subtree ||
23284                 skip "Fileset feature is not supported"
23285
23286         local submount=${MOUNT}_$tdir
23287
23288         mkdir $MOUNT/$tdir
23289         mkdir -p $submount || error "mkdir $submount failed"
23290         FILESET="$FILESET/.." mount_client $submount &&
23291                 error "mount $submount should fail"
23292         rmdir $submount
23293 }
23294 run_test 247e "mount .. as fileset"
23295
23296 test_247f() {
23297         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23298         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23299                 skip "Need at least version 2.14.50.162"
23300         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23301                 skip "Fileset feature is not supported"
23302
23303         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23304         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23305                 error "mkdir remote failed"
23306         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23307                 error "mkdir remote/subdir failed"
23308         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23309                 error "mkdir striped failed"
23310         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23311
23312         local submount=${MOUNT}_$tdir
23313
23314         mkdir -p $submount || error "mkdir $submount failed"
23315         stack_trap "rmdir $submount"
23316
23317         local dir
23318         local fileset=$FILESET
23319         local mdts=$(comma_list $(mdts_nodes))
23320
23321         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23322         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23323                 $tdir/striped/subdir $tdir/striped/.; do
23324                 FILESET="$fileset/$dir" mount_client $submount ||
23325                         error "mount $dir failed"
23326                 umount_client $submount
23327         done
23328 }
23329 run_test 247f "mount striped or remote directory as fileset"
23330
23331 test_subdir_mount_lock()
23332 {
23333         local testdir=$1
23334         local submount=${MOUNT}_$(basename $testdir)
23335
23336         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23337
23338         mkdir -p $submount || error "mkdir $submount failed"
23339         stack_trap "rmdir $submount"
23340
23341         FILESET="$fileset/$testdir" mount_client $submount ||
23342                 error "mount $FILESET failed"
23343         stack_trap "umount $submount"
23344
23345         local mdts=$(comma_list $(mdts_nodes))
23346
23347         local nrpcs
23348
23349         stat $submount > /dev/null || error "stat $submount failed"
23350         cancel_lru_locks $MDC
23351         stat $submount > /dev/null || error "stat $submount failed"
23352         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23353         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23354         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23355         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23356                 awk '/getattr/ {sum += $2} END {print sum}')
23357
23358         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23359 }
23360
23361 test_247g() {
23362         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23363
23364         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23365                 error "mkdir $tdir failed"
23366         test_subdir_mount_lock $tdir
23367 }
23368 run_test 247g "striped directory submount revalidate ROOT from cache"
23369
23370 test_247h() {
23371         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23372         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23373                 skip "Need MDS version at least 2.15.51"
23374
23375         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23376         test_subdir_mount_lock $tdir
23377         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23378         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23379                 error "mkdir $tdir.1 failed"
23380         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23381 }
23382 run_test 247h "remote directory submount revalidate ROOT from cache"
23383
23384 test_248a() {
23385         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23386         [ -z "$fast_read_sav" ] && skip "no fast read support"
23387
23388         # create a large file for fast read verification
23389         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23390
23391         # make sure the file is created correctly
23392         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23393                 { rm -f $DIR/$tfile; skip "file creation error"; }
23394
23395         echo "Test 1: verify that fast read is 4 times faster on cache read"
23396
23397         # small read with fast read enabled
23398         $LCTL set_param -n llite.*.fast_read=1
23399         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23400                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23401                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23402         # small read with fast read disabled
23403         $LCTL set_param -n llite.*.fast_read=0
23404         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23405                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23406                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23407
23408         # verify that fast read is 4 times faster for cache read
23409         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23410                 error_not_in_vm "fast read was not 4 times faster: " \
23411                            "$t_fast vs $t_slow"
23412
23413         echo "Test 2: verify the performance between big and small read"
23414         $LCTL set_param -n llite.*.fast_read=1
23415
23416         # 1k non-cache read
23417         cancel_lru_locks osc
23418         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23419                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23420                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23421
23422         # 1M non-cache read
23423         cancel_lru_locks osc
23424         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23425                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23426                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23427
23428         # verify that big IO is not 4 times faster than small IO
23429         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23430                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23431
23432         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23433         rm -f $DIR/$tfile
23434 }
23435 run_test 248a "fast read verification"
23436
23437 test_248b() {
23438         # Default short_io_bytes=16384, try both smaller and larger sizes.
23439         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23440         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23441         echo "bs=53248 count=113 normal buffered write"
23442         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23443                 error "dd of initial data file failed"
23444         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23445
23446         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23447         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23448                 error "dd with sync normal writes failed"
23449         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23450
23451         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23452         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23453                 error "dd with sync small writes failed"
23454         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23455
23456         cancel_lru_locks osc
23457
23458         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23459         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23460         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23461         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23462                 iflag=direct || error "dd with O_DIRECT small read failed"
23463         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23464         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23465                 error "compare $TMP/$tfile.1 failed"
23466
23467         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23468         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23469
23470         # just to see what the maximum tunable value is, and test parsing
23471         echo "test invalid parameter 2MB"
23472         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23473                 error "too-large short_io_bytes allowed"
23474         echo "test maximum parameter 512KB"
23475         # if we can set a larger short_io_bytes, run test regardless of version
23476         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23477                 # older clients may not allow setting it this large, that's OK
23478                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23479                         skip "Need at least client version 2.13.50"
23480                 error "medium short_io_bytes failed"
23481         fi
23482         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23483         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23484
23485         echo "test large parameter 64KB"
23486         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23487         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23488
23489         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23490         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23491                 error "dd with sync large writes failed"
23492         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23493
23494         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23495         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23496         num=$((113 * 4096 / PAGE_SIZE))
23497         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23498         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23499                 error "dd with O_DIRECT large writes failed"
23500         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23501                 error "compare $DIR/$tfile.3 failed"
23502
23503         cancel_lru_locks osc
23504
23505         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23506         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23507                 error "dd with O_DIRECT large read failed"
23508         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23509                 error "compare $TMP/$tfile.2 failed"
23510
23511         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23512         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23513                 error "dd with O_DIRECT large read failed"
23514         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23515                 error "compare $TMP/$tfile.3 failed"
23516 }
23517 run_test 248b "test short_io read and write for both small and large sizes"
23518
23519 test_249() { # LU-7890
23520         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23521                 skip "Need at least version 2.8.54"
23522
23523         rm -f $DIR/$tfile
23524         $LFS setstripe -c 1 $DIR/$tfile
23525         # Offset 2T == 4k * 512M
23526         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23527                 error "dd to 2T offset failed"
23528 }
23529 run_test 249 "Write above 2T file size"
23530
23531 test_250() {
23532         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23533          && skip "no 16TB file size limit on ZFS"
23534
23535         $LFS setstripe -c 1 $DIR/$tfile
23536         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23537         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23538         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23539         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23540                 conv=notrunc,fsync && error "append succeeded"
23541         return 0
23542 }
23543 run_test 250 "Write above 16T limit"
23544
23545 test_251() {
23546         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23547
23548         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23549         #Skip once - writing the first stripe will succeed
23550         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23551         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23552                 error "short write happened"
23553
23554         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23555         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23556                 error "short read happened"
23557
23558         rm -f $DIR/$tfile
23559 }
23560 run_test 251 "Handling short read and write correctly"
23561
23562 test_252() {
23563         remote_mds_nodsh && skip "remote MDS with nodsh"
23564         remote_ost_nodsh && skip "remote OST with nodsh"
23565         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23566                 skip_env "ldiskfs only test"
23567         fi
23568
23569         local tgt
23570         local dev
23571         local out
23572         local uuid
23573         local num
23574         local gen
23575
23576         # check lr_reader on OST0000
23577         tgt=ost1
23578         dev=$(facet_device $tgt)
23579         out=$(do_facet $tgt $LR_READER $dev)
23580         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23581         echo "$out"
23582         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23583         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23584                 error "Invalid uuid returned by $LR_READER on target $tgt"
23585         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23586
23587         # check lr_reader -c on MDT0000
23588         tgt=mds1
23589         dev=$(facet_device $tgt)
23590         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23591                 skip "$LR_READER does not support additional options"
23592         fi
23593         out=$(do_facet $tgt $LR_READER -c $dev)
23594         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23595         echo "$out"
23596         num=$(echo "$out" | grep -c "mdtlov")
23597         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23598                 error "Invalid number of mdtlov clients returned by $LR_READER"
23599         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23600
23601         # check lr_reader -cr on MDT0000
23602         out=$(do_facet $tgt $LR_READER -cr $dev)
23603         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23604         echo "$out"
23605         echo "$out" | grep -q "^reply_data:$" ||
23606                 error "$LR_READER should have returned 'reply_data' section"
23607         num=$(echo "$out" | grep -c "client_generation")
23608         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23609 }
23610 run_test 252 "check lr_reader tool"
23611
23612 test_253() {
23613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23614         remote_mds_nodsh && skip "remote MDS with nodsh"
23615         remote_mgs_nodsh && skip "remote MGS with nodsh"
23616
23617         local ostidx=0
23618         local rc=0
23619         local ost_name=$(ostname_from_index $ostidx)
23620
23621         # on the mdt's osc
23622         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23623         do_facet $SINGLEMDS $LCTL get_param -n \
23624                 osp.$mdtosc_proc1.reserved_mb_high ||
23625                 skip  "remote MDS does not support reserved_mb_high"
23626
23627         rm -rf $DIR/$tdir
23628         wait_mds_ost_sync
23629         wait_delete_completed
23630         mkdir $DIR/$tdir
23631         stack_trap "rm -rf $DIR/$tdir"
23632
23633         pool_add $TESTNAME || error "Pool creation failed"
23634         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23635
23636         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23637                 error "Setstripe failed"
23638
23639         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23640
23641         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23642                     grep "watermarks")
23643         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23644
23645         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23646                         osp.$mdtosc_proc1.prealloc_status)
23647         echo "prealloc_status $oa_status"
23648
23649         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23650                 error "File creation should fail"
23651
23652         #object allocation was stopped, but we still able to append files
23653         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23654                 oflag=append || error "Append failed"
23655
23656         rm -f $DIR/$tdir/$tfile.0
23657
23658         # For this test, we want to delete the files we created to go out of
23659         # space but leave the watermark, so we remain nearly out of space
23660         ost_watermarks_enospc_delete_files $tfile $ostidx
23661
23662         wait_delete_completed
23663
23664         sleep_maxage
23665
23666         for i in $(seq 10 12); do
23667                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23668                         2>/dev/null || error "File creation failed after rm"
23669         done
23670
23671         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23672                         osp.$mdtosc_proc1.prealloc_status)
23673         echo "prealloc_status $oa_status"
23674
23675         if (( oa_status != 0 )); then
23676                 error "Object allocation still disable after rm"
23677         fi
23678 }
23679 run_test 253 "Check object allocation limit"
23680
23681 test_254() {
23682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23683         remote_mds_nodsh && skip "remote MDS with nodsh"
23684
23685         local mdt=$(facet_svc $SINGLEMDS)
23686
23687         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23688                 skip "MDS does not support changelog_size"
23689
23690         local cl_user
23691
23692         changelog_register || error "changelog_register failed"
23693
23694         changelog_clear 0 || error "changelog_clear failed"
23695
23696         local size1=$(do_facet $SINGLEMDS \
23697                       $LCTL get_param -n mdd.$mdt.changelog_size)
23698         echo "Changelog size $size1"
23699
23700         rm -rf $DIR/$tdir
23701         $LFS mkdir -i 0 $DIR/$tdir
23702         # change something
23703         mkdir -p $DIR/$tdir/pics/2008/zachy
23704         touch $DIR/$tdir/pics/2008/zachy/timestamp
23705         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23706         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23707         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23708         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23709         rm $DIR/$tdir/pics/desktop.jpg
23710
23711         local size2=$(do_facet $SINGLEMDS \
23712                       $LCTL get_param -n mdd.$mdt.changelog_size)
23713         echo "Changelog size after work $size2"
23714
23715         (( $size2 > $size1 )) ||
23716                 error "new Changelog size=$size2 less than old size=$size1"
23717 }
23718 run_test 254 "Check changelog size"
23719
23720 ladvise_no_type()
23721 {
23722         local type=$1
23723         local file=$2
23724
23725         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23726                 awk -F: '{print $2}' | grep $type > /dev/null
23727         if [ $? -ne 0 ]; then
23728                 return 0
23729         fi
23730         return 1
23731 }
23732
23733 ladvise_no_ioctl()
23734 {
23735         local file=$1
23736
23737         lfs ladvise -a willread $file > /dev/null 2>&1
23738         if [ $? -eq 0 ]; then
23739                 return 1
23740         fi
23741
23742         lfs ladvise -a willread $file 2>&1 |
23743                 grep "Inappropriate ioctl for device" > /dev/null
23744         if [ $? -eq 0 ]; then
23745                 return 0
23746         fi
23747         return 1
23748 }
23749
23750 percent() {
23751         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23752 }
23753
23754 # run a random read IO workload
23755 # usage: random_read_iops <filename> <filesize> <iosize>
23756 random_read_iops() {
23757         local file=$1
23758         local fsize=$2
23759         local iosize=${3:-4096}
23760
23761         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23762                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23763 }
23764
23765 drop_file_oss_cache() {
23766         local file="$1"
23767         local nodes="$2"
23768
23769         $LFS ladvise -a dontneed $file 2>/dev/null ||
23770                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23771 }
23772
23773 ladvise_willread_performance()
23774 {
23775         local repeat=10
23776         local average_origin=0
23777         local average_cache=0
23778         local average_ladvise=0
23779
23780         for ((i = 1; i <= $repeat; i++)); do
23781                 echo "Iter $i/$repeat: reading without willread hint"
23782                 cancel_lru_locks osc
23783                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23784                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23785                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23786                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23787
23788                 cancel_lru_locks osc
23789                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23790                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23791                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23792
23793                 cancel_lru_locks osc
23794                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23795                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23796                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23797                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23798                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23799         done
23800         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23801         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23802         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23803
23804         speedup_cache=$(percent $average_cache $average_origin)
23805         speedup_ladvise=$(percent $average_ladvise $average_origin)
23806
23807         echo "Average uncached read: $average_origin"
23808         echo "Average speedup with OSS cached read: " \
23809                 "$average_cache = +$speedup_cache%"
23810         echo "Average speedup with ladvise willread: " \
23811                 "$average_ladvise = +$speedup_ladvise%"
23812
23813         local lowest_speedup=20
23814         if (( ${average_cache%.*} < $lowest_speedup )); then
23815                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23816                      " got $average_cache%. Skipping ladvise willread check."
23817                 return 0
23818         fi
23819
23820         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23821         # it is still good to run until then to exercise 'ladvise willread'
23822         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23823                 [ "$ost1_FSTYPE" = "zfs" ] &&
23824                 echo "osd-zfs does not support dontneed or drop_caches" &&
23825                 return 0
23826
23827         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23828         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23829                 error_not_in_vm "Speedup with willread is less than " \
23830                         "$lowest_speedup%, got $average_ladvise%"
23831 }
23832
23833 test_255a() {
23834         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23835                 skip "lustre < 2.8.54 does not support ladvise "
23836         remote_ost_nodsh && skip "remote OST with nodsh"
23837
23838         stack_trap "rm -f $DIR/$tfile"
23839         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23840
23841         ladvise_no_type willread $DIR/$tfile &&
23842                 skip "willread ladvise is not supported"
23843
23844         ladvise_no_ioctl $DIR/$tfile &&
23845                 skip "ladvise ioctl is not supported"
23846
23847         local size_mb=100
23848         local size=$((size_mb * 1048576))
23849         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23850                 error "dd to $DIR/$tfile failed"
23851
23852         lfs ladvise -a willread $DIR/$tfile ||
23853                 error "Ladvise failed with no range argument"
23854
23855         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23856                 error "Ladvise failed with no -l or -e argument"
23857
23858         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23859                 error "Ladvise failed with only -e argument"
23860
23861         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23862                 error "Ladvise failed with only -l argument"
23863
23864         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23865                 error "End offset should not be smaller than start offset"
23866
23867         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23868                 error "End offset should not be equal to start offset"
23869
23870         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23871                 error "Ladvise failed with overflowing -s argument"
23872
23873         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23874                 error "Ladvise failed with overflowing -e argument"
23875
23876         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23877                 error "Ladvise failed with overflowing -l argument"
23878
23879         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23880                 error "Ladvise succeeded with conflicting -l and -e arguments"
23881
23882         echo "Synchronous ladvise should wait"
23883         local delay=8
23884 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23885         do_nodes $(comma_list $(osts_nodes)) \
23886                 $LCTL set_param fail_val=$delay fail_loc=0x237
23887         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23888                 $LCTL set_param fail_loc=0"
23889
23890         local start_ts=$SECONDS
23891         lfs ladvise -a willread $DIR/$tfile ||
23892                 error "Ladvise failed with no range argument"
23893         local end_ts=$SECONDS
23894         local inteval_ts=$((end_ts - start_ts))
23895
23896         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23897                 error "Synchronous advice didn't wait reply"
23898         fi
23899
23900         echo "Asynchronous ladvise shouldn't wait"
23901         local start_ts=$SECONDS
23902         lfs ladvise -a willread -b $DIR/$tfile ||
23903                 error "Ladvise failed with no range argument"
23904         local end_ts=$SECONDS
23905         local inteval_ts=$((end_ts - start_ts))
23906
23907         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23908                 error "Asynchronous advice blocked"
23909         fi
23910
23911         ladvise_willread_performance
23912 }
23913 run_test 255a "check 'lfs ladvise -a willread'"
23914
23915 facet_meminfo() {
23916         local facet=$1
23917         local info=$2
23918
23919         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23920 }
23921
23922 test_255b() {
23923         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23924                 skip "lustre < 2.8.54 does not support ladvise "
23925         remote_ost_nodsh && skip "remote OST with nodsh"
23926
23927         stack_trap "rm -f $DIR/$tfile"
23928         lfs setstripe -c 1 -i 0 $DIR/$tfile
23929
23930         ladvise_no_type dontneed $DIR/$tfile &&
23931                 skip "dontneed ladvise is not supported"
23932
23933         ladvise_no_ioctl $DIR/$tfile &&
23934                 skip "ladvise ioctl is not supported"
23935
23936         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23937                 [ "$ost1_FSTYPE" = "zfs" ] &&
23938                 skip "zfs-osd does not support 'ladvise dontneed'"
23939
23940         local size_mb=100
23941         local size=$((size_mb * 1048576))
23942         # In order to prevent disturbance of other processes, only check 3/4
23943         # of the memory usage
23944         local kibibytes=$((size_mb * 1024 * 3 / 4))
23945
23946         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23947                 error "dd to $DIR/$tfile failed"
23948
23949         #force write to complete before dropping OST cache & checking memory
23950         sync
23951
23952         local total=$(facet_meminfo ost1 MemTotal)
23953         echo "Total memory: $total KiB"
23954
23955         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23956         local before_read=$(facet_meminfo ost1 Cached)
23957         echo "Cache used before read: $before_read KiB"
23958
23959         lfs ladvise -a willread $DIR/$tfile ||
23960                 error "Ladvise willread failed"
23961         local after_read=$(facet_meminfo ost1 Cached)
23962         echo "Cache used after read: $after_read KiB"
23963
23964         lfs ladvise -a dontneed $DIR/$tfile ||
23965                 error "Ladvise dontneed again failed"
23966         local no_read=$(facet_meminfo ost1 Cached)
23967         echo "Cache used after dontneed ladvise: $no_read KiB"
23968
23969         if [ $total -lt $((before_read + kibibytes)) ]; then
23970                 echo "Memory is too small, abort checking"
23971                 return 0
23972         fi
23973
23974         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23975                 error "Ladvise willread should use more memory" \
23976                         "than $kibibytes KiB"
23977         fi
23978
23979         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23980                 error "Ladvise dontneed should release more memory" \
23981                         "than $kibibytes KiB"
23982         fi
23983 }
23984 run_test 255b "check 'lfs ladvise -a dontneed'"
23985
23986 test_255c() {
23987         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23988                 skip "lustre < 2.10.50 does not support lockahead"
23989
23990         local ost1_imp=$(get_osc_import_name client ost1)
23991         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23992                          cut -d'.' -f2)
23993         local count
23994         local new_count
23995         local difference
23996         local i
23997         local rc
23998
23999         test_mkdir -p $DIR/$tdir
24000         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24001
24002         #test 10 returns only success/failure
24003         i=10
24004         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24005         rc=$?
24006         if [ $rc -eq 255 ]; then
24007                 error "Ladvise test${i} failed, ${rc}"
24008         fi
24009
24010         #test 11 counts lock enqueue requests, all others count new locks
24011         i=11
24012         count=$(do_facet ost1 \
24013                 $LCTL get_param -n ost.OSS.ost.stats)
24014         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24015
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         new_count=$(do_facet ost1 \
24023                 $LCTL get_param -n ost.OSS.ost.stats)
24024         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24025                    awk '{ print $2 }')
24026
24027         difference="$((new_count - count))"
24028         if [ $difference -ne $rc ]; then
24029                 error "Ladvise test${i}, bad enqueue count, returned " \
24030                       "${rc}, actual ${difference}"
24031         fi
24032
24033         for i in $(seq 12 21); do
24034                 # If we do not do this, we run the risk of having too many
24035                 # locks and starting lock cancellation while we are checking
24036                 # lock counts.
24037                 cancel_lru_locks osc
24038
24039                 count=$($LCTL get_param -n \
24040                        ldlm.namespaces.$imp_name.lock_unused_count)
24041
24042                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24043                 rc=$?
24044                 if [ $rc -eq 255 ]; then
24045                         error "Ladvise test ${i} failed, ${rc}"
24046                 fi
24047
24048                 new_count=$($LCTL get_param -n \
24049                        ldlm.namespaces.$imp_name.lock_unused_count)
24050                 difference="$((new_count - count))"
24051
24052                 # Test 15 output is divided by 100 to map down to valid return
24053                 if [ $i -eq 15 ]; then
24054                         rc="$((rc * 100))"
24055                 fi
24056
24057                 if [ $difference -ne $rc ]; then
24058                         error "Ladvise test ${i}, bad lock count, returned " \
24059                               "${rc}, actual ${difference}"
24060                 fi
24061         done
24062
24063         #test 22 returns only success/failure
24064         i=22
24065         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24066         rc=$?
24067         if [ $rc -eq 255 ]; then
24068                 error "Ladvise test${i} failed, ${rc}"
24069         fi
24070 }
24071 run_test 255c "suite of ladvise lockahead tests"
24072
24073 test_256() {
24074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24075         remote_mds_nodsh && skip "remote MDS with nodsh"
24076         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24077         changelog_users $SINGLEMDS | grep "^cl" &&
24078                 skip "active changelog user"
24079
24080         local cl_user
24081         local cat_sl
24082         local mdt_dev
24083
24084         mdt_dev=$(facet_device $SINGLEMDS)
24085         echo $mdt_dev
24086
24087         changelog_register || error "changelog_register failed"
24088
24089         rm -rf $DIR/$tdir
24090         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24091
24092         changelog_clear 0 || error "changelog_clear failed"
24093
24094         # change something
24095         touch $DIR/$tdir/{1..10}
24096
24097         # stop the MDT
24098         stop $SINGLEMDS || error "Fail to stop MDT"
24099
24100         # remount the MDT
24101         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24102                 error "Fail to start MDT"
24103
24104         #after mount new plainllog is used
24105         touch $DIR/$tdir/{11..19}
24106         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24107         stack_trap "rm -f $tmpfile"
24108         cat_sl=$(do_facet $SINGLEMDS "sync; \
24109                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24110                  llog_reader $tmpfile | grep -c type=1064553b")
24111         do_facet $SINGLEMDS llog_reader $tmpfile
24112
24113         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24114
24115         changelog_clear 0 || error "changelog_clear failed"
24116
24117         cat_sl=$(do_facet $SINGLEMDS "sync; \
24118                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24119                  llog_reader $tmpfile | grep -c type=1064553b")
24120
24121         if (( cat_sl == 2 )); then
24122                 error "Empty plain llog was not deleted from changelog catalog"
24123         elif (( cat_sl != 1 )); then
24124                 error "Active plain llog shouldn't be deleted from catalog"
24125         fi
24126 }
24127 run_test 256 "Check llog delete for empty and not full state"
24128
24129 test_257() {
24130         remote_mds_nodsh && skip "remote MDS with nodsh"
24131         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24132                 skip "Need MDS version at least 2.8.55"
24133
24134         test_mkdir $DIR/$tdir
24135
24136         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24137                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24138         stat $DIR/$tdir
24139
24140 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24141         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24142         local facet=mds$((mdtidx + 1))
24143         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24144         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24145
24146         stop $facet || error "stop MDS failed"
24147         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24148                 error "start MDS fail"
24149         wait_recovery_complete $facet
24150 }
24151 run_test 257 "xattr locks are not lost"
24152
24153 # Verify we take the i_mutex when security requires it
24154 test_258a() {
24155 #define OBD_FAIL_IMUTEX_SEC 0x141c
24156         $LCTL set_param fail_loc=0x141c
24157         touch $DIR/$tfile
24158         chmod u+s $DIR/$tfile
24159         chmod a+rwx $DIR/$tfile
24160         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24161         RC=$?
24162         if [ $RC -ne 0 ]; then
24163                 error "error, failed to take i_mutex, rc=$?"
24164         fi
24165         rm -f $DIR/$tfile
24166 }
24167 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24168
24169 # Verify we do NOT take the i_mutex in the normal case
24170 test_258b() {
24171 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24172         $LCTL set_param fail_loc=0x141d
24173         touch $DIR/$tfile
24174         chmod a+rwx $DIR
24175         chmod a+rw $DIR/$tfile
24176         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24177         RC=$?
24178         if [ $RC -ne 0 ]; then
24179                 error "error, took i_mutex unnecessarily, rc=$?"
24180         fi
24181         rm -f $DIR/$tfile
24182
24183 }
24184 run_test 258b "verify i_mutex security behavior"
24185
24186 test_259() {
24187         local file=$DIR/$tfile
24188         local before
24189         local after
24190
24191         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24192
24193         stack_trap "rm -f $file" EXIT
24194
24195         wait_delete_completed
24196         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24197         echo "before: $before"
24198
24199         $LFS setstripe -i 0 -c 1 $file
24200         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24201         sync_all_data
24202         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24203         echo "after write: $after"
24204
24205 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24206         do_facet ost1 $LCTL set_param fail_loc=0x2301
24207         $TRUNCATE $file 0
24208         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24209         echo "after truncate: $after"
24210
24211         stop ost1
24212         do_facet ost1 $LCTL set_param fail_loc=0
24213         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24214         sleep 2
24215         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24216         echo "after restart: $after"
24217         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24218                 error "missing truncate?"
24219
24220         return 0
24221 }
24222 run_test 259 "crash at delayed truncate"
24223
24224 test_260() {
24225 #define OBD_FAIL_MDC_CLOSE               0x806
24226         $LCTL set_param fail_loc=0x80000806
24227         touch $DIR/$tfile
24228
24229 }
24230 run_test 260 "Check mdc_close fail"
24231
24232 ### Data-on-MDT sanity tests ###
24233 test_270a() {
24234         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24235                 skip "Need MDS version at least 2.10.55 for DoM"
24236
24237         # create DoM file
24238         local dom=$DIR/$tdir/dom_file
24239         local tmp=$DIR/$tdir/tmp_file
24240
24241         mkdir_on_mdt0 $DIR/$tdir
24242
24243         # basic checks for DoM component creation
24244         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24245                 error "Can set MDT layout to non-first entry"
24246
24247         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24248                 error "Can define multiple entries as MDT layout"
24249
24250         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24251
24252         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24253         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24254         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24255
24256         local mdtidx=$($LFS getstripe -m $dom)
24257         local mdtname=MDT$(printf %04x $mdtidx)
24258         local facet=mds$((mdtidx + 1))
24259         local space_check=1
24260
24261         # Skip free space checks with ZFS
24262         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24263
24264         # write
24265         sync
24266         local size_tmp=$((65536 * 3))
24267         local mdtfree1=$(do_facet $facet \
24268                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24269
24270         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24271         # check also direct IO along write
24272         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24273         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24274         sync
24275         cmp $tmp $dom || error "file data is different"
24276         [ $(stat -c%s $dom) == $size_tmp ] ||
24277                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24278         if [ $space_check == 1 ]; then
24279                 local mdtfree2=$(do_facet $facet \
24280                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24281
24282                 # increase in usage from by $size_tmp
24283                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24284                         error "MDT free space wrong after write: " \
24285                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24286         fi
24287
24288         # truncate
24289         local size_dom=10000
24290
24291         $TRUNCATE $dom $size_dom
24292         [ $(stat -c%s $dom) == $size_dom ] ||
24293                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24294         if [ $space_check == 1 ]; then
24295                 mdtfree1=$(do_facet $facet \
24296                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24297                 # decrease in usage from $size_tmp to new $size_dom
24298                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24299                   $(((size_tmp - size_dom) / 1024)) ] ||
24300                         error "MDT free space is wrong after truncate: " \
24301                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24302         fi
24303
24304         # append
24305         cat $tmp >> $dom
24306         sync
24307         size_dom=$((size_dom + size_tmp))
24308         [ $(stat -c%s $dom) == $size_dom ] ||
24309                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24310         if [ $space_check == 1 ]; then
24311                 mdtfree2=$(do_facet $facet \
24312                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24313                 # increase in usage by $size_tmp from previous
24314                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24315                         error "MDT free space is wrong after append: " \
24316                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24317         fi
24318
24319         # delete
24320         rm $dom
24321         if [ $space_check == 1 ]; then
24322                 mdtfree1=$(do_facet $facet \
24323                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24324                 # decrease in usage by $size_dom from previous
24325                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24326                         error "MDT free space is wrong after removal: " \
24327                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24328         fi
24329
24330         # combined striping
24331         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24332                 error "Can't create DoM + OST striping"
24333
24334         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24335         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24336         # check also direct IO along write
24337         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24338         sync
24339         cmp $tmp $dom || error "file data is different"
24340         [ $(stat -c%s $dom) == $size_tmp ] ||
24341                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24342         rm $dom $tmp
24343
24344         return 0
24345 }
24346 run_test 270a "DoM: basic functionality tests"
24347
24348 test_270b() {
24349         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24350                 skip "Need MDS version at least 2.10.55"
24351
24352         local dom=$DIR/$tdir/dom_file
24353         local max_size=1048576
24354
24355         mkdir -p $DIR/$tdir
24356         $LFS setstripe -E $max_size -L mdt $dom
24357
24358         # truncate over the limit
24359         $TRUNCATE $dom $(($max_size + 1)) &&
24360                 error "successful truncate over the maximum size"
24361         # write over the limit
24362         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24363                 error "successful write over the maximum size"
24364         # append over the limit
24365         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24366         echo "12345" >> $dom && error "successful append over the maximum size"
24367         rm $dom
24368
24369         return 0
24370 }
24371 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24372
24373 test_270c() {
24374         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24375                 skip "Need MDS version at least 2.10.55"
24376
24377         mkdir -p $DIR/$tdir
24378         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24379
24380         # check files inherit DoM EA
24381         touch $DIR/$tdir/first
24382         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24383                 error "bad pattern"
24384         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24385                 error "bad stripe count"
24386         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24387                 error "bad stripe size"
24388
24389         # check directory inherits DoM EA and uses it as default
24390         mkdir $DIR/$tdir/subdir
24391         touch $DIR/$tdir/subdir/second
24392         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24393                 error "bad pattern in sub-directory"
24394         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24395                 error "bad stripe count in sub-directory"
24396         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24397                 error "bad stripe size in sub-directory"
24398         return 0
24399 }
24400 run_test 270c "DoM: DoM EA inheritance tests"
24401
24402 test_270d() {
24403         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24404                 skip "Need MDS version at least 2.10.55"
24405
24406         mkdir -p $DIR/$tdir
24407         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24408
24409         # inherit default DoM striping
24410         mkdir $DIR/$tdir/subdir
24411         touch $DIR/$tdir/subdir/f1
24412
24413         # change default directory striping
24414         $LFS setstripe -c 1 $DIR/$tdir/subdir
24415         touch $DIR/$tdir/subdir/f2
24416         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24417                 error "wrong default striping in file 2"
24418         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24419                 error "bad pattern in file 2"
24420         return 0
24421 }
24422 run_test 270d "DoM: change striping from DoM to RAID0"
24423
24424 test_270e() {
24425         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24426                 skip "Need MDS version at least 2.10.55"
24427
24428         mkdir -p $DIR/$tdir/dom
24429         mkdir -p $DIR/$tdir/norm
24430         DOMFILES=20
24431         NORMFILES=10
24432         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24433         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24434
24435         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24436         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24437
24438         # find DoM files by layout
24439         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24440         [ $NUM -eq  $DOMFILES ] ||
24441                 error "lfs find -L: found $NUM, expected $DOMFILES"
24442         echo "Test 1: lfs find 20 DOM files by layout: OK"
24443
24444         # there should be 1 dir with default DOM striping
24445         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24446         [ $NUM -eq  1 ] ||
24447                 error "lfs find -L: found $NUM, expected 1 dir"
24448         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24449
24450         # find DoM files by stripe size
24451         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24452         [ $NUM -eq  $DOMFILES ] ||
24453                 error "lfs find -S: found $NUM, expected $DOMFILES"
24454         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24455
24456         # find files by stripe offset except DoM files
24457         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24458         [ $NUM -eq  $NORMFILES ] ||
24459                 error "lfs find -i: found $NUM, expected $NORMFILES"
24460         echo "Test 5: lfs find no DOM files by stripe index: OK"
24461         return 0
24462 }
24463 run_test 270e "DoM: lfs find with DoM files test"
24464
24465 test_270f() {
24466         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24467                 skip "Need MDS version at least 2.10.55"
24468
24469         local mdtname=${FSNAME}-MDT0000-mdtlov
24470         local dom=$DIR/$tdir/dom_file
24471         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24472                                                 lod.$mdtname.dom_stripesize)
24473         local dom_limit=131072
24474
24475         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24476         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24477                                                 lod.$mdtname.dom_stripesize)
24478         [ ${dom_limit} -eq ${dom_current} ] ||
24479                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24480
24481         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24482         $LFS setstripe -d $DIR/$tdir
24483         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24484                 error "Can't set directory default striping"
24485
24486         # exceed maximum stripe size
24487         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24488                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24489         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24490                 error "Able to create DoM component size more than LOD limit"
24491
24492         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24493         dom_current=$(do_facet mds1 $LCTL get_param -n \
24494                                                 lod.$mdtname.dom_stripesize)
24495         [ 0 -eq ${dom_current} ] ||
24496                 error "Can't set zero DoM stripe limit"
24497         rm $dom
24498
24499         # attempt to create DoM file on server with disabled DoM should
24500         # remove DoM entry from layout and be succeed
24501         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24502                 error "Can't create DoM file (DoM is disabled)"
24503         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24504                 error "File has DoM component while DoM is disabled"
24505         rm $dom
24506
24507         # attempt to create DoM file with only DoM stripe should return error
24508         $LFS setstripe -E $dom_limit -L mdt $dom &&
24509                 error "Able to create DoM-only file while DoM is disabled"
24510
24511         # too low values to be aligned with smallest stripe size 64K
24512         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24513         dom_current=$(do_facet mds1 $LCTL get_param -n \
24514                                                 lod.$mdtname.dom_stripesize)
24515         [ 30000 -eq ${dom_current} ] &&
24516                 error "Can set too small DoM stripe limit"
24517
24518         # 64K is a minimal stripe size in Lustre, expect limit of that size
24519         [ 65536 -eq ${dom_current} ] ||
24520                 error "Limit is not set to 64K but ${dom_current}"
24521
24522         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24523         dom_current=$(do_facet mds1 $LCTL get_param -n \
24524                                                 lod.$mdtname.dom_stripesize)
24525         echo $dom_current
24526         [ 2147483648 -eq ${dom_current} ] &&
24527                 error "Can set too large DoM stripe limit"
24528
24529         do_facet mds1 $LCTL set_param -n \
24530                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24531         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24532                 error "Can't create DoM component size after limit change"
24533         do_facet mds1 $LCTL set_param -n \
24534                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24535         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24536                 error "Can't create DoM file after limit decrease"
24537         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24538                 error "Can create big DoM component after limit decrease"
24539         touch ${dom}_def ||
24540                 error "Can't create file with old default layout"
24541
24542         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24543         return 0
24544 }
24545 run_test 270f "DoM: maximum DoM stripe size checks"
24546
24547 test_270g() {
24548         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24549                 skip "Need MDS version at least 2.13.52"
24550         local dom=$DIR/$tdir/$tfile
24551
24552         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24553         local lodname=${FSNAME}-MDT0000-mdtlov
24554
24555         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24556         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24557         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24558         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24559
24560         local dom_limit=1024
24561         local dom_threshold="50%"
24562
24563         $LFS setstripe -d $DIR/$tdir
24564         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24565                 error "Can't set directory default striping"
24566
24567         do_facet mds1 $LCTL set_param -n \
24568                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24569         # set 0 threshold and create DOM file to change tunable stripesize
24570         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24571         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24572                 error "Failed to create $dom file"
24573         # now tunable dom_cur_stripesize should reach maximum
24574         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24575                                         lod.${lodname}.dom_stripesize_cur_kb)
24576         [[ $dom_current == $dom_limit ]] ||
24577                 error "Current DOM stripesize is not maximum"
24578         rm $dom
24579
24580         # set threshold for further tests
24581         do_facet mds1 $LCTL set_param -n \
24582                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24583         echo "DOM threshold is $dom_threshold free space"
24584         local dom_def
24585         local dom_set
24586         # Spoof bfree to exceed threshold
24587         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24588         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24589         for spfree in 40 20 0 15 30 55; do
24590                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24591                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24592                         error "Failed to create $dom file"
24593                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24594                                         lod.${lodname}.dom_stripesize_cur_kb)
24595                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24596                 [[ $dom_def != $dom_current ]] ||
24597                         error "Default stripe size was not changed"
24598                 if (( spfree > 0 )) ; then
24599                         dom_set=$($LFS getstripe -S $dom)
24600                         (( dom_set == dom_def * 1024 )) ||
24601                                 error "DOM component size is still old"
24602                 else
24603                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24604                                 error "DoM component is set with no free space"
24605                 fi
24606                 rm $dom
24607                 dom_current=$dom_def
24608         done
24609 }
24610 run_test 270g "DoM: default DoM stripe size depends on free space"
24611
24612 test_270h() {
24613         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24614                 skip "Need MDS version at least 2.13.53"
24615
24616         local mdtname=${FSNAME}-MDT0000-mdtlov
24617         local dom=$DIR/$tdir/$tfile
24618         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24619
24620         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24621         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24622
24623         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24624         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24625                 error "can't create OST file"
24626         # mirrored file with DOM entry in the second mirror
24627         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24628                 error "can't create mirror with DoM component"
24629
24630         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24631
24632         # DOM component in the middle and has other enries in the same mirror,
24633         # should succeed but lost DoM component
24634         $LFS setstripe --copy=${dom}_1 $dom ||
24635                 error "Can't create file from OST|DOM mirror layout"
24636         # check new file has no DoM layout after all
24637         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24638                 error "File has DoM component while DoM is disabled"
24639 }
24640 run_test 270h "DoM: DoM stripe removal when disabled on server"
24641
24642 test_270i() {
24643         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24644                 skip "Need MDS version at least 2.14.54"
24645
24646         mkdir $DIR/$tdir
24647         # DoM with plain layout
24648         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24649                 error "default plain layout with DoM must fail"
24650         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24651                 error "setstripe plain file layout with DoM must fail"
24652         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24653                 error "default DoM layout with bad striping must fail"
24654         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24655                 error "setstripe to DoM layout with bad striping must fail"
24656         return 0
24657 }
24658 run_test 270i "DoM: setting invalid DoM striping should fail"
24659
24660 test_270j() {
24661         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24662                 skip "Need MDS version at least 2.15.55.203"
24663
24664         local dom=$DIR/$tdir/$tfile
24665         local odv
24666         local ndv
24667
24668         mkdir -p $DIR/$tdir
24669
24670         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24671
24672         odv=$($LFS data_version $dom)
24673         chmod 666 $dom
24674         mv $dom ${dom}_moved
24675         link ${dom}_moved $dom
24676         setfattr -n user.attrx -v "some_attr" $dom
24677         ndv=$($LFS data_version $dom)
24678         (( $ndv == $odv )) ||
24679                 error "data version was changed by metadata operations"
24680
24681         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24682                 error "failed to write data into $dom"
24683         cancel_lru_locks mdc
24684         ndv=$($LFS data_version $dom)
24685         (( $ndv != $odv )) ||
24686                 error "data version wasn't changed on write"
24687
24688         odv=$ndv
24689         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24690         ndv=$($LFS data_version $dom)
24691         (( $ndv != $odv )) ||
24692                 error "data version wasn't changed on truncate down"
24693
24694         odv=$ndv
24695         $TRUNCATE $dom 25000
24696         ndv=$($LFS data_version $dom)
24697         (( $ndv != $odv )) ||
24698                 error "data version wasn't changed on truncate up"
24699
24700         # check also fallocate for ldiskfs
24701         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24702                 odv=$ndv
24703                 fallocate -l 1048576 $dom
24704                 ndv=$($LFS data_version $dom)
24705                 (( $ndv != $odv )) ||
24706                         error "data version wasn't changed on fallocate"
24707
24708                 odv=$ndv
24709                 fallocate -p --offset 4096 -l 4096 $dom
24710                 ndv=$($LFS data_version $dom)
24711                 (( $ndv != $odv )) ||
24712                         error "data version wasn't changed on fallocate punch"
24713         fi
24714 }
24715 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24716
24717 test_271a() {
24718         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24719                 skip "Need MDS version at least 2.10.55"
24720
24721         local dom=$DIR/$tdir/dom
24722
24723         mkdir -p $DIR/$tdir
24724
24725         $LFS setstripe -E 1024K -L mdt $dom
24726
24727         lctl set_param -n mdc.*.stats=clear
24728         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24729         cat $dom > /dev/null
24730         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24731         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24732         ls $dom
24733         rm -f $dom
24734 }
24735 run_test 271a "DoM: data is cached for read after write"
24736
24737 test_271b() {
24738         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24739                 skip "Need MDS version at least 2.10.55"
24740
24741         local dom=$DIR/$tdir/dom
24742
24743         mkdir -p $DIR/$tdir
24744
24745         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24746
24747         lctl set_param -n mdc.*.stats=clear
24748         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24749         cancel_lru_locks mdc
24750         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24751         # second stat to check size is cached on client
24752         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24753         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24754         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24755         rm -f $dom
24756 }
24757 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24758
24759 test_271ba() {
24760         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24761                 skip "Need MDS version at least 2.10.55"
24762
24763         local dom=$DIR/$tdir/dom
24764
24765         mkdir -p $DIR/$tdir
24766
24767         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24768
24769         lctl set_param -n mdc.*.stats=clear
24770         lctl set_param -n osc.*.stats=clear
24771         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24772         cancel_lru_locks mdc
24773         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24774         # second stat to check size is cached on client
24775         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24776         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24777         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24778         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24779         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24780         rm -f $dom
24781 }
24782 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24783
24784
24785 get_mdc_stats() {
24786         local mdtidx=$1
24787         local param=$2
24788         local mdt=MDT$(printf %04x $mdtidx)
24789
24790         if [ -z $param ]; then
24791                 lctl get_param -n mdc.*$mdt*.stats
24792         else
24793                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24794         fi
24795 }
24796
24797 test_271c() {
24798         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24799                 skip "Need MDS version at least 2.10.55"
24800
24801         local dom=$DIR/$tdir/dom
24802
24803         mkdir -p $DIR/$tdir
24804
24805         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24806
24807         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24808         local facet=mds$((mdtidx + 1))
24809
24810         cancel_lru_locks mdc
24811         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24812         createmany -o $dom 1000
24813         lctl set_param -n mdc.*.stats=clear
24814         smalliomany -w $dom 1000 200
24815         get_mdc_stats $mdtidx
24816         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24817         # Each file has 1 open, 1 IO enqueues, total 2000
24818         # but now we have also +1 getxattr for security.capability, total 3000
24819         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24820         unlinkmany $dom 1000
24821
24822         cancel_lru_locks mdc
24823         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24824         createmany -o $dom 1000
24825         lctl set_param -n mdc.*.stats=clear
24826         smalliomany -w $dom 1000 200
24827         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24828         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24829         # for OPEN and IO lock.
24830         [ $((enq - enq_2)) -ge 1000 ] ||
24831                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24832         unlinkmany $dom 1000
24833         return 0
24834 }
24835 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24836
24837 cleanup_271def_tests() {
24838         trap 0
24839         rm -f $1
24840 }
24841
24842 test_271d() {
24843         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24844                 skip "Need MDS version at least 2.10.57"
24845
24846         local dom=$DIR/$tdir/dom
24847         local tmp=$TMP/$tfile
24848         trap "cleanup_271def_tests $tmp" EXIT
24849
24850         mkdir -p $DIR/$tdir
24851
24852         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24853
24854         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24855
24856         cancel_lru_locks mdc
24857         dd if=/dev/urandom of=$tmp bs=1000 count=1
24858         dd if=$tmp of=$dom bs=1000 count=1
24859         cancel_lru_locks mdc
24860
24861         cat /etc/hosts >> $tmp
24862         lctl set_param -n mdc.*.stats=clear
24863
24864         # append data to the same file it should update local page
24865         echo "Append to the same page"
24866         cat /etc/hosts >> $dom
24867         local num=$(get_mdc_stats $mdtidx ost_read)
24868         local ra=$(get_mdc_stats $mdtidx req_active)
24869         local rw=$(get_mdc_stats $mdtidx req_waittime)
24870
24871         [ -z $num ] || error "$num READ RPC occured"
24872         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24873         echo "... DONE"
24874
24875         # compare content
24876         cmp $tmp $dom || error "file miscompare"
24877
24878         cancel_lru_locks mdc
24879         lctl set_param -n mdc.*.stats=clear
24880
24881         echo "Open and read file"
24882         cat $dom > /dev/null
24883         local num=$(get_mdc_stats $mdtidx ost_read)
24884         local ra=$(get_mdc_stats $mdtidx req_active)
24885         local rw=$(get_mdc_stats $mdtidx req_waittime)
24886
24887         [ -z $num ] || error "$num READ RPC occured"
24888         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24889         echo "... DONE"
24890
24891         # compare content
24892         cmp $tmp $dom || error "file miscompare"
24893
24894         return 0
24895 }
24896 run_test 271d "DoM: read on open (1K file in reply buffer)"
24897
24898 test_271f() {
24899         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24900                 skip "Need MDS version at least 2.10.57"
24901
24902         local dom=$DIR/$tdir/dom
24903         local tmp=$TMP/$tfile
24904         trap "cleanup_271def_tests $tmp" EXIT
24905
24906         mkdir -p $DIR/$tdir
24907
24908         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24909
24910         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24911
24912         cancel_lru_locks mdc
24913         dd if=/dev/urandom of=$tmp bs=265000 count=1
24914         dd if=$tmp of=$dom bs=265000 count=1
24915         cancel_lru_locks mdc
24916         cat /etc/hosts >> $tmp
24917         lctl set_param -n mdc.*.stats=clear
24918
24919         echo "Append to the same page"
24920         cat /etc/hosts >> $dom
24921         local num=$(get_mdc_stats $mdtidx ost_read)
24922         local ra=$(get_mdc_stats $mdtidx req_active)
24923         local rw=$(get_mdc_stats $mdtidx req_waittime)
24924
24925         [ -z $num ] || error "$num READ RPC occured"
24926         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24927         echo "... DONE"
24928
24929         # compare content
24930         cmp $tmp $dom || error "file miscompare"
24931
24932         cancel_lru_locks mdc
24933         lctl set_param -n mdc.*.stats=clear
24934
24935         echo "Open and read file"
24936         cat $dom > /dev/null
24937         local num=$(get_mdc_stats $mdtidx ost_read)
24938         local ra=$(get_mdc_stats $mdtidx req_active)
24939         local rw=$(get_mdc_stats $mdtidx req_waittime)
24940
24941         [ -z $num ] && num=0
24942         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24943         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24944         echo "... DONE"
24945
24946         # compare content
24947         cmp $tmp $dom || error "file miscompare"
24948
24949         return 0
24950 }
24951 run_test 271f "DoM: read on open (200K file and read tail)"
24952
24953 test_271g() {
24954         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24955                 skip "Skipping due to old client or server version"
24956
24957         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24958         # to get layout
24959         $CHECKSTAT -t file $DIR1/$tfile
24960
24961         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24962         MULTIOP_PID=$!
24963         sleep 1
24964         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24965         $LCTL set_param fail_loc=0x80000314
24966         rm $DIR1/$tfile || error "Unlink fails"
24967         RC=$?
24968         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24969         [ $RC -eq 0 ] || error "Failed write to stale object"
24970 }
24971 run_test 271g "Discard DoM data vs client flush race"
24972
24973 test_272a() {
24974         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24975                 skip "Need MDS version at least 2.11.50"
24976
24977         local dom=$DIR/$tdir/dom
24978         mkdir -p $DIR/$tdir
24979
24980         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24981         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24982                 error "failed to write data into $dom"
24983         local old_md5=$(md5sum $dom)
24984
24985         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24986                 error "failed to migrate to the same DoM component"
24987
24988         local new_md5=$(md5sum $dom)
24989
24990         [ "$old_md5" == "$new_md5" ] ||
24991                 error "md5sum differ: $old_md5, $new_md5"
24992
24993         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24994                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24995 }
24996 run_test 272a "DoM migration: new layout with the same DOM component"
24997
24998 test_272b() {
24999         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25000                 skip "Need MDS version at least 2.11.50"
25001
25002         local dom=$DIR/$tdir/dom
25003         mkdir -p $DIR/$tdir
25004         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25005         stack_trap "rm -rf $DIR/$tdir"
25006
25007         local mdtidx=$($LFS getstripe -m $dom)
25008         local mdtname=MDT$(printf %04x $mdtidx)
25009         local facet=mds$((mdtidx + 1))
25010
25011         local mdtfree1=$(do_facet $facet \
25012                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25013         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25014                 error "failed to write data into $dom"
25015         local old_md5=$(md5sum $dom)
25016         cancel_lru_locks mdc
25017         local mdtfree1=$(do_facet $facet \
25018                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25019
25020         $LFS migrate -c2 $dom ||
25021                 error "failed to migrate to the new composite layout"
25022         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25023                 error "MDT stripe was not removed"
25024         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25025                 error "$dir1 shouldn't have DATAVER EA"
25026
25027         cancel_lru_locks mdc
25028         local new_md5=$(md5sum $dom)
25029         [ "$old_md5" == "$new_md5" ] ||
25030                 error "$old_md5 != $new_md5"
25031
25032         # Skip free space checks with ZFS
25033         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25034                 local mdtfree2=$(do_facet $facet \
25035                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25036                 [ $mdtfree2 -gt $mdtfree1 ] ||
25037                         error "MDT space is not freed after migration"
25038         fi
25039         return 0
25040 }
25041 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25042
25043 test_272c() {
25044         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25045                 skip "Need MDS version at least 2.11.50"
25046
25047         local dom=$DIR/$tdir/$tfile
25048         mkdir -p $DIR/$tdir
25049         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25050         stack_trap "rm -rf $DIR/$tdir"
25051
25052         local mdtidx=$($LFS getstripe -m $dom)
25053         local mdtname=MDT$(printf %04x $mdtidx)
25054         local facet=mds$((mdtidx + 1))
25055
25056         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25057                 error "failed to write data into $dom"
25058         local old_md5=$(md5sum $dom)
25059         cancel_lru_locks mdc
25060         local mdtfree1=$(do_facet $facet \
25061                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25062
25063         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25064                 error "failed to migrate to the new composite layout"
25065         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25066                 error "MDT stripe was not removed"
25067
25068         cancel_lru_locks mdc
25069         local new_md5=$(md5sum $dom)
25070         [ "$old_md5" == "$new_md5" ] ||
25071                 error "$old_md5 != $new_md5"
25072
25073         # Skip free space checks with ZFS
25074         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25075                 local mdtfree2=$(do_facet $facet \
25076                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25077                 [ $mdtfree2 -gt $mdtfree1 ] ||
25078                         error "MDS space is not freed after migration"
25079         fi
25080         return 0
25081 }
25082 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25083
25084 test_272d() {
25085         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25086                 skip "Need MDS version at least 2.12.55"
25087
25088         local dom=$DIR/$tdir/$tfile
25089         mkdir -p $DIR/$tdir
25090         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25091
25092         local mdtidx=$($LFS getstripe -m $dom)
25093         local mdtname=MDT$(printf %04x $mdtidx)
25094         local facet=mds$((mdtidx + 1))
25095
25096         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25097                 error "failed to write data into $dom"
25098         local old_md5=$(md5sum $dom)
25099         cancel_lru_locks mdc
25100         local mdtfree1=$(do_facet $facet \
25101                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25102
25103         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25104                 error "failed mirroring to the new composite layout"
25105         $LFS mirror resync $dom ||
25106                 error "failed mirror resync"
25107         $LFS mirror split --mirror-id 1 -d $dom ||
25108                 error "failed mirror split"
25109
25110         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25111                 error "MDT stripe was not removed"
25112
25113         cancel_lru_locks mdc
25114         local new_md5=$(md5sum $dom)
25115         [ "$old_md5" == "$new_md5" ] ||
25116                 error "$old_md5 != $new_md5"
25117
25118         # Skip free space checks with ZFS
25119         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25120                 local mdtfree2=$(do_facet $facet \
25121                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25122                 [ $mdtfree2 -gt $mdtfree1 ] ||
25123                         error "MDS space is not freed after DOM mirror deletion"
25124         fi
25125         return 0
25126 }
25127 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25128
25129 test_272e() {
25130         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25131                 skip "Need MDS version at least 2.12.55"
25132
25133         local dom=$DIR/$tdir/$tfile
25134         mkdir -p $DIR/$tdir
25135         $LFS setstripe -c 2 $dom
25136
25137         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25138                 error "failed to write data into $dom"
25139         local old_md5=$(md5sum $dom)
25140         cancel_lru_locks
25141
25142         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25143                 error "failed mirroring to the DOM layout"
25144         $LFS mirror resync $dom ||
25145                 error "failed mirror resync"
25146         $LFS mirror split --mirror-id 1 -d $dom ||
25147                 error "failed mirror split"
25148
25149         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25150                 error "MDT stripe wasn't set"
25151
25152         cancel_lru_locks
25153         local new_md5=$(md5sum $dom)
25154         [ "$old_md5" == "$new_md5" ] ||
25155                 error "$old_md5 != $new_md5"
25156
25157         return 0
25158 }
25159 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25160
25161 test_272f() {
25162         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25163                 skip "Need MDS version at least 2.12.55"
25164
25165         local dom=$DIR/$tdir/$tfile
25166         mkdir -p $DIR/$tdir
25167         $LFS setstripe -c 2 $dom
25168
25169         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25170                 error "failed to write data into $dom"
25171         local old_md5=$(md5sum $dom)
25172         cancel_lru_locks
25173
25174         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25175                 error "failed migrating to the DOM file"
25176
25177         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25178                 error "MDT stripe wasn't set"
25179
25180         cancel_lru_locks
25181         local new_md5=$(md5sum $dom)
25182         [ "$old_md5" != "$new_md5" ] &&
25183                 error "$old_md5 != $new_md5"
25184
25185         return 0
25186 }
25187 run_test 272f "DoM migration: OST-striped file to DOM file"
25188
25189 test_273a() {
25190         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25191                 skip "Need MDS version at least 2.11.50"
25192
25193         # Layout swap cannot be done if either file has DOM component,
25194         # this will never be supported, migration should be used instead
25195
25196         local dom=$DIR/$tdir/$tfile
25197         mkdir -p $DIR/$tdir
25198
25199         $LFS setstripe -c2 ${dom}_plain
25200         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25201         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25202                 error "can swap layout with DoM component"
25203         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25204                 error "can swap layout with DoM component"
25205
25206         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25207         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25208                 error "can swap layout with DoM component"
25209         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25210                 error "can swap layout with DoM component"
25211         return 0
25212 }
25213 run_test 273a "DoM: layout swapping should fail with DOM"
25214
25215 test_273b() {
25216         mkdir -p $DIR/$tdir
25217         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25218
25219 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25220         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25221
25222         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25223 }
25224 run_test 273b "DoM: race writeback and object destroy"
25225
25226 test_273c() {
25227         mkdir -p $DIR/$tdir
25228         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25229
25230         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25231         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25232
25233         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25234 }
25235 run_test 273c "race writeback and object destroy"
25236
25237 test_275() {
25238         remote_ost_nodsh && skip "remote OST with nodsh"
25239         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25240                 skip "Need OST version >= 2.10.57"
25241
25242         local file=$DIR/$tfile
25243         local oss
25244
25245         oss=$(comma_list $(osts_nodes))
25246
25247         dd if=/dev/urandom of=$file bs=1M count=2 ||
25248                 error "failed to create a file"
25249         stack_trap "rm -f $file"
25250         cancel_lru_locks osc
25251
25252         #lock 1
25253         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25254                 error "failed to read a file"
25255
25256 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25257         $LCTL set_param fail_loc=0x8000031f
25258
25259         cancel_lru_locks osc &
25260         sleep 1
25261
25262 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25263         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25264         #IO takes another lock, but matches the PENDING one
25265         #and places it to the IO RPC
25266         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25267                 error "failed to read a file with PENDING lock"
25268 }
25269 run_test 275 "Read on a canceled duplicate lock"
25270
25271 test_276() {
25272         remote_ost_nodsh && skip "remote OST with nodsh"
25273         local pid
25274
25275         do_facet ost1 "(while true; do \
25276                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25277                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25278         pid=$!
25279
25280         for LOOP in $(seq 20); do
25281                 stop ost1
25282                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25283         done
25284         kill -9 $pid
25285         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25286                 rm $TMP/sanity_276_pid"
25287 }
25288 run_test 276 "Race between mount and obd_statfs"
25289
25290 test_277() {
25291         $LCTL set_param ldlm.namespaces.*.lru_size=0
25292         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25293         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25294                           awk '/^used_mb/ { print $2 }')
25295         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25297                 oflag=direct conv=notrunc
25298         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25299                     awk '/^used_mb/ { print $2 }')
25300         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25301 }
25302 run_test 277 "Direct IO shall drop page cache"
25303
25304 test_278() {
25305         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25306         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25307         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25308                 skip "needs the same host for mdt1 mdt2" && return
25309
25310         local pid1
25311         local pid2
25312
25313 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25314         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25315         stop mds2 &
25316         pid2=$!
25317
25318         stop mds1
25319
25320         echo "Starting MDTs"
25321         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25322         wait $pid2
25323 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25324 #will return NULL
25325         do_facet mds2 $LCTL set_param fail_loc=0
25326
25327         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25328         wait_recovery_complete mds2
25329 }
25330 run_test 278 "Race starting MDS between MDTs stop/start"
25331
25332 test_280() {
25333         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25334                 skip "Need MGS version at least 2.13.52"
25335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25336         combined_mgs_mds || skip "needs combined MGS/MDT"
25337
25338         umount_client $MOUNT
25339 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25340         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25341
25342         mount_client $MOUNT &
25343         sleep 1
25344         stop mgs || error "stop mgs failed"
25345         #for a race mgs would crash
25346         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25347         # make sure we unmount client before remounting
25348         wait
25349         umount_client $MOUNT
25350         mount_client $MOUNT || error "mount client failed"
25351 }
25352 run_test 280 "Race between MGS umount and client llog processing"
25353
25354 cleanup_test_300() {
25355         trap 0
25356         umask $SAVE_UMASK
25357 }
25358 test_striped_dir() {
25359         local mdt_index=$1
25360         local stripe_count
25361         local stripe_index
25362
25363         mkdir -p $DIR/$tdir
25364
25365         SAVE_UMASK=$(umask)
25366         trap cleanup_test_300 RETURN EXIT
25367
25368         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25369                                                 $DIR/$tdir/striped_dir ||
25370                 error "set striped dir error"
25371
25372         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25373         [ "$mode" = "755" ] || error "expect 755 got $mode"
25374
25375         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25376                 error "getdirstripe failed"
25377         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25378         if [ "$stripe_count" != "2" ]; then
25379                 error "1:stripe_count is $stripe_count, expect 2"
25380         fi
25381         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25382         if [ "$stripe_count" != "2" ]; then
25383                 error "2:stripe_count is $stripe_count, expect 2"
25384         fi
25385
25386         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25387         if [ "$stripe_index" != "$mdt_index" ]; then
25388                 error "stripe_index is $stripe_index, expect $mdt_index"
25389         fi
25390
25391         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25392                 error "nlink error after create striped dir"
25393
25394         mkdir $DIR/$tdir/striped_dir/a
25395         mkdir $DIR/$tdir/striped_dir/b
25396
25397         stat $DIR/$tdir/striped_dir/a ||
25398                 error "create dir under striped dir failed"
25399         stat $DIR/$tdir/striped_dir/b ||
25400                 error "create dir under striped dir failed"
25401
25402         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25403                 error "nlink error after mkdir"
25404
25405         rmdir $DIR/$tdir/striped_dir/a
25406         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25407                 error "nlink error after rmdir"
25408
25409         rmdir $DIR/$tdir/striped_dir/b
25410         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25411                 error "nlink error after rmdir"
25412
25413         chattr +i $DIR/$tdir/striped_dir
25414         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25415                 error "immutable flags not working under striped dir!"
25416         chattr -i $DIR/$tdir/striped_dir
25417
25418         rmdir $DIR/$tdir/striped_dir ||
25419                 error "rmdir striped dir error"
25420
25421         cleanup_test_300
25422
25423         true
25424 }
25425
25426 test_300a() {
25427         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25428                 skip "skipped for lustre < 2.7.0"
25429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25430         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25431
25432         test_striped_dir 0 || error "failed on striped dir on MDT0"
25433         test_striped_dir 1 || error "failed on striped dir on MDT0"
25434 }
25435 run_test 300a "basic striped dir sanity test"
25436
25437 test_300b() {
25438         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25439                 skip "skipped for lustre < 2.7.0"
25440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25442
25443         local i
25444         local mtime1
25445         local mtime2
25446         local mtime3
25447
25448         test_mkdir $DIR/$tdir || error "mkdir fail"
25449         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25450                 error "set striped dir error"
25451         for i in {0..9}; do
25452                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25453                 sleep 1
25454                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25455                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25456                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25457                 sleep 1
25458                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25459                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25460                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25461         done
25462         true
25463 }
25464 run_test 300b "check ctime/mtime for striped dir"
25465
25466 test_300c() {
25467         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25468                 skip "skipped for lustre < 2.7.0"
25469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25470         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25471
25472         local file_count
25473
25474         mkdir_on_mdt0 $DIR/$tdir
25475         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25476                 error "set striped dir error"
25477
25478         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25479                 error "chown striped dir failed"
25480
25481         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25482                 error "create 5k files failed"
25483
25484         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25485
25486         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25487
25488         rm -rf $DIR/$tdir
25489 }
25490 run_test 300c "chown && check ls under striped directory"
25491
25492 test_300d() {
25493         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25494                 skip "skipped for lustre < 2.7.0"
25495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25497
25498         local stripe_count
25499         local file
25500
25501         mkdir -p $DIR/$tdir
25502         $LFS setstripe -c 2 $DIR/$tdir
25503
25504         #local striped directory
25505         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25506                 error "set striped dir error"
25507         #look at the directories for debug purposes
25508         ls -l $DIR/$tdir
25509         $LFS getdirstripe $DIR/$tdir
25510         ls -l $DIR/$tdir/striped_dir
25511         $LFS getdirstripe $DIR/$tdir/striped_dir
25512         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25513                 error "create 10 files failed"
25514
25515         #remote striped directory
25516         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25517                 error "set striped dir error"
25518         #look at the directories for debug purposes
25519         ls -l $DIR/$tdir
25520         $LFS getdirstripe $DIR/$tdir
25521         ls -l $DIR/$tdir/remote_striped_dir
25522         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25523         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25524                 error "create 10 files failed"
25525
25526         for file in $(find $DIR/$tdir); do
25527                 stripe_count=$($LFS getstripe -c $file)
25528                 [ $stripe_count -eq 2 ] ||
25529                         error "wrong stripe $stripe_count for $file"
25530         done
25531
25532         rm -rf $DIR/$tdir
25533 }
25534 run_test 300d "check default stripe under striped directory"
25535
25536 test_300e() {
25537         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25538                 skip "Need MDS version at least 2.7.55"
25539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25541
25542         local stripe_count
25543         local file
25544
25545         mkdir -p $DIR/$tdir
25546
25547         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25548                 error "set striped dir error"
25549
25550         touch $DIR/$tdir/striped_dir/a
25551         touch $DIR/$tdir/striped_dir/b
25552         touch $DIR/$tdir/striped_dir/c
25553
25554         mkdir $DIR/$tdir/striped_dir/dir_a
25555         mkdir $DIR/$tdir/striped_dir/dir_b
25556         mkdir $DIR/$tdir/striped_dir/dir_c
25557
25558         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25559                 error "set striped adir under striped dir error"
25560
25561         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25562                 error "set striped bdir under striped dir error"
25563
25564         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25565                 error "set striped cdir under striped dir error"
25566
25567         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25568                 error "rename dir under striped dir fails"
25569
25570         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25571                 error "rename dir under different stripes fails"
25572
25573         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25574                 error "rename file under striped dir should succeed"
25575
25576         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25577                 error "rename dir under striped dir should succeed"
25578
25579         rm -rf $DIR/$tdir
25580 }
25581 run_test 300e "check rename under striped directory"
25582
25583 test_300f() {
25584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25586         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25587                 skip "Need MDS version at least 2.7.55"
25588
25589         local stripe_count
25590         local file
25591
25592         rm -rf $DIR/$tdir
25593         mkdir -p $DIR/$tdir
25594
25595         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25596                 error "set striped dir error"
25597
25598         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25599                 error "set striped dir error"
25600
25601         touch $DIR/$tdir/striped_dir/a
25602         mkdir $DIR/$tdir/striped_dir/dir_a
25603         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25604                 error "create striped dir under striped dir fails"
25605
25606         touch $DIR/$tdir/striped_dir1/b
25607         mkdir $DIR/$tdir/striped_dir1/dir_b
25608         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25609                 error "create striped dir under striped dir fails"
25610
25611         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25612                 error "rename dir under different striped dir should fail"
25613
25614         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25615                 error "rename striped dir under diff striped dir should fail"
25616
25617         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25618                 error "rename file under diff striped dirs fails"
25619
25620         rm -rf $DIR/$tdir
25621 }
25622 run_test 300f "check rename cross striped directory"
25623
25624 test_300_check_default_striped_dir()
25625 {
25626         local dirname=$1
25627         local default_count=$2
25628         local default_index=$3
25629         local stripe_count
25630         local stripe_index
25631         local dir_stripe_index
25632         local dir
25633
25634         echo "checking $dirname $default_count $default_index"
25635         $LFS setdirstripe -D -c $default_count -i $default_index \
25636                                 -H all_char $DIR/$tdir/$dirname ||
25637                 error "set default stripe on striped dir error"
25638         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25639         [ $stripe_count -eq $default_count ] ||
25640                 error "expect $default_count get $stripe_count for $dirname"
25641
25642         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25643         [ $stripe_index -eq $default_index ] ||
25644                 error "expect $default_index get $stripe_index for $dirname"
25645
25646         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25647                                                 error "create dirs failed"
25648
25649         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25650         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25651         for dir in $(find $DIR/$tdir/$dirname/*); do
25652                 stripe_count=$($LFS getdirstripe -c $dir)
25653                 (( $stripe_count == $default_count )) ||
25654                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25655                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25656                 error "stripe count $default_count != $stripe_count for $dir"
25657
25658                 stripe_index=$($LFS getdirstripe -i $dir)
25659                 [ $default_index -eq -1 ] ||
25660                         [ $stripe_index -eq $default_index ] ||
25661                         error "$stripe_index != $default_index for $dir"
25662
25663                 #check default stripe
25664                 stripe_count=$($LFS getdirstripe -D -c $dir)
25665                 [ $stripe_count -eq $default_count ] ||
25666                 error "default count $default_count != $stripe_count for $dir"
25667
25668                 stripe_index=$($LFS getdirstripe -D -i $dir)
25669                 [ $stripe_index -eq $default_index ] ||
25670                 error "default index $default_index != $stripe_index for $dir"
25671         done
25672         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25673 }
25674
25675 test_300g() {
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         local stripe_index
25683
25684         mkdir_on_mdt0 $DIR/$tdir
25685         mkdir $DIR/$tdir/normal_dir
25686
25687         #Checking when client cache stripe index
25688         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25689         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25690                 error "create striped_dir failed"
25691
25692         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25693                 error "create dir0 fails"
25694         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25695         [ $stripe_index -eq 0 ] ||
25696                 error "dir0 expect index 0 got $stripe_index"
25697
25698         mkdir $DIR/$tdir/striped_dir/dir1 ||
25699                 error "create dir1 fails"
25700         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25701         [ $stripe_index -eq 1 ] ||
25702                 error "dir1 expect index 1 got $stripe_index"
25703
25704         #check default stripe count/stripe index
25705         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25706         test_300_check_default_striped_dir normal_dir 1 0
25707         test_300_check_default_striped_dir normal_dir -1 1
25708         test_300_check_default_striped_dir normal_dir 2 -1
25709
25710         #delete default stripe information
25711         echo "delete default stripeEA"
25712         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25713                 error "set default stripe on striped dir error"
25714
25715         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25716         for dir in $(find $DIR/$tdir/normal_dir/*); do
25717                 stripe_count=$($LFS getdirstripe -c $dir)
25718                 [ $stripe_count -eq 0 ] ||
25719                         error "expect 1 get $stripe_count for $dir"
25720         done
25721 }
25722 run_test 300g "check default striped directory for normal directory"
25723
25724 test_300h() {
25725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25726         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25727                 skip "Need MDS version at least 2.7.55"
25728
25729         local dir
25730         local stripe_count
25731
25732         mkdir $DIR/$tdir
25733         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25734                 error "set striped dir error"
25735
25736         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25737         test_300_check_default_striped_dir striped_dir 1 0
25738         test_300_check_default_striped_dir striped_dir -1 1
25739         test_300_check_default_striped_dir striped_dir 2 -1
25740
25741         #delete default stripe information
25742         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25743                 error "set default stripe on striped dir error"
25744
25745         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25746         for dir in $(find $DIR/$tdir/striped_dir/*); do
25747                 stripe_count=$($LFS getdirstripe -c $dir)
25748                 [ $stripe_count -eq 0 ] ||
25749                         error "expect 1 get $stripe_count for $dir"
25750         done
25751 }
25752 run_test 300h "check default striped directory for striped directory"
25753
25754 test_300i() {
25755         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25756         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25757         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25758                 skip "Need MDS version at least 2.7.55"
25759
25760         local stripe_count
25761         local file
25762
25763         mkdir $DIR/$tdir
25764
25765         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25766                 error "set striped dir error"
25767
25768         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25769                 error "create files under striped dir failed"
25770
25771         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25772                 error "set striped hashdir error"
25773
25774         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25775                 error "create dir0 under hash dir failed"
25776         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25777                 error "create dir1 under hash dir failed"
25778         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25779                 error "create dir2 under hash dir failed"
25780
25781         # unfortunately, we need to umount to clear dir layout cache for now
25782         # once we fully implement dir layout, we can drop this
25783         umount_client $MOUNT || error "umount failed"
25784         mount_client $MOUNT || error "mount failed"
25785
25786         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25787         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25788         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25789
25790         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25791                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25792                         error "create crush2 dir $tdir/hashdir/d3 failed"
25793                 $LFS find -H crush2 $DIR/$tdir/hashdir
25794                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25795                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25796
25797                 # mkdir with an invalid hash type (hash=fail_val) from client
25798                 # should be replaced on MDS with a valid (default) hash type
25799                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25800                 $LCTL set_param fail_loc=0x1901 fail_val=99
25801                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25802
25803                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25804                 local expect=$(do_facet mds1 \
25805                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25806                 [[ $hash == $expect ]] ||
25807                         error "d99 hash '$hash' != expected hash '$expect'"
25808         fi
25809
25810         #set the stripe to be unknown hash type on read
25811         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25812         $LCTL set_param fail_loc=0x1901 fail_val=99
25813         for ((i = 0; i < 10; i++)); do
25814                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25815                         error "stat f-$i failed"
25816                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25817         done
25818
25819         touch $DIR/$tdir/striped_dir/f0 &&
25820                 error "create under striped dir with unknown hash should fail"
25821
25822         $LCTL set_param fail_loc=0
25823
25824         umount_client $MOUNT || error "umount failed"
25825         mount_client $MOUNT || error "mount failed"
25826
25827         return 0
25828 }
25829 run_test 300i "client handle unknown hash type striped directory"
25830
25831 test_300j() {
25832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25834         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25835                 skip "Need MDS version at least 2.7.55"
25836
25837         local stripe_count
25838         local file
25839
25840         mkdir $DIR/$tdir
25841
25842         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25843         $LCTL set_param fail_loc=0x1702
25844         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25845                 error "set striped dir error"
25846
25847         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25848                 error "create files under striped dir failed"
25849
25850         $LCTL set_param fail_loc=0
25851
25852         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25853
25854         return 0
25855 }
25856 run_test 300j "test large update record"
25857
25858 test_300k() {
25859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25861         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25862                 skip "Need MDS version at least 2.7.55"
25863
25864         # this test needs a huge transaction
25865         local kb
25866         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25867              osd*.$FSNAME-MDT0000.kbytestotal")
25868         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25869
25870         local stripe_count
25871         local file
25872
25873         mkdir $DIR/$tdir
25874
25875         #define OBD_FAIL_LARGE_STRIPE   0x1703
25876         $LCTL set_param fail_loc=0x1703
25877         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25878                 error "set striped dir error"
25879         $LCTL set_param fail_loc=0
25880
25881         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25882                 error "getstripeddir fails"
25883         rm -rf $DIR/$tdir/striped_dir ||
25884                 error "unlink striped dir fails"
25885
25886         return 0
25887 }
25888 run_test 300k "test large striped directory"
25889
25890 test_300l() {
25891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25893         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25894                 skip "Need MDS version at least 2.7.55"
25895
25896         local stripe_index
25897
25898         test_mkdir -p $DIR/$tdir/striped_dir
25899         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25900                         error "chown $RUNAS_ID failed"
25901         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25902                 error "set default striped dir failed"
25903
25904         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25905         $LCTL set_param fail_loc=0x80000158
25906         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25907
25908         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25909         [ $stripe_index -eq 1 ] ||
25910                 error "expect 1 get $stripe_index for $dir"
25911 }
25912 run_test 300l "non-root user to create dir under striped dir with stale layout"
25913
25914 test_300m() {
25915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25916         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25917         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25918                 skip "Need MDS version at least 2.7.55"
25919
25920         mkdir -p $DIR/$tdir/striped_dir
25921         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25922                 error "set default stripes dir error"
25923
25924         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25925
25926         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25927         [ $stripe_count -eq 0 ] ||
25928                         error "expect 0 get $stripe_count for a"
25929
25930         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25931                 error "set default stripes dir error"
25932
25933         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25934
25935         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25936         [ $stripe_count -eq 0 ] ||
25937                         error "expect 0 get $stripe_count for b"
25938
25939         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25940                 error "set default stripes dir error"
25941
25942         mkdir $DIR/$tdir/striped_dir/c &&
25943                 error "default stripe_index is invalid, mkdir c should fails"
25944
25945         rm -rf $DIR/$tdir || error "rmdir fails"
25946 }
25947 run_test 300m "setstriped directory on single MDT FS"
25948
25949 cleanup_300n() {
25950         local list=$(comma_list $(mdts_nodes))
25951
25952         trap 0
25953         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25954 }
25955
25956 test_300n() {
25957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25960                 skip "Need MDS version at least 2.7.55"
25961         remote_mds_nodsh && skip "remote MDS with nodsh"
25962
25963         local stripe_index
25964         local list=$(comma_list $(mdts_nodes))
25965
25966         trap cleanup_300n RETURN EXIT
25967         mkdir -p $DIR/$tdir
25968         chmod 777 $DIR/$tdir
25969         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25970                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25971                 error "create striped dir succeeds with gid=0"
25972
25973         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25974         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25975                 error "create striped dir fails with gid=-1"
25976
25977         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25978         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25979                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25980                 error "set default striped dir succeeds with gid=0"
25981
25982
25983         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25984         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25985                 error "set default striped dir fails with gid=-1"
25986
25987
25988         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25989         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25990                                         error "create test_dir fails"
25991         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25992                                         error "create test_dir1 fails"
25993         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25994                                         error "create test_dir2 fails"
25995         cleanup_300n
25996 }
25997 run_test 300n "non-root user to create dir under striped dir with default EA"
25998
25999 test_300o() {
26000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26001         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26002         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26003                 skip "Need MDS version at least 2.7.55"
26004
26005         local numfree1
26006         local numfree2
26007
26008         mkdir -p $DIR/$tdir
26009
26010         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26011         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26012         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26013                 skip "not enough free inodes $numfree1 $numfree2"
26014         fi
26015
26016         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26017         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26018         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26019                 skip "not enough free space $numfree1 $numfree2"
26020         fi
26021
26022         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26023                 error "setdirstripe fails"
26024
26025         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26026                 error "create dirs fails"
26027
26028         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26029         ls $DIR/$tdir/striped_dir > /dev/null ||
26030                 error "ls striped dir fails"
26031         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26032                 error "unlink big striped dir fails"
26033 }
26034 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26035
26036 test_300p() {
26037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26039         remote_mds_nodsh && skip "remote MDS with nodsh"
26040
26041         mkdir_on_mdt0 $DIR/$tdir
26042
26043         #define OBD_FAIL_OUT_ENOSPC     0x1704
26044         do_facet mds2 lctl set_param fail_loc=0x80001704
26045         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26046                  && error "create striped directory should fail"
26047
26048         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26049
26050         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26051         true
26052 }
26053 run_test 300p "create striped directory without space"
26054
26055 test_300q() {
26056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26058
26059         local fd=$(free_fd)
26060         local cmd="exec $fd<$tdir"
26061         cd $DIR
26062         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26063         eval $cmd
26064         cmd="exec $fd<&-"
26065         trap "eval $cmd" EXIT
26066         cd $tdir || error "cd $tdir fails"
26067         rmdir  ../$tdir || error "rmdir $tdir fails"
26068         mkdir local_dir && error "create dir succeeds"
26069         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26070         eval $cmd
26071         return 0
26072 }
26073 run_test 300q "create remote directory under orphan directory"
26074
26075 test_300r() {
26076         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26077                 skip "Need MDS version at least 2.7.55" && return
26078         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26079
26080         mkdir $DIR/$tdir
26081
26082         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26083                 error "set striped dir error"
26084
26085         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26086                 error "getstripeddir fails"
26087
26088         local stripe_count
26089         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26090                       awk '/lmv_stripe_count:/ { print $2 }')
26091
26092         [ $MDSCOUNT -ne $stripe_count ] &&
26093                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26094
26095         rm -rf $DIR/$tdir/striped_dir ||
26096                 error "unlink striped dir fails"
26097 }
26098 run_test 300r "test -1 striped directory"
26099
26100 test_300s_helper() {
26101         local count=$1
26102
26103         local stripe_dir=$DIR/$tdir/striped_dir.$count
26104
26105         $LFS mkdir -c $count $stripe_dir ||
26106                 error "lfs mkdir -c error"
26107
26108         $LFS getdirstripe $stripe_dir ||
26109                 error "lfs getdirstripe fails"
26110
26111         local stripe_count
26112         stripe_count=$($LFS getdirstripe $stripe_dir |
26113                       awk '/lmv_stripe_count:/ { print $2 }')
26114
26115         [ $count -ne $stripe_count ] &&
26116                 error_noexit "bad stripe count $stripe_count expected $count"
26117
26118         local dupe_stripes
26119         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26120                 awk '/0x/ {count[$1] += 1}; END {
26121                         for (idx in count) {
26122                                 if (count[idx]>1) {
26123                                         print "index " idx " count " count[idx]
26124                                 }
26125                         }
26126                 }')
26127
26128         if [[ -n "$dupe_stripes" ]] ; then
26129                 lfs getdirstripe $stripe_dir
26130                 error_noexit "Dupe MDT above: $dupe_stripes "
26131         fi
26132
26133         rm -rf $stripe_dir ||
26134                 error_noexit "unlink $stripe_dir fails"
26135 }
26136
26137 test_300s() {
26138         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26139                 skip "Need MDS version at least 2.7.55" && return
26140         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26141
26142         mkdir $DIR/$tdir
26143         for count in $(seq 2 $MDSCOUNT); do
26144                 test_300s_helper $count
26145         done
26146 }
26147 run_test 300s "test lfs mkdir -c without -i"
26148
26149 test_300t() {
26150         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26151                 skip "need MDS 2.14.55 or later"
26152         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26153
26154         local testdir="$DIR/$tdir/striped_dir"
26155         local dir1=$testdir/dir1
26156         local dir2=$testdir/dir2
26157
26158         mkdir -p $testdir
26159
26160         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26161                 error "failed to set default stripe count for $testdir"
26162
26163         mkdir $dir1
26164         local stripe_count=$($LFS getdirstripe -c $dir1)
26165
26166         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26167
26168         local max_count=$((MDSCOUNT - 1))
26169         local mdts=$(comma_list $(mdts_nodes))
26170
26171         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26172         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26173
26174         mkdir $dir2
26175         stripe_count=$($LFS getdirstripe -c $dir2)
26176
26177         (( $stripe_count == $max_count )) || error "wrong stripe count"
26178 }
26179 run_test 300t "test max_mdt_stripecount"
26180
26181 prepare_remote_file() {
26182         mkdir $DIR/$tdir/src_dir ||
26183                 error "create remote source failed"
26184
26185         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26186                  error "cp to remote source failed"
26187         touch $DIR/$tdir/src_dir/a
26188
26189         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26190                 error "create remote target dir failed"
26191
26192         touch $DIR/$tdir/tgt_dir/b
26193
26194         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26195                 error "rename dir cross MDT failed!"
26196
26197         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26198                 error "src_child still exists after rename"
26199
26200         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26201                 error "missing file(a) after rename"
26202
26203         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26204                 error "diff after rename"
26205 }
26206
26207 test_310a() {
26208         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26210
26211         local remote_file=$DIR/$tdir/tgt_dir/b
26212
26213         mkdir -p $DIR/$tdir
26214
26215         prepare_remote_file || error "prepare remote file failed"
26216
26217         #open-unlink file
26218         $OPENUNLINK $remote_file $remote_file ||
26219                 error "openunlink $remote_file failed"
26220         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26221 }
26222 run_test 310a "open unlink remote file"
26223
26224 test_310b() {
26225         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26227
26228         local remote_file=$DIR/$tdir/tgt_dir/b
26229
26230         mkdir -p $DIR/$tdir
26231
26232         prepare_remote_file || error "prepare remote file failed"
26233
26234         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26235         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26236         $CHECKSTAT -t file $remote_file || error "check file failed"
26237 }
26238 run_test 310b "unlink remote file with multiple links while open"
26239
26240 test_310c() {
26241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26242         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26243
26244         local remote_file=$DIR/$tdir/tgt_dir/b
26245
26246         mkdir -p $DIR/$tdir
26247
26248         prepare_remote_file || error "prepare remote file failed"
26249
26250         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26251         multiop_bg_pause $remote_file O_uc ||
26252                         error "mulitop failed for remote file"
26253         MULTIPID=$!
26254         $MULTIOP $DIR/$tfile Ouc
26255         kill -USR1 $MULTIPID
26256         wait $MULTIPID
26257 }
26258 run_test 310c "open-unlink remote file with multiple links"
26259
26260 #LU-4825
26261 test_311() {
26262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26263         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26264         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26265                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26266         remote_mds_nodsh && skip "remote MDS with nodsh"
26267
26268         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26269         local mdts=$(comma_list $(mdts_nodes))
26270
26271         mkdir -p $DIR/$tdir
26272         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26273         createmany -o $DIR/$tdir/$tfile. 1000
26274
26275         # statfs data is not real time, let's just calculate it
26276         old_iused=$((old_iused + 1000))
26277
26278         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26279                         osp.*OST0000*MDT0000.create_count")
26280         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26281                                 osp.*OST0000*MDT0000.max_create_count")
26282         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26283
26284         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26285         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26286         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26287
26288         unlinkmany $DIR/$tdir/$tfile. 1000
26289
26290         do_nodes $mdts "$LCTL set_param -n \
26291                         osp.*OST0000*.max_create_count=$max_count"
26292         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26293                 do_nodes $mdts "$LCTL set_param -n \
26294                                 osp.*OST0000*.create_count=$count"
26295         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26296                         grep "=0" && error "create_count is zero"
26297
26298         local new_iused
26299         for i in $(seq 120); do
26300                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26301                 # system may be too busy to destroy all objs in time, use
26302                 # a somewhat small value to not fail autotest
26303                 [ $((old_iused - new_iused)) -gt 400 ] && break
26304                 sleep 1
26305         done
26306
26307         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26308         [ $((old_iused - new_iused)) -gt 400 ] ||
26309                 error "objs not destroyed after unlink"
26310 }
26311 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26312
26313 zfs_get_objid()
26314 {
26315         local ost=$1
26316         local tf=$2
26317         local fid=($($LFS getstripe $tf | grep 0x))
26318         local seq=${fid[3]#0x}
26319         local objid=${fid[1]}
26320
26321         local vdevdir=$(dirname $(facet_vdevice $ost))
26322         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26323         local zfs_zapid=$(do_facet $ost $cmd |
26324                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26325                           awk '/Object/{getline; print $1}')
26326         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26327                           awk "/$objid = /"'{printf $3}')
26328
26329         echo $zfs_objid
26330 }
26331
26332 zfs_object_blksz() {
26333         local ost=$1
26334         local objid=$2
26335
26336         local vdevdir=$(dirname $(facet_vdevice $ost))
26337         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26338         local blksz=$(do_facet $ost $cmd $objid |
26339                       awk '/dblk/{getline; printf $4}')
26340
26341         case "${blksz: -1}" in
26342                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26343                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26344                 *) ;;
26345         esac
26346
26347         echo $blksz
26348 }
26349
26350 test_312() { # LU-4856
26351         remote_ost_nodsh && skip "remote OST with nodsh"
26352         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26353
26354         local max_blksz=$(do_facet ost1 \
26355                           $ZFS get -p recordsize $(facet_device ost1) |
26356                           awk '!/VALUE/{print $3}')
26357         local tf=$DIR/$tfile
26358
26359         $LFS setstripe -c1 $tf
26360         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26361
26362         # Get ZFS object id
26363         local zfs_objid=$(zfs_get_objid $facet $tf)
26364         # block size change by sequential overwrite
26365         local bs
26366
26367         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26368                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26369
26370                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26371                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26372         done
26373         rm -f $tf
26374
26375         $LFS setstripe -c1 $tf
26376         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26377
26378         # block size change by sequential append write
26379         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26380         zfs_objid=$(zfs_get_objid $facet $tf)
26381         local count
26382
26383         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26384                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26385                         oflag=sync conv=notrunc
26386
26387                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26388                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26389                         error "blksz error, actual $blksz, " \
26390                                 "expected: 2 * $count * $PAGE_SIZE"
26391         done
26392         rm -f $tf
26393
26394         # random write
26395         $LFS setstripe -c1 $tf
26396         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26397         zfs_objid=$(zfs_get_objid $facet $tf)
26398
26399         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26400         blksz=$(zfs_object_blksz $facet $zfs_objid)
26401         (( blksz == PAGE_SIZE )) ||
26402                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26403
26404         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26405         blksz=$(zfs_object_blksz $facet $zfs_objid)
26406         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26407
26408         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26409         blksz=$(zfs_object_blksz $facet $zfs_objid)
26410         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26411 }
26412 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26413
26414 test_313() {
26415         remote_ost_nodsh && skip "remote OST with nodsh"
26416
26417         local file=$DIR/$tfile
26418
26419         rm -f $file
26420         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26421
26422         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26423         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26424         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26425                 error "write should failed"
26426         do_facet ost1 "$LCTL set_param fail_loc=0"
26427         rm -f $file
26428 }
26429 run_test 313 "io should fail after last_rcvd update fail"
26430
26431 test_314() {
26432         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26433
26434         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26435         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26436         rm -f $DIR/$tfile
26437         wait_delete_completed
26438         do_facet ost1 "$LCTL set_param fail_loc=0"
26439 }
26440 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26441
26442 test_315() { # LU-618
26443         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26444
26445         local file=$DIR/$tfile
26446         rm -f $file
26447
26448         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26449                 error "multiop file write failed"
26450         $MULTIOP $file oO_RDONLY:r4063232_c &
26451         PID=$!
26452
26453         sleep 2
26454
26455         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26456         kill -USR1 $PID
26457
26458         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26459         rm -f $file
26460 }
26461 run_test 315 "read should be accounted"
26462
26463 test_316() {
26464         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26465         large_xattr_enabled || skip "ea_inode feature disabled"
26466
26467         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26468         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26469         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26470         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26471
26472         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26473 }
26474 run_test 316 "lfs migrate of file with large_xattr enabled"
26475
26476 test_317() {
26477         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26478                 skip "Need MDS version at least 2.11.53"
26479         if [ "$ost1_FSTYPE" == "zfs" ]; then
26480                 skip "LU-10370: no implementation for ZFS"
26481         fi
26482
26483         local trunc_sz
26484         local grant_blk_size
26485
26486         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26487                         awk '/grant_block_size:/ { print $2; exit; }')
26488         #
26489         # Create File of size 5M. Truncate it to below size's and verify
26490         # blocks count.
26491         #
26492         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26493                 error "Create file $DIR/$tfile failed"
26494         stack_trap "rm -f $DIR/$tfile" EXIT
26495
26496         for trunc_sz in 2097152 4097 4000 509 0; do
26497                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26498                         error "truncate $tfile to $trunc_sz failed"
26499                 local sz=$(stat --format=%s $DIR/$tfile)
26500                 local blk=$(stat --format=%b $DIR/$tfile)
26501                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26502                                      grant_blk_size) * 8))
26503
26504                 if [[ $blk -ne $trunc_blk ]]; then
26505                         $(which stat) $DIR/$tfile
26506                         error "Expected Block $trunc_blk got $blk for $tfile"
26507                 fi
26508
26509                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26510                         error "Expected Size $trunc_sz got $sz for $tfile"
26511         done
26512
26513         #
26514         # sparse file test
26515         # Create file with a hole and write actual 65536 bytes which aligned
26516         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26517         #
26518         local bs=65536
26519         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26520                 error "Create file : $DIR/$tfile"
26521
26522         #
26523         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26524         # blocks. The block count must drop to 8.
26525         #
26526         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26527                 ((bs - grant_blk_size) + 1)))
26528         $TRUNCATE $DIR/$tfile $trunc_sz ||
26529                 error "truncate $tfile to $trunc_sz failed"
26530
26531         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26532         sz=$(stat --format=%s $DIR/$tfile)
26533         blk=$(stat --format=%b $DIR/$tfile)
26534
26535         if [[ $blk -ne $trunc_bsz ]]; then
26536                 $(which stat) $DIR/$tfile
26537                 error "Expected Block $trunc_bsz got $blk for $tfile"
26538         fi
26539
26540         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26541                 error "Expected Size $trunc_sz got $sz for $tfile"
26542 }
26543 run_test 317 "Verify blocks get correctly update after truncate"
26544
26545 test_318() {
26546         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26547         local old_max_active=$($LCTL get_param -n \
26548                             ${llite_name}.max_read_ahead_async_active \
26549                             2>/dev/null)
26550
26551         $LCTL set_param llite.*.max_read_ahead_async_active=256
26552         local max_active=$($LCTL get_param -n \
26553                            ${llite_name}.max_read_ahead_async_active \
26554                            2>/dev/null)
26555         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26556
26557         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26558                 error "set max_read_ahead_async_active should succeed"
26559
26560         $LCTL set_param llite.*.max_read_ahead_async_active=512
26561         max_active=$($LCTL get_param -n \
26562                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26563         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26564
26565         # restore @max_active
26566         [ $old_max_active -ne 0 ] && $LCTL set_param \
26567                 llite.*.max_read_ahead_async_active=$old_max_active
26568
26569         local old_threshold=$($LCTL get_param -n \
26570                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26571         local max_per_file_mb=$($LCTL get_param -n \
26572                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26573
26574         local invalid=$(($max_per_file_mb + 1))
26575         $LCTL set_param \
26576                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26577                         && error "set $invalid should fail"
26578
26579         local valid=$(($invalid - 1))
26580         $LCTL set_param \
26581                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26582                         error "set $valid should succeed"
26583         local threshold=$($LCTL get_param -n \
26584                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26585         [ $threshold -eq $valid ] || error \
26586                 "expect threshold $valid got $threshold"
26587         $LCTL set_param \
26588                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26589 }
26590 run_test 318 "Verify async readahead tunables"
26591
26592 test_319() {
26593         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26594
26595         local before=$(date +%s)
26596         local evict
26597         local mdir=$DIR/$tdir
26598         local file=$mdir/xxx
26599
26600         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26601         touch $file
26602
26603 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26604         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26605         $LFS migrate -m1 $mdir &
26606
26607         sleep 1
26608         dd if=$file of=/dev/null
26609         wait
26610         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26611           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26612
26613         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26614 }
26615 run_test 319 "lost lease lock on migrate error"
26616
26617 test_360() {
26618         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26619                 skip "Need OST version at least 2.15.58.96"
26620         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26621
26622         check_set_fallocate_or_skip
26623         local param="osd-ldiskfs.delayed_unlink_mb"
26624         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26625
26626         do_facet ost1 "$LCTL set_param $param=1MiB"
26627         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26628
26629         mkdir $DIR/$tdir/
26630         do_facet ost1 $LCTL set_param debug=+inode
26631         do_facet ost1 $LCTL clear
26632         local files=100
26633
26634         for ((i = 0; i < $files; i++)); do
26635                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26636                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26637         done
26638         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26639
26640         for ((i = 0; i < $files; i++)); do
26641                 unlink $DIR/$tdir/$tfile.$i ||
26642                         error "unlink $DIR/$tdir/$tfile.$i failed"
26643         done
26644
26645         local count=0
26646         local loop
26647
26648         for (( loop = 0; loop < 30 && count < min; loop++)); do
26649                 sleep 1
26650                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26651                 echo "Count[$loop]: $count"
26652         done
26653         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26654 }
26655 run_test 360 "ldiskfs unlink in a separate thread"
26656
26657 test_398a() { # LU-4198
26658         local ost1_imp=$(get_osc_import_name client ost1)
26659         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26660                          cut -d'.' -f2)
26661
26662         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26663         stack_trap "rm -f $DIR/$tfile"
26664         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26665
26666         # request a new lock on client
26667         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26668
26669         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26670         local lock_count=$($LCTL get_param -n \
26671                            ldlm.namespaces.$imp_name.lru_size)
26672         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26673
26674         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26675
26676         # no lock cached, should use lockless DIO and not enqueue new lock
26677         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26678         lock_count=$($LCTL get_param -n \
26679                      ldlm.namespaces.$imp_name.lru_size)
26680         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26681
26682         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26683
26684         # no lock cached, should use locked DIO append
26685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26686                 conv=notrunc || error "DIO append failed"
26687         lock_count=$($LCTL get_param -n \
26688                      ldlm.namespaces.$imp_name.lru_size)
26689         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26690 }
26691 run_test 398a "direct IO should cancel lock otherwise lockless"
26692
26693 test_398b() { # LU-4198
26694         local before=$(date +%s)
26695         local njobs=4
26696         local size=48
26697
26698         which fio || skip_env "no fio installed"
26699         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26700         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26701
26702         # Single page, multiple pages, stripe size, 4*stripe size
26703         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26704                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26705                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26706                         --numjobs=$njobs --fallocate=none \
26707                         --iodepth=16 --allow_file_create=0 \
26708                         --size=$((size/njobs))M \
26709                         --filename=$DIR/$tfile &
26710                 bg_pid=$!
26711
26712                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26713                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26714                         --numjobs=$njobs --fallocate=none \
26715                         --iodepth=16 --allow_file_create=0 \
26716                         --size=$((size/njobs))M \
26717                         --filename=$DIR/$tfile || true
26718                 wait $bg_pid
26719         done
26720
26721         evict=$(do_facet client $LCTL get_param \
26722                 osc.$FSNAME-OST*-osc-*/state |
26723             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26724
26725         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26726                 (do_facet client $LCTL get_param \
26727                         osc.$FSNAME-OST*-osc-*/state;
26728                     error "eviction happened: $evict before:$before")
26729
26730         rm -f $DIR/$tfile
26731 }
26732 run_test 398b "DIO and buffer IO race"
26733
26734 test_398c() { # LU-4198
26735         local ost1_imp=$(get_osc_import_name client ost1)
26736         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26737                          cut -d'.' -f2)
26738
26739         which fio || skip_env "no fio installed"
26740
26741         saved_debug=$($LCTL get_param -n debug)
26742         $LCTL set_param debug=0
26743
26744         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26745         ((size /= 1024)) # by megabytes
26746         ((size /= 2)) # write half of the OST at most
26747         [ $size -gt 40 ] && size=40 #reduce test time anyway
26748
26749         $LFS setstripe -c 1 $DIR/$tfile
26750
26751         # it seems like ldiskfs reserves more space than necessary if the
26752         # writing blocks are not mapped, so it extends the file firstly
26753         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26754         cancel_lru_locks osc
26755
26756         # clear and verify rpc_stats later
26757         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26758
26759         local njobs=4
26760         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26761         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26762                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26763                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26764                 --filename=$DIR/$tfile
26765         [ $? -eq 0 ] || error "fio write error"
26766
26767         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26768                 error "Locks were requested while doing AIO"
26769
26770         # get the percentage of 1-page I/O
26771         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26772                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26773                 awk '{print $7}')
26774         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26775
26776         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26777         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26778                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26779                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26780                 --filename=$DIR/$tfile
26781         [ $? -eq 0 ] || error "fio mixed read write error"
26782
26783         echo "AIO with large block size ${size}M"
26784         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26785                 --numjobs=1 --fallocate=none --ioengine=libaio \
26786                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26787                 --filename=$DIR/$tfile
26788         [ $? -eq 0 ] || error "fio large block size failed"
26789
26790         rm -f $DIR/$tfile
26791         $LCTL set_param debug="$saved_debug"
26792 }
26793 run_test 398c "run fio to test AIO"
26794
26795 test_398d() { #  LU-13846
26796         which aiocp || skip_env "no aiocp installed"
26797         local aio_file=$DIR/$tfile.aio
26798
26799         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26800
26801         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26802         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26803         stack_trap "rm -f $DIR/$tfile $aio_file"
26804
26805         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26806
26807         # test memory unaligned aio
26808         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26809                 error "unaligned aio failed"
26810         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26811
26812         rm -f $DIR/$tfile $aio_file
26813 }
26814 run_test 398d "run aiocp to verify block size > stripe size"
26815
26816 test_398e() {
26817         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26818         touch $DIR/$tfile.new
26819         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26820 }
26821 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26822
26823 test_398f() { #  LU-14687
26824         which aiocp || skip_env "no aiocp installed"
26825         local aio_file=$DIR/$tfile.aio
26826
26827         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26828
26829         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26830         stack_trap "rm -f $DIR/$tfile $aio_file"
26831
26832         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26833         $LCTL set_param fail_loc=0x1418
26834         # make sure we don't crash and fail properly
26835         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26836                 error "aio with page allocation failure succeeded"
26837         $LCTL set_param fail_loc=0
26838         diff $DIR/$tfile $aio_file
26839         [[ $? != 0 ]] || error "no diff after failed aiocp"
26840 }
26841 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26842
26843 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26844 # stripe and i/o size must be > stripe size
26845 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26846 # single RPC in flight.  This test shows async DIO submission is working by
26847 # showing multiple RPCs in flight.
26848 test_398g() { #  LU-13798
26849         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26850
26851         # We need to do some i/o first to acquire enough grant to put our RPCs
26852         # in flight; otherwise a new connection may not have enough grant
26853         # available
26854         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26855                 error "parallel dio failed"
26856         stack_trap "rm -f $DIR/$tfile"
26857
26858         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26859         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26860         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26861         stack_trap "$LCTL set_param -n $pages_per_rpc"
26862
26863         # Recreate file so it's empty
26864         rm -f $DIR/$tfile
26865         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26866         #Pause rpc completion to guarantee we see multiple rpcs in flight
26867         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26868         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26869         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26870
26871         # Clear rpc stats
26872         $LCTL set_param osc.*.rpc_stats=c
26873
26874         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26875                 error "parallel dio failed"
26876         stack_trap "rm -f $DIR/$tfile"
26877
26878         $LCTL get_param osc.*-OST0000-*.rpc_stats
26879         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26880                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26881                 grep "8:" | awk '{print $8}')
26882         # We look at the "8 rpcs in flight" field, and verify A) it is present
26883         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26884         # as expected for an 8M DIO to a file with 1M stripes.
26885         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26886
26887         # Verify turning off parallel dio works as expected
26888         # Clear rpc stats
26889         $LCTL set_param osc.*.rpc_stats=c
26890         $LCTL set_param llite.*.parallel_dio=0
26891         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26892
26893         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26894                 error "dio with parallel dio disabled failed"
26895
26896         # Ideally, we would see only one RPC in flight here, but there is an
26897         # unavoidable race between i/o completion and RPC in flight counting,
26898         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26899         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26900         # So instead we just verify it's always < 8.
26901         $LCTL get_param osc.*-OST0000-*.rpc_stats
26902         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26903                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26904                 grep '^$' -B1 | grep . | awk '{print $1}')
26905         [ $ret != "8:" ] ||
26906                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26907 }
26908 run_test 398g "verify parallel dio async RPC submission"
26909
26910 test_398h() { #  LU-13798
26911         local dio_file=$DIR/$tfile.dio
26912
26913         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26914
26915         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26916         stack_trap "rm -f $DIR/$tfile $dio_file"
26917
26918         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26919                 error "parallel dio failed"
26920         diff $DIR/$tfile $dio_file
26921         [[ $? == 0 ]] || error "file diff after aiocp"
26922 }
26923 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26924
26925 test_398i() { #  LU-13798
26926         local dio_file=$DIR/$tfile.dio
26927
26928         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26929
26930         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26931         stack_trap "rm -f $DIR/$tfile $dio_file"
26932
26933         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26934         $LCTL set_param fail_loc=0x1418
26935         # make sure we don't crash and fail properly
26936         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26937                 error "parallel dio page allocation failure succeeded"
26938         diff $DIR/$tfile $dio_file
26939         [[ $? != 0 ]] || error "no diff after failed aiocp"
26940 }
26941 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26942
26943 test_398j() { #  LU-13798
26944         # Stripe size > RPC size but less than i/o size tests split across
26945         # stripes and RPCs for individual i/o op
26946         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26947
26948         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26949         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26950         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26951         stack_trap "$LCTL set_param -n $pages_per_rpc"
26952
26953         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26954                 error "parallel dio write failed"
26955         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26956
26957         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26958                 error "parallel dio read failed"
26959         diff $DIR/$tfile $DIR/$tfile.2
26960         [[ $? == 0 ]] || error "file diff after parallel dio read"
26961 }
26962 run_test 398j "test parallel dio where stripe size > rpc_size"
26963
26964 test_398k() { #  LU-13798
26965         wait_delete_completed
26966         wait_mds_ost_sync
26967
26968         # 4 stripe file; we will cause out of space on OST0
26969         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26970
26971         # Fill OST0 (if it's not too large)
26972         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26973                    head -n1)
26974         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26975                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26976         fi
26977         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26978         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26979                 error "dd should fill OST0"
26980         stack_trap "rm -f $DIR/$tfile.1"
26981
26982         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26983         err=$?
26984
26985         ls -la $DIR/$tfile
26986         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26987                 error "file is not 0 bytes in size"
26988
26989         # dd above should not succeed, but don't error until here so we can
26990         # get debug info above
26991         [[ $err != 0 ]] ||
26992                 error "parallel dio write with enospc succeeded"
26993         stack_trap "rm -f $DIR/$tfile"
26994 }
26995 run_test 398k "test enospc on first stripe"
26996
26997 test_398l() { #  LU-13798
26998         wait_delete_completed
26999         wait_mds_ost_sync
27000
27001         # 4 stripe file; we will cause out of space on OST0
27002         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27003         # happens on the second i/o chunk we issue
27004         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27005
27006         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27007         stack_trap "rm -f $DIR/$tfile"
27008
27009         # Fill OST0 (if it's not too large)
27010         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27011                    head -n1)
27012         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27013                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27014         fi
27015         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27016         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27017                 error "dd should fill OST0"
27018         stack_trap "rm -f $DIR/$tfile.1"
27019
27020         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27021         err=$?
27022         stack_trap "rm -f $DIR/$tfile.2"
27023
27024         # Check that short write completed as expected
27025         ls -la $DIR/$tfile.2
27026         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27027                 error "file is not 1M in size"
27028
27029         # dd above should not succeed, but don't error until here so we can
27030         # get debug info above
27031         [[ $err != 0 ]] ||
27032                 error "parallel dio write with enospc succeeded"
27033
27034         # Truncate source file to same length as output file and diff them
27035         $TRUNCATE $DIR/$tfile 1048576
27036         diff $DIR/$tfile $DIR/$tfile.2
27037         [[ $? == 0 ]] || error "data incorrect after short write"
27038 }
27039 run_test 398l "test enospc on intermediate stripe/RPC"
27040
27041 test_398m() { #  LU-13798
27042         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27043
27044         # Set up failure on OST0, the first stripe:
27045         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27046         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27047         # OST0 is on ost1, OST1 is on ost2.
27048         # So this fail_val specifies OST0
27049         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27050         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27051
27052         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27053                 error "parallel dio write with failure on first stripe succeeded"
27054         stack_trap "rm -f $DIR/$tfile"
27055         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27056
27057         # Place data in file for read
27058         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27059                 error "parallel dio write failed"
27060
27061         # Fail read on OST0, first stripe
27062         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27063         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27064         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27065                 error "parallel dio read with error on first stripe succeeded"
27066         rm -f $DIR/$tfile.2
27067         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27068
27069         # Switch to testing on OST1, second stripe
27070         # Clear file contents, maintain striping
27071         echo > $DIR/$tfile
27072         # Set up failure on OST1, second stripe:
27073         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27074         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27075
27076         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27077                 error "parallel dio write with failure on second stripe succeeded"
27078         stack_trap "rm -f $DIR/$tfile"
27079         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27080
27081         # Place data in file for read
27082         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27083                 error "parallel dio write failed"
27084
27085         # Fail read on OST1, second stripe
27086         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27087         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27088         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27089                 error "parallel dio read with error on second stripe succeeded"
27090         rm -f $DIR/$tfile.2
27091         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27092 }
27093 run_test 398m "test RPC failures with parallel dio"
27094
27095 # Parallel submission of DIO should not cause problems for append, but it's
27096 # important to verify.
27097 test_398n() { #  LU-13798
27098         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27099
27100         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27101                 error "dd to create source file failed"
27102         stack_trap "rm -f $DIR/$tfile"
27103
27104         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27105                 error "parallel dio write with failure on second stripe succeeded"
27106         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27107         diff $DIR/$tfile $DIR/$tfile.1
27108         [[ $? == 0 ]] || error "data incorrect after append"
27109
27110 }
27111 run_test 398n "test append with parallel DIO"
27112
27113 test_398o() {
27114         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27115 }
27116 run_test 398o "right kms with DIO"
27117
27118 test_398p()
27119 {
27120         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27121         which aiocp || skip_env "no aiocp installed"
27122
27123         local stripe_size=$((1024 * 1024)) #1 MiB
27124         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27125         local file_size=$((25 * stripe_size))
27126
27127         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27128         stack_trap "rm -f $DIR/$tfile*"
27129         # Just a bit bigger than the largest size in the test set below
27130         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27131                 error "buffered i/o to create file failed"
27132
27133         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27134                 $((stripe_size * 4)); do
27135
27136                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27137
27138                 echo "bs: $bs, file_size $file_size"
27139                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27140                         $DIR/$tfile.1 $DIR/$tfile.2 &
27141                 pid_dio1=$!
27142                 # Buffered I/O with similar but not the same block size
27143                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27144                         conv=notrunc &
27145                 pid_bio2=$!
27146                 wait $pid_dio1
27147                 rc1=$?
27148                 wait $pid_bio2
27149                 rc2=$?
27150                 if (( rc1 != 0 )); then
27151                         error "aio copy 1 w/bsize $bs failed: $rc1"
27152                 fi
27153                 if (( rc2 != 0 )); then
27154                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27155                 fi
27156
27157                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27158                         error "size incorrect"
27159                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27160                         error "files differ, bsize $bs"
27161                 rm -f $DIR/$tfile.2
27162         done
27163 }
27164 run_test 398p "race aio with buffered i/o"
27165
27166 test_398q()
27167 {
27168         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27169
27170         local stripe_size=$((1024 * 1024)) #1 MiB
27171         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27172         local file_size=$((25 * stripe_size))
27173
27174         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27175         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27176
27177         # Just a bit bigger than the largest size in the test set below
27178         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27179                 error "buffered i/o to create file failed"
27180
27181         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27182                 $((stripe_size * 4)); do
27183
27184                 echo "bs: $bs, file_size $file_size"
27185                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27186                         conv=notrunc oflag=direct iflag=direct &
27187                 pid_dio1=$!
27188                 # Buffered I/O with similar but not the same block size
27189                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27190                         conv=notrunc &
27191                 pid_bio2=$!
27192                 wait $pid_dio1
27193                 rc1=$?
27194                 wait $pid_bio2
27195                 rc2=$?
27196                 if (( rc1 != 0 )); then
27197                         error "dio copy 1 w/bsize $bs failed: $rc1"
27198                 fi
27199                 if (( rc2 != 0 )); then
27200                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27201                 fi
27202
27203                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27204                         error "size incorrect"
27205                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27206                         error "files differ, bsize $bs"
27207         done
27208
27209         rm -f $DIR/$tfile*
27210 }
27211 run_test 398q "race dio with buffered i/o"
27212
27213 test_fake_rw() {
27214         local read_write=$1
27215         if [ "$read_write" = "write" ]; then
27216                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27217         elif [ "$read_write" = "read" ]; then
27218                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27219         else
27220                 error "argument error"
27221         fi
27222
27223         # turn off debug for performance testing
27224         local saved_debug=$($LCTL get_param -n debug)
27225         $LCTL set_param debug=0
27226
27227         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27228
27229         # get ost1 size - $FSNAME-OST0000
27230         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27231         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27232         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27233
27234         if [ "$read_write" = "read" ]; then
27235                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27236         fi
27237
27238         local start_time=$(date +%s.%N)
27239         $dd_cmd bs=1M count=$blocks oflag=sync ||
27240                 error "real dd $read_write error"
27241         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27242
27243         if [ "$read_write" = "write" ]; then
27244                 rm -f $DIR/$tfile
27245         fi
27246
27247         # define OBD_FAIL_OST_FAKE_RW           0x238
27248         do_facet ost1 $LCTL set_param fail_loc=0x238
27249
27250         local start_time=$(date +%s.%N)
27251         $dd_cmd bs=1M count=$blocks oflag=sync ||
27252                 error "fake dd $read_write error"
27253         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27254
27255         if [ "$read_write" = "write" ]; then
27256                 # verify file size
27257                 cancel_lru_locks osc
27258                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27259                         error "$tfile size not $blocks MB"
27260         fi
27261         do_facet ost1 $LCTL set_param fail_loc=0
27262
27263         echo "fake $read_write $duration_fake vs. normal $read_write" \
27264                 "$duration in seconds"
27265         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27266                 error_not_in_vm "fake write is slower"
27267
27268         $LCTL set_param -n debug="$saved_debug"
27269         rm -f $DIR/$tfile
27270 }
27271 test_399a() { # LU-7655 for OST fake write
27272         remote_ost_nodsh && skip "remote OST with nodsh"
27273
27274         test_fake_rw write
27275 }
27276 run_test 399a "fake write should not be slower than normal write"
27277
27278 test_399b() { # LU-8726 for OST fake read
27279         remote_ost_nodsh && skip "remote OST with nodsh"
27280         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27281                 skip_env "ldiskfs only test"
27282         fi
27283
27284         test_fake_rw read
27285 }
27286 run_test 399b "fake read should not be slower than normal read"
27287
27288 test_400a() { # LU-1606, was conf-sanity test_74
27289         if ! which $CC > /dev/null 2>&1; then
27290                 skip_env "$CC is not installed"
27291         fi
27292
27293         local extra_flags=''
27294         local out=$TMP/$tfile
27295         local prefix=/usr/include/lustre
27296         local prog
27297
27298         # Oleg removes .c files in his test rig so test if any c files exist
27299         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27300                 skip_env "Needed .c test files are missing"
27301
27302         if ! [[ -d $prefix ]]; then
27303                 # Assume we're running in tree and fixup the include path.
27304                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27305                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27306                 extra_flags+=" -L$LUSTRE/utils/.libs"
27307         fi
27308
27309         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27310                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27311                         error "client api broken"
27312         done
27313         rm -f $out
27314 }
27315 run_test 400a "Lustre client api program can compile and link"
27316
27317 test_400b() { # LU-1606, LU-5011
27318         local header
27319         local out=$TMP/$tfile
27320         local prefix=/usr/include/linux/lustre
27321
27322         # We use a hard coded prefix so that this test will not fail
27323         # when run in tree. There are headers in lustre/include/lustre/
27324         # that are not packaged (like lustre_idl.h) and have more
27325         # complicated include dependencies (like config.h and lnet/types.h).
27326         # Since this test about correct packaging we just skip them when
27327         # they don't exist (see below) rather than try to fixup cppflags.
27328
27329         if ! which $CC > /dev/null 2>&1; then
27330                 skip_env "$CC is not installed"
27331         fi
27332
27333         for header in $prefix/*.h; do
27334                 if ! [[ -f "$header" ]]; then
27335                         continue
27336                 fi
27337
27338                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27339                         continue # lustre_ioctl.h is internal header
27340                 fi
27341
27342                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27343                         error "cannot compile '$header'"
27344         done
27345         rm -f $out
27346 }
27347 run_test 400b "packaged headers can be compiled"
27348
27349 test_401a() { #LU-7437
27350         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27351         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27352
27353         #count the number of parameters by "list_param -R"
27354         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27355         #count the number of parameters by listing proc files
27356         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27357         echo "proc_dirs='$proc_dirs'"
27358         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27359         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27360                       sort -u | wc -l)
27361
27362         [ $params -eq $procs ] ||
27363                 error "found $params parameters vs. $procs proc files"
27364
27365         # test the list_param -D option only returns directories
27366         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27367         #count the number of parameters by listing proc directories
27368         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27369                 sort -u | wc -l)
27370
27371         [ $params -eq $procs ] ||
27372                 error "found $params parameters vs. $procs proc files"
27373 }
27374 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27375
27376 test_401b() {
27377         # jobid_var may not allow arbitrary values, so use jobid_name
27378         # if available
27379         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27380                 local testname=jobid_name tmp='testing%p'
27381         else
27382                 local testname=jobid_var tmp=testing
27383         fi
27384
27385         local save=$($LCTL get_param -n $testname)
27386
27387         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27388                 error "no error returned when setting bad parameters"
27389
27390         local jobid_new=$($LCTL get_param -n foe $testname baz)
27391         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27392
27393         $LCTL set_param -n fog=bam $testname=$save bat=fog
27394         local jobid_old=$($LCTL get_param -n foe $testname bag)
27395         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27396 }
27397 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27398
27399 test_401c() {
27400         # jobid_var may not allow arbitrary values, so use jobid_name
27401         # if available
27402         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27403                 local testname=jobid_name
27404         else
27405                 local testname=jobid_var
27406         fi
27407
27408         local jobid_var_old=$($LCTL get_param -n $testname)
27409         local jobid_var_new
27410
27411         $LCTL set_param $testname= &&
27412                 error "no error returned for 'set_param a='"
27413
27414         jobid_var_new=$($LCTL get_param -n $testname)
27415         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27416                 error "$testname was changed by setting without value"
27417
27418         $LCTL set_param $testname &&
27419                 error "no error returned for 'set_param a'"
27420
27421         jobid_var_new=$($LCTL get_param -n $testname)
27422         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27423                 error "$testname was changed by setting without value"
27424 }
27425 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27426
27427 test_401d() {
27428         # jobid_var may not allow arbitrary values, so use jobid_name
27429         # if available
27430         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27431                 local testname=jobid_name new_value='foo=bar%p'
27432         else
27433                 local testname=jobid_var new_valuie=foo=bar
27434         fi
27435
27436         local jobid_var_old=$($LCTL get_param -n $testname)
27437         local jobid_var_new
27438
27439         $LCTL set_param $testname=$new_value ||
27440                 error "'set_param a=b' did not accept a value containing '='"
27441
27442         jobid_var_new=$($LCTL get_param -n $testname)
27443         [[ "$jobid_var_new" == "$new_value" ]] ||
27444                 error "'set_param a=b' failed on a value containing '='"
27445
27446         # Reset the $testname to test the other format
27447         $LCTL set_param $testname=$jobid_var_old
27448         jobid_var_new=$($LCTL get_param -n $testname)
27449         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27450                 error "failed to reset $testname"
27451
27452         $LCTL set_param $testname $new_value ||
27453                 error "'set_param a b' did not accept a value containing '='"
27454
27455         jobid_var_new=$($LCTL get_param -n $testname)
27456         [[ "$jobid_var_new" == "$new_value" ]] ||
27457                 error "'set_param a b' failed on a value containing '='"
27458
27459         $LCTL set_param $testname $jobid_var_old
27460         jobid_var_new=$($LCTL get_param -n $testname)
27461         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27462                 error "failed to reset $testname"
27463 }
27464 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27465
27466 test_401e() { # LU-14779
27467         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27468                 error "lctl list_param MGC* failed"
27469         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27470         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27471                 error "lctl get_param lru_size failed"
27472 }
27473 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27474
27475 test_402() {
27476         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27477         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27478                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27479         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27480                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27481                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27482         remote_mds_nodsh && skip "remote MDS with nodsh"
27483
27484         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27485 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27486         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27487         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27488                 echo "Touch failed - OK"
27489 }
27490 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27491
27492 test_403() {
27493         local file1=$DIR/$tfile.1
27494         local file2=$DIR/$tfile.2
27495         local tfile=$TMP/$tfile
27496
27497         rm -f $file1 $file2 $tfile
27498
27499         touch $file1
27500         ln $file1 $file2
27501
27502         # 30 sec OBD_TIMEOUT in ll_getattr()
27503         # right before populating st_nlink
27504         $LCTL set_param fail_loc=0x80001409
27505         stat -c %h $file1 > $tfile &
27506
27507         # create an alias, drop all locks and reclaim the dentry
27508         < $file2
27509         cancel_lru_locks mdc
27510         cancel_lru_locks osc
27511         sysctl -w vm.drop_caches=2
27512
27513         wait
27514
27515         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27516
27517         rm -f $tfile $file1 $file2
27518 }
27519 run_test 403 "i_nlink should not drop to zero due to aliasing"
27520
27521 test_404() { # LU-6601
27522         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27523                 skip "Need server version newer than 2.8.52"
27524         remote_mds_nodsh && skip "remote MDS with nodsh"
27525
27526         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27527                 awk '/osp .*-osc-MDT/ { print $4}')
27528
27529         local osp
27530         for osp in $mosps; do
27531                 echo "Deactivate: " $osp
27532                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27533                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27534                         awk -vp=$osp '$4 == p { print $2 }')
27535                 [ $stat = IN ] || {
27536                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27537                         error "deactivate error"
27538                 }
27539                 echo "Activate: " $osp
27540                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27541                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27542                         awk -vp=$osp '$4 == p { print $2 }')
27543                 [ $stat = UP ] || {
27544                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27545                         error "activate error"
27546                 }
27547         done
27548 }
27549 run_test 404 "validate manual {de}activated works properly for OSPs"
27550
27551 test_405() {
27552         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27553         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27554                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27555                         skip "Layout swap lock is not supported"
27556
27557         check_swap_layouts_support
27558         check_swap_layout_no_dom $DIR
27559
27560         test_mkdir $DIR/$tdir
27561         swap_lock_test -d $DIR/$tdir ||
27562                 error "One layout swap locked test failed"
27563 }
27564 run_test 405 "Various layout swap lock tests"
27565
27566 test_406() {
27567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27568         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27569         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27571         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27572                 skip "Need MDS version at least 2.8.50"
27573
27574         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27575         local test_pool=$TESTNAME
27576
27577         pool_add $test_pool || error "pool_add failed"
27578         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27579                 error "pool_add_targets failed"
27580
27581         save_layout_restore_at_exit $MOUNT
27582
27583         # parent set default stripe count only, child will stripe from both
27584         # parent and fs default
27585         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27586                 error "setstripe $MOUNT failed"
27587         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27588         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27589         for i in $(seq 10); do
27590                 local f=$DIR/$tdir/$tfile.$i
27591                 touch $f || error "touch failed"
27592                 local count=$($LFS getstripe -c $f)
27593                 [ $count -eq $OSTCOUNT ] ||
27594                         error "$f stripe count $count != $OSTCOUNT"
27595                 local offset=$($LFS getstripe -i $f)
27596                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27597                 local size=$($LFS getstripe -S $f)
27598                 [ $size -eq $((def_stripe_size * 2)) ] ||
27599                         error "$f stripe size $size != $((def_stripe_size * 2))"
27600                 local pool=$($LFS getstripe -p $f)
27601                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27602         done
27603
27604         # change fs default striping, delete parent default striping, now child
27605         # will stripe from new fs default striping only
27606         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27607                 error "change $MOUNT default stripe failed"
27608         $LFS setstripe -c 0 $DIR/$tdir ||
27609                 error "delete $tdir default stripe failed"
27610         for i in $(seq 11 20); do
27611                 local f=$DIR/$tdir/$tfile.$i
27612                 touch $f || error "touch $f failed"
27613                 local count=$($LFS getstripe -c $f)
27614                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27615                 local offset=$($LFS getstripe -i $f)
27616                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27617                 local size=$($LFS getstripe -S $f)
27618                 [ $size -eq $def_stripe_size ] ||
27619                         error "$f stripe size $size != $def_stripe_size"
27620                 local pool=$($LFS getstripe -p $f)
27621                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27622         done
27623
27624         unlinkmany $DIR/$tdir/$tfile. 1 20
27625
27626         local f=$DIR/$tdir/$tfile
27627         pool_remove_all_targets $test_pool $f
27628         pool_remove $test_pool $f
27629 }
27630 run_test 406 "DNE support fs default striping"
27631
27632 test_407() {
27633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27634         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27635                 skip "Need MDS version at least 2.8.55"
27636         remote_mds_nodsh && skip "remote MDS with nodsh"
27637
27638         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27639                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27640         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27641                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27642         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27643
27644         #define OBD_FAIL_DT_TXN_STOP    0x2019
27645         for idx in $(seq $MDSCOUNT); do
27646                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27647         done
27648         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27649         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27650                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27651         true
27652 }
27653 run_test 407 "transaction fail should cause operation fail"
27654
27655 test_408() {
27656         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27657
27658         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27659         lctl set_param fail_loc=0x8000040a
27660         # let ll_prepare_partial_page() fail
27661         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27662
27663         rm -f $DIR/$tfile
27664
27665         # create at least 100 unused inodes so that
27666         # shrink_icache_memory(0) should not return 0
27667         touch $DIR/$tfile-{0..100}
27668         rm -f $DIR/$tfile-{0..100}
27669         sync
27670
27671         echo 2 > /proc/sys/vm/drop_caches
27672 }
27673 run_test 408 "drop_caches should not hang due to page leaks"
27674
27675 test_409()
27676 {
27677         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27678
27679         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27680         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27681         touch $DIR/$tdir/guard || error "(2) Fail to create"
27682
27683         local PREFIX=$(str_repeat 'A' 128)
27684         echo "Create 1K hard links start at $(date)"
27685         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27686                 error "(3) Fail to hard link"
27687
27688         echo "Links count should be right although linkEA overflow"
27689         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27690         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27691         [ $linkcount -eq 1001 ] ||
27692                 error "(5) Unexpected hard links count: $linkcount"
27693
27694         echo "List all links start at $(date)"
27695         ls -l $DIR/$tdir/foo > /dev/null ||
27696                 error "(6) Fail to list $DIR/$tdir/foo"
27697
27698         echo "Unlink hard links start at $(date)"
27699         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27700                 error "(7) Fail to unlink"
27701         echo "Unlink hard links finished at $(date)"
27702 }
27703 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27704
27705 test_410()
27706 {
27707         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27708                 skip "Need client version at least 2.9.59"
27709         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27710                 skip "Need MODULES build"
27711
27712         # Create a file, and stat it from the kernel
27713         local testfile=$DIR/$tfile
27714         touch $testfile
27715
27716         local run_id=$RANDOM
27717         local my_ino=$(stat --format "%i" $testfile)
27718
27719         # Try to insert the module. This will always fail as the
27720         # module is designed to not be inserted.
27721         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27722             &> /dev/null
27723
27724         # Anything but success is a test failure
27725         dmesg | grep -q \
27726             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27727             error "no inode match"
27728 }
27729 run_test 410 "Test inode number returned from kernel thread"
27730
27731 cleanup_test411_cgroup() {
27732         trap 0
27733         cat $1/memory.stat
27734         rmdir "$1"
27735 }
27736
27737 test_411a() {
27738         local cg_basedir=/sys/fs/cgroup/memory
27739         # LU-9966
27740         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27741                 skip "no setup for cgroup"
27742
27743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27744                 error "test file creation failed"
27745         cancel_lru_locks osc
27746
27747         # Create a very small memory cgroup to force a slab allocation error
27748         local cgdir=$cg_basedir/osc_slab_alloc
27749         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27750         trap "cleanup_test411_cgroup $cgdir" EXIT
27751         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27752         echo 1M > $cgdir/memory.limit_in_bytes
27753
27754         # Should not LBUG, just be killed by oom-killer
27755         # dd will return 0 even allocation failure in some environment.
27756         # So don't check return value
27757         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27758         cleanup_test411_cgroup $cgdir
27759
27760         return 0
27761 }
27762 run_test 411a "Slab allocation error with cgroup does not LBUG"
27763
27764 test_411b() {
27765         local cg_basedir=/sys/fs/cgroup/memory
27766         # LU-9966
27767         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27768                 skip "no setup for cgroup"
27769         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27770         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27771         # limit, so we have 384M in cgroup
27772         # (arm) this seems to hit OOM more often than x86, so 1024M
27773         if [[ $(uname -m) = aarch64 ]]; then
27774                 local memlimit_mb=1024
27775         else
27776                 local memlimit_mb=384
27777         fi
27778
27779         # Create a cgroup and set memory limit
27780         # (tfile is used as an easy way to get a recognizable cgroup name)
27781         local cgdir=$cg_basedir/$tfile
27782         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27783         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27784         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27785
27786         echo "writing first file"
27787         # Write a file 4x the memory limit in size
27788         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27789                 error "(1) failed to write successfully"
27790
27791         sync
27792         cancel_lru_locks osc
27793
27794         rm -f $DIR/$tfile
27795         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27796
27797         # Try writing at a larger block size
27798         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27799         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27800         # need *some* memory to do IO in)
27801         echo "writing at larger block size"
27802         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27803                 error "(3) failed to write successfully"
27804
27805         sync
27806         cancel_lru_locks osc
27807         rm -f $DIR/$tfile
27808         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27809
27810         # Try writing multiple files at once
27811         echo "writing multiple files"
27812         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27813         local pid1=$!
27814         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27815         local pid2=$!
27816         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27817         local pid3=$!
27818         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27819         local pid4=$!
27820
27821         wait $pid1
27822         local rc1=$?
27823         wait $pid2
27824         local rc2=$?
27825         wait $pid3
27826         local rc3=$?
27827         wait $pid4
27828         local rc4=$?
27829         if (( rc1 != 0)); then
27830                 error "error $rc1 writing to file from $pid1"
27831         fi
27832         if (( rc2 != 0)); then
27833                 error "error $rc2 writing to file from $pid2"
27834         fi
27835         if (( rc3 != 0)); then
27836                 error "error $rc3 writing to file from $pid3"
27837         fi
27838         if (( rc4 != 0)); then
27839                 error "error $rc4 writing to file from $pid4"
27840         fi
27841
27842         sync
27843         cancel_lru_locks osc
27844
27845         # These files can be large-ish (~1 GiB total), so delete them rather
27846         # than leave for later cleanup
27847         rm -f $DIR/$tfile.*
27848         return 0
27849 }
27850 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27851
27852 test_412() {
27853         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27854         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27855                 skip "Need server version at least 2.10.55"
27856
27857         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27858                 error "mkdir failed"
27859         $LFS getdirstripe $DIR/$tdir
27860         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27861         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27862                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27863         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27864         [ $stripe_count -eq 2 ] ||
27865                 error "expect 2 get $stripe_count"
27866
27867         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27868
27869         local index
27870         local index2
27871
27872         # subdirs should be on the same MDT as parent
27873         for i in $(seq 0 $((MDSCOUNT - 1))); do
27874                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27875                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27876                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27877                 (( index == i )) || error "mdt$i/sub on MDT$index"
27878         done
27879
27880         # stripe offset -1, ditto
27881         for i in {1..10}; do
27882                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27883                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27884                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27885                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27886                 (( index == index2 )) ||
27887                         error "qos$i on MDT$index, sub on MDT$index2"
27888         done
27889
27890         local testdir=$DIR/$tdir/inherit
27891
27892         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27893         # inherit 2 levels
27894         for i in 1 2; do
27895                 testdir=$testdir/s$i
27896                 mkdir $testdir || error "mkdir $testdir failed"
27897                 index=$($LFS getstripe -m $testdir)
27898                 (( index == 1 )) ||
27899                         error "$testdir on MDT$index"
27900         done
27901
27902         # not inherit any more
27903         testdir=$testdir/s3
27904         mkdir $testdir || error "mkdir $testdir failed"
27905         getfattr -d -m dmv $testdir | grep dmv &&
27906                 error "default LMV set on $testdir" || true
27907 }
27908 run_test 412 "mkdir on specific MDTs"
27909
27910 TEST413_COUNT=${TEST413_COUNT:-200}
27911
27912 #
27913 # set_maxage() is used by test_413 only.
27914 # This is a helper function to set maxage. Does not return any value.
27915 # Input: maxage to set
27916 #
27917 set_maxage() {
27918         local lmv_qos_maxage
27919         local lod_qos_maxage
27920         local new_maxage=$1
27921
27922         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27923         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27924         stack_trap "$LCTL set_param \
27925                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27926         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27927                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27928         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27929                 lod.*.mdt_qos_maxage=$new_maxage
27930         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27931                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27932 }
27933
27934 generate_uneven_mdts() {
27935         local threshold=$1
27936         local ffree
27937         local bavail
27938         local max
27939         local min
27940         local max_index
27941         local min_index
27942         local tmp
27943         local i
27944
27945         echo
27946         echo "Check for uneven MDTs: "
27947
27948         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27949         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27950         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27951
27952         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27953         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27954         max_index=0
27955         min_index=0
27956         for ((i = 1; i < ${#ffree[@]}; i++)); do
27957                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27958                 if [ $tmp -gt $max ]; then
27959                         max=$tmp
27960                         max_index=$i
27961                 fi
27962                 if [ $tmp -lt $min ]; then
27963                         min=$tmp
27964                         min_index=$i
27965                 fi
27966         done
27967
27968         (( min > 0 )) || skip "low space on MDT$min_index"
27969         (( ${ffree[min_index]} > 0 )) ||
27970                 skip "no free files on MDT$min_index"
27971         (( ${ffree[min_index]} < 10000000 )) ||
27972                 skip "too many free files on MDT$min_index"
27973
27974         # Check if we need to generate uneven MDTs
27975         local diff=$(((max - min) * 100 / min))
27976         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27977         local testdir # individual folder within $testdirp
27978         local start
27979         local cmd
27980
27981         # fallocate is faster to consume space on MDT, if available
27982         if check_fallocate_supported mds$((min_index + 1)); then
27983                 cmd="fallocate -l 128K "
27984         else
27985                 cmd="dd if=/dev/zero bs=128K count=1 of="
27986         fi
27987
27988         echo "using cmd $cmd"
27989         for (( i = 0; diff < threshold; i++ )); do
27990                 testdir=${testdirp}/$i
27991                 [ -d $testdir ] && continue
27992
27993                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27994
27995                 mkdir -p $testdirp
27996                 # generate uneven MDTs, create till $threshold% diff
27997                 echo -n "weight diff=$diff% must be > $threshold% ..."
27998                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27999                 $LFS mkdir -i $min_index $testdir ||
28000                         error "mkdir $testdir failed"
28001                 $LFS setstripe -E 1M -L mdt $testdir ||
28002                         error "setstripe $testdir failed"
28003                 start=$SECONDS
28004                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28005                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28006                 done
28007                 sync; sleep 1; sync
28008
28009                 # wait for QOS to update
28010                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28011
28012                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28013                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28014                 max=$(((${ffree[max_index]} >> 8) *
28015                         (${bavail[max_index]} * bsize >> 16)))
28016                 min=$(((${ffree[min_index]} >> 8) *
28017                         (${bavail[min_index]} * bsize >> 16)))
28018                 (( min > 0 )) || skip "low space on MDT$min_index"
28019                 diff=$(((max - min) * 100 / min))
28020         done
28021
28022         echo "MDT filesfree available: ${ffree[*]}"
28023         echo "MDT blocks available: ${bavail[*]}"
28024         echo "weight diff=$diff%"
28025 }
28026
28027 test_qos_mkdir() {
28028         local mkdir_cmd=$1
28029         local stripe_count=$2
28030         local mdts=$(comma_list $(mdts_nodes))
28031
28032         local testdir
28033         local lmv_qos_prio_free
28034         local lmv_qos_threshold_rr
28035         local lod_qos_prio_free
28036         local lod_qos_threshold_rr
28037         local total
28038         local count
28039         local i
28040
28041         # @total is total directories created if it's testing plain
28042         # directories, otherwise it's total stripe object count for
28043         # striped directories test.
28044         # remote/striped directory unlinking is slow on zfs and may
28045         # timeout, test with fewer directories
28046         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28047
28048         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28049         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28050         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28051                 head -n1)
28052         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28053         stack_trap "$LCTL set_param \
28054                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28055         stack_trap "$LCTL set_param \
28056                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28057
28058         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28059                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28060         lod_qos_prio_free=${lod_qos_prio_free%%%}
28061         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28062                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28063         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28064         stack_trap "do_nodes $mdts $LCTL set_param \
28065                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28066         stack_trap "do_nodes $mdts $LCTL set_param \
28067                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28068
28069         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28070         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28071
28072         testdir=$DIR/$tdir-s$stripe_count/rr
28073
28074         local stripe_index=$($LFS getstripe -m $testdir)
28075         local test_mkdir_rr=true
28076
28077         getfattr -d -m dmv -e hex $testdir | grep dmv
28078         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28079                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28080                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28081                         test_mkdir_rr=false
28082         fi
28083
28084         echo
28085         $test_mkdir_rr &&
28086                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28087                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28088
28089         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28090         for (( i = 0; i < total / stripe_count; i++ )); do
28091                 eval $mkdir_cmd $testdir/subdir$i ||
28092                         error "$mkdir_cmd subdir$i failed"
28093         done
28094
28095         for (( i = 0; i < $MDSCOUNT; i++ )); do
28096                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28097                 echo "$count directories created on MDT$i"
28098                 if $test_mkdir_rr; then
28099                         (( count == total / stripe_count / MDSCOUNT )) ||
28100                                 error "subdirs are not evenly distributed"
28101                 elif (( i == stripe_index )); then
28102                         (( count == total / stripe_count )) ||
28103                                 error "$count subdirs created on MDT$i"
28104                 else
28105                         (( count == 0 )) ||
28106                                 error "$count subdirs created on MDT$i"
28107                 fi
28108
28109                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28110                         count=$($LFS getdirstripe $testdir/* |
28111                                 grep -c -P "^\s+$i\t")
28112                         echo "$count stripes created on MDT$i"
28113                         # deviation should < 5% of average
28114                         delta=$((count - total / MDSCOUNT))
28115                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28116                                 error "stripes are not evenly distributed"
28117                 fi
28118         done
28119
28120         echo
28121         echo "Check for uneven MDTs: "
28122
28123         local ffree
28124         local bavail
28125         local max
28126         local min
28127         local max_index
28128         local min_index
28129         local tmp
28130
28131         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28132         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28133         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28134
28135         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28136         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28137         max_index=0
28138         min_index=0
28139         for ((i = 1; i < ${#ffree[@]}; i++)); do
28140                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28141                 if [ $tmp -gt $max ]; then
28142                         max=$tmp
28143                         max_index=$i
28144                 fi
28145                 if [ $tmp -lt $min ]; then
28146                         min=$tmp
28147                         min_index=$i
28148                 fi
28149         done
28150         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28151
28152         (( min > 0 )) || skip "low space on MDT$min_index"
28153         (( ${ffree[min_index]} < 10000000 )) ||
28154                 skip "too many free files on MDT$min_index"
28155
28156         generate_uneven_mdts 120
28157
28158         echo "MDT filesfree available: ${ffree[*]}"
28159         echo "MDT blocks available: ${bavail[*]}"
28160         echo "weight diff=$(((max - min) * 100 / min))%"
28161         echo
28162         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28163
28164         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28165         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28166         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28167         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28168         # decrease statfs age, so that it can be updated in time
28169         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28170         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28171
28172         sleep 1
28173
28174         testdir=$DIR/$tdir-s$stripe_count/qos
28175
28176         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28177         for (( i = 0; i < total / stripe_count; i++ )); do
28178                 eval $mkdir_cmd $testdir/subdir$i ||
28179                         error "$mkdir_cmd subdir$i failed"
28180         done
28181
28182         max=0
28183         for (( i = 0; i < $MDSCOUNT; i++ )); do
28184                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28185                 (( count > max )) && max=$count
28186                 echo "$count directories created on MDT$i : curmax=$max"
28187         done
28188
28189         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28190
28191         # D-value should > 10% of average
28192         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28193                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28194
28195         # ditto for stripes
28196         if (( stripe_count > 1 )); then
28197                 max=0
28198                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28199                         count=$($LFS getdirstripe $testdir/* |
28200                                 grep -c -P "^\s+$i\t")
28201                         (( count > max )) && max=$count
28202                         echo "$count stripes created on MDT$i"
28203                 done
28204
28205                 min=$($LFS getdirstripe $testdir/* |
28206                         grep -c -P "^\s+$min_index\t")
28207                 (( max - min > total / MDSCOUNT / 10 )) ||
28208                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28209         fi
28210 }
28211
28212 most_full_mdt() {
28213         local ffree
28214         local bavail
28215         local bsize
28216         local min
28217         local min_index
28218         local tmp
28219
28220         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28221         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28222         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28223
28224         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28225         min_index=0
28226         for ((i = 1; i < ${#ffree[@]}; i++)); do
28227                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28228                 (( tmp < min )) && min=$tmp && min_index=$i
28229         done
28230
28231         echo -n $min_index
28232 }
28233
28234 test_413a() {
28235         [ $MDSCOUNT -lt 2 ] &&
28236                 skip "We need at least 2 MDTs for this test"
28237
28238         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28239                 skip "Need server version at least 2.12.52"
28240
28241         local stripe_max=$((MDSCOUNT - 1))
28242         local stripe_count
28243
28244         # let caller set maxage for latest result
28245         set_maxage 1
28246
28247         # fill MDT unevenly
28248         generate_uneven_mdts 120
28249
28250         # test 4-stripe directory at most, otherwise it's too slow
28251         # We are being very defensive. Although Autotest uses 4 MDTs.
28252         # We make sure stripe_max does not go over 4.
28253         (( stripe_max > 4 )) && stripe_max=4
28254         # unlinking striped directory is slow on zfs, and may timeout, only test
28255         # plain directory
28256         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28257         for stripe_count in $(seq 1 $stripe_max); do
28258                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28259                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28260                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28261                         error "mkdir failed"
28262                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28263         done
28264 }
28265 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28266
28267 test_413b() {
28268         [ $MDSCOUNT -lt 2 ] &&
28269                 skip "We need at least 2 MDTs for this test"
28270
28271         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28272                 skip "Need server version at least 2.12.52"
28273
28274         local stripe_max=$((MDSCOUNT - 1))
28275         local testdir
28276         local stripe_count
28277
28278         # let caller set maxage for latest result
28279         set_maxage 1
28280
28281         # fill MDT unevenly
28282         generate_uneven_mdts 120
28283
28284         # test 4-stripe directory at most, otherwise it's too slow
28285         # We are being very defensive. Although Autotest uses 4 MDTs.
28286         # We make sure stripe_max does not go over 4.
28287         (( stripe_max > 4 )) && stripe_max=4
28288         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28289         for stripe_count in $(seq 1 $stripe_max); do
28290                 testdir=$DIR/$tdir-s$stripe_count
28291                 mkdir $testdir || error "mkdir $testdir failed"
28292                 mkdir $testdir/rr || error "mkdir rr failed"
28293                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28294                         error "mkdir qos failed"
28295                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28296                         $testdir/rr || error "setdirstripe rr failed"
28297                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28298                         error "setdirstripe failed"
28299                 test_qos_mkdir "mkdir" $stripe_count
28300         done
28301 }
28302 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28303
28304 test_413c() {
28305         (( $MDSCOUNT >= 2 )) ||
28306                 skip "We need at least 2 MDTs for this test"
28307
28308         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28309                 skip "Need server version at least 2.14.51"
28310
28311         local testdir
28312         local inherit
28313         local inherit_rr
28314         local lmv_qos_maxage
28315         local lod_qos_maxage
28316
28317         # let caller set maxage for latest result
28318         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28319         $LCTL set_param lmv.*.qos_maxage=1
28320         stack_trap "$LCTL set_param \
28321                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28322         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28323                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28324         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28325                 lod.*.mdt_qos_maxage=1
28326         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28327                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28328
28329         # fill MDT unevenly
28330         generate_uneven_mdts 120
28331
28332         testdir=$DIR/${tdir}-s1
28333         mkdir $testdir || error "mkdir $testdir failed"
28334         mkdir $testdir/rr || error "mkdir rr failed"
28335         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28336         # default max_inherit is -1, default max_inherit_rr is 0
28337         $LFS setdirstripe -D -c 1 $testdir/rr ||
28338                 error "setdirstripe rr failed"
28339         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28340                 error "setdirstripe qos failed"
28341         test_qos_mkdir "mkdir" 1
28342
28343         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28344         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28345         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28346         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28347         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28348
28349         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28350         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28351         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28352         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28353         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28354         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28355         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28356                 error "level2 shouldn't have default LMV" || true
28357 }
28358 run_test 413c "mkdir with default LMV max inherit rr"
28359
28360 test_413d() {
28361         (( MDSCOUNT >= 2 )) ||
28362                 skip "We need at least 2 MDTs for this test"
28363
28364         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28365                 skip "Need server version at least 2.14.51"
28366
28367         local lmv_qos_threshold_rr
28368
28369         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28370                 head -n1)
28371         stack_trap "$LCTL set_param \
28372                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28373
28374         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28375         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28376         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28377                 error "$tdir shouldn't have default LMV"
28378         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28379                 error "mkdir sub failed"
28380
28381         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28382
28383         (( count == 100 )) || error "$count subdirs on MDT0"
28384 }
28385 run_test 413d "inherit ROOT default LMV"
28386
28387 test_413e() {
28388         (( MDSCOUNT >= 2 )) ||
28389                 skip "We need at least 2 MDTs for this test"
28390         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28391                 skip "Need server version at least 2.14.55"
28392
28393         local testdir=$DIR/$tdir
28394         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28395         local max_inherit
28396         local sub_max_inherit
28397
28398         mkdir -p $testdir || error "failed to create $testdir"
28399
28400         # set default max-inherit to -1 if stripe count is 0 or 1
28401         $LFS setdirstripe -D -c 1 $testdir ||
28402                 error "failed to set default LMV"
28403         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28404         (( max_inherit == -1 )) ||
28405                 error "wrong max_inherit value $max_inherit"
28406
28407         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28408         $LFS setdirstripe -D -c -1 $testdir ||
28409                 error "failed to set default LMV"
28410         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28411         (( max_inherit > 0 )) ||
28412                 error "wrong max_inherit value $max_inherit"
28413
28414         # and the subdir will decrease the max_inherit by 1
28415         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28416         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28417         (( sub_max_inherit == max_inherit - 1)) ||
28418                 error "wrong max-inherit of subdir $sub_max_inherit"
28419
28420         # check specified --max-inherit and warning message
28421         stack_trap "rm -f $tmpfile"
28422         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28423                 error "failed to set default LMV"
28424         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28425         (( max_inherit == -1 )) ||
28426                 error "wrong max_inherit value $max_inherit"
28427
28428         # check the warning messages
28429         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28430                 error "failed to detect warning string"
28431         fi
28432 }
28433 run_test 413e "check default max-inherit value"
28434
28435 test_fs_dmv_inherit()
28436 {
28437         local testdir=$DIR/$tdir
28438
28439         local count
28440         local inherit
28441         local inherit_rr
28442
28443         for i in 1 2; do
28444                 mkdir $testdir || error "mkdir $testdir failed"
28445                 count=$($LFS getdirstripe -D -c $testdir)
28446                 (( count == 1 )) ||
28447                         error "$testdir default LMV count mismatch $count != 1"
28448                 inherit=$($LFS getdirstripe -D -X $testdir)
28449                 (( inherit == 3 - i )) ||
28450                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28451                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28452                 (( inherit_rr == 3 - i )) ||
28453                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28454                 testdir=$testdir/sub
28455         done
28456
28457         mkdir $testdir || error "mkdir $testdir failed"
28458         count=$($LFS getdirstripe -D -c $testdir)
28459         (( count == 0 )) ||
28460                 error "$testdir default LMV count not zero: $count"
28461 }
28462
28463 test_413f() {
28464         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28465
28466         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28467                 skip "Need server version at least 2.14.55"
28468
28469         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28470                 error "dump $DIR default LMV failed"
28471         stack_trap "setfattr --restore=$TMP/dmv.ea"
28472
28473         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28474                 error "set $DIR default LMV failed"
28475
28476         test_fs_dmv_inherit
28477 }
28478 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28479
28480 test_413g() {
28481         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28482
28483         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28484         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28485                 error "dump $DIR default LMV failed"
28486         stack_trap "setfattr --restore=$TMP/dmv.ea"
28487
28488         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28489                 error "set $DIR default LMV failed"
28490
28491         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28492                 error "mount $MOUNT2 failed"
28493         stack_trap "umount_client $MOUNT2"
28494
28495         local saved_DIR=$DIR
28496
28497         export DIR=$MOUNT2
28498
28499         stack_trap "export DIR=$saved_DIR"
28500
28501         # first check filesystem-wide default LMV inheritance
28502         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28503
28504         # then check subdirs are spread to all MDTs
28505         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28506
28507         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28508
28509         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28510 }
28511 run_test 413g "enforce ROOT default LMV on subdir mount"
28512
28513 test_413h() {
28514         (( MDSCOUNT >= 2 )) ||
28515                 skip "We need at least 2 MDTs for this test"
28516
28517         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28518                 skip "Need server version at least 2.15.50.6"
28519
28520         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28521
28522         stack_trap "$LCTL set_param \
28523                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28524         $LCTL set_param lmv.*.qos_maxage=1
28525
28526         local depth=5
28527         local rr_depth=4
28528         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28529         local count=$((MDSCOUNT * 20))
28530
28531         generate_uneven_mdts 50
28532
28533         mkdir -p $dir || error "mkdir $dir failed"
28534         stack_trap "rm -rf $dir"
28535         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28536                 --max-inherit-rr=$rr_depth $dir
28537
28538         for ((d=0; d < depth + 2; d++)); do
28539                 log "dir=$dir:"
28540                 for ((sub=0; sub < count; sub++)); do
28541                         mkdir $dir/d$sub
28542                 done
28543                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28544                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28545                 # subdirs within $rr_depth should be created round-robin
28546                 if (( d < rr_depth )); then
28547                         (( ${num[0]} != count )) ||
28548                                 error "all objects created on MDT ${num[1]}"
28549                 fi
28550
28551                 dir=$dir/d0
28552         done
28553 }
28554 run_test 413h "don't stick to parent for round-robin dirs"
28555
28556 test_413i() {
28557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28558
28559         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28560                 skip "Need server version at least 2.14.55"
28561
28562         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28563                 error "dump $DIR default LMV failed"
28564         stack_trap "setfattr --restore=$TMP/dmv.ea"
28565
28566         local testdir=$DIR/$tdir
28567         local def_max_rr=1
28568         local def_max=3
28569         local count
28570
28571         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28572                 --max-inherit-rr=$def_max_rr $DIR ||
28573                 error "set $DIR default LMV failed"
28574
28575         for i in $(seq 2 3); do
28576                 def_max=$((def_max - 1))
28577                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28578
28579                 mkdir $testdir
28580                 # RR is decremented and keeps zeroed once exhausted
28581                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28582                 (( count == def_max_rr )) ||
28583                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28584
28585                 # max-inherit is decremented
28586                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28587                 (( count == def_max )) ||
28588                         error_noexit "$testdir: max-inherit $count != $def_max"
28589
28590                 testdir=$testdir/d$i
28591         done
28592
28593         # d3 is the last inherited from ROOT, no inheritance anymore
28594         # i.e. no the default layout anymore
28595         mkdir -p $testdir/d4/d5
28596         count=$($LFS getdirstripe -D --max-inherit $testdir)
28597         (( count == -1 )) ||
28598                 error_noexit "$testdir: max-inherit $count != -1"
28599
28600         local p_count=$($LFS getdirstripe -i $testdir)
28601
28602         for i in $(seq 4 5); do
28603                 testdir=$testdir/d$i
28604
28605                 # the root default layout is not applied once exhausted
28606                 count=$($LFS getdirstripe -i $testdir)
28607                 (( count == p_count )) ||
28608                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28609         done
28610
28611         $LFS setdirstripe -i 0 $DIR/d2
28612         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28613         (( count == -1 )) ||
28614                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28615 }
28616 run_test 413i "check default layout inheritance"
28617
28618 test_413j()
28619 {
28620         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28621
28622         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28623         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28624                 error "setdirstripe $tdir failed"
28625
28626         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28627                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28628
28629         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28630         # setfattr dmv calls setdirstripe -D
28631         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28632                 error "setfattr sub failed"
28633         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28634                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28635
28636         [ $value == $value2 ] || error "dmv mismatch"
28637
28638         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28639
28640         # do not allow remove dmv by setfattr -x
28641         do_nodes $(comma_list $(mdts_nodes)) \
28642                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28643         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28644         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28645
28646         # allow remove dmv by setfattr -x
28647         do_nodes $(comma_list $(mdts_nodes)) \
28648                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28649         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28650         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28651         do_nodes $(comma_list $(mdts_nodes)) \
28652                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28653 }
28654 run_test 413j "set default LMV by setxattr"
28655
28656 test_413z() {
28657         local pids=""
28658         local subdir
28659         local pid
28660
28661         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28662                 unlinkmany $subdir/f. $TEST413_COUNT &
28663                 pids="$pids $!"
28664         done
28665
28666         for pid in $pids; do
28667                 wait $pid
28668         done
28669
28670         true
28671 }
28672 run_test 413z "413 test cleanup"
28673
28674 test_414() {
28675 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28676         $LCTL set_param fail_loc=0x80000521
28677         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28678         rm -f $DIR/$tfile
28679 }
28680 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28681
28682 test_415() {
28683         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28684         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28685                 skip "Need server version at least 2.11.52"
28686
28687         # LU-11102
28688         local total=500
28689         local max=120
28690
28691         # this test may be slow on ZFS
28692         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28693
28694         # though this test is designed for striped directory, let's test normal
28695         # directory too since lock is always saved as CoS lock.
28696         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28697         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28698         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28699         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28700         wait_delete_completed_mds
28701
28702         # run a loop without concurrent touch to measure rename duration.
28703         # only for test debug/robustness, NOT part of COS functional test.
28704         local start_time=$SECONDS
28705         for ((i = 0; i < total; i++)); do
28706                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28707                         > /dev/null
28708         done
28709         local baseline=$((SECONDS - start_time))
28710         echo "rename $total files without 'touch' took $baseline sec"
28711
28712         (
28713                 while true; do
28714                         touch $DIR/$tdir
28715                 done
28716         ) &
28717         local setattr_pid=$!
28718
28719         # rename files back to original name so unlinkmany works
28720         start_time=$SECONDS
28721         for ((i = 0; i < total; i++)); do
28722                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28723                         > /dev/null
28724         done
28725         local duration=$((SECONDS - start_time))
28726
28727         kill -9 $setattr_pid
28728
28729         echo "rename $total files with 'touch' took $duration sec"
28730         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28731         (( duration <= max )) ||
28732                 error_not_in_vm "rename took $duration > $max sec"
28733 }
28734 run_test 415 "lock revoke is not missing"
28735
28736 test_416() {
28737         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28738                 skip "Need server version at least 2.11.55"
28739
28740         # define OBD_FAIL_OSD_TXN_START    0x19a
28741         do_facet mds1 lctl set_param fail_loc=0x19a
28742
28743         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28744
28745         true
28746 }
28747 run_test 416 "transaction start failure won't cause system hung"
28748
28749 cleanup_417() {
28750         trap 0
28751         do_nodes $(comma_list $(mdts_nodes)) \
28752                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28753         do_nodes $(comma_list $(mdts_nodes)) \
28754                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28755         do_nodes $(comma_list $(mdts_nodes)) \
28756                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28757 }
28758
28759 test_417() {
28760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28761         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28762                 skip "Need MDS version at least 2.11.56"
28763
28764         trap cleanup_417 RETURN EXIT
28765
28766         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28767         do_nodes $(comma_list $(mdts_nodes)) \
28768                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28769         $LFS migrate -m 0 $DIR/$tdir.1 &&
28770                 error "migrate dir $tdir.1 should fail"
28771
28772         do_nodes $(comma_list $(mdts_nodes)) \
28773                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28774         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28775                 error "create remote dir $tdir.2 should fail"
28776
28777         do_nodes $(comma_list $(mdts_nodes)) \
28778                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28779         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28780                 error "create striped dir $tdir.3 should fail"
28781         true
28782 }
28783 run_test 417 "disable remote dir, striped dir and dir migration"
28784
28785 # Checks that the outputs of df [-i] and lfs df [-i] match
28786 #
28787 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28788 check_lfs_df() {
28789         local dir=$2
28790         local inodes
28791         local df_out
28792         local lfs_df_out
28793         local count
28794         local passed=false
28795
28796         # blocks or inodes
28797         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28798
28799         for count in {1..100}; do
28800                 do_nodes "$CLIENTS" \
28801                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28802                 sync; sleep 0.2
28803
28804                 # read the lines of interest
28805                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28806                         error "df $inodes $dir | tail -n +2 failed"
28807                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28808                         error "lfs df $inodes $dir | grep summary: failed"
28809
28810                 # skip first substrings of each output as they are different
28811                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28812                 # compare the two outputs
28813                 passed=true
28814                 #  skip "available" on MDT until LU-13997 is fixed.
28815                 #for i in {1..5}; do
28816                 for i in 1 2 4 5; do
28817                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28818                 done
28819                 $passed && break
28820         done
28821
28822         if ! $passed; then
28823                 df -P $inodes $dir
28824                 echo
28825                 lfs df $inodes $dir
28826                 error "df and lfs df $1 output mismatch: "      \
28827                       "df ${inodes}: ${df_out[*]}, "            \
28828                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28829         fi
28830 }
28831
28832 test_418() {
28833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28834
28835         local dir=$DIR/$tdir
28836         local numfiles=$((RANDOM % 4096 + 2))
28837         local numblocks=$((RANDOM % 256 + 1))
28838
28839         wait_delete_completed
28840         test_mkdir $dir
28841
28842         # check block output
28843         check_lfs_df blocks $dir
28844         # check inode output
28845         check_lfs_df inodes $dir
28846
28847         # create a single file and retest
28848         echo "Creating a single file and testing"
28849         createmany -o $dir/$tfile- 1 &>/dev/null ||
28850                 error "creating 1 file in $dir failed"
28851         check_lfs_df blocks $dir
28852         check_lfs_df inodes $dir
28853
28854         # create a random number of files
28855         echo "Creating $((numfiles - 1)) files and testing"
28856         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28857                 error "creating $((numfiles - 1)) files in $dir failed"
28858
28859         # write a random number of blocks to the first test file
28860         echo "Writing $numblocks 4K blocks and testing"
28861         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28862                 count=$numblocks &>/dev/null ||
28863                 error "dd to $dir/${tfile}-0 failed"
28864
28865         # retest
28866         check_lfs_df blocks $dir
28867         check_lfs_df inodes $dir
28868
28869         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28870                 error "unlinking $numfiles files in $dir failed"
28871 }
28872 run_test 418 "df and lfs df outputs match"
28873
28874 test_419()
28875 {
28876         local dir=$DIR/$tdir
28877
28878         mkdir -p $dir
28879         touch $dir/file
28880
28881         cancel_lru_locks mdc
28882
28883         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28884         $LCTL set_param fail_loc=0x1410
28885         cat $dir/file
28886         $LCTL set_param fail_loc=0
28887         rm -rf $dir
28888 }
28889 run_test 419 "Verify open file by name doesn't crash kernel"
28890
28891 test_420()
28892 {
28893         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28894                 skip "Need MDS version at least 2.12.53"
28895
28896         local SAVE_UMASK=$(umask)
28897         local dir=$DIR/$tdir
28898         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28899
28900         mkdir -p $dir
28901         umask 0000
28902         mkdir -m03777 $dir/testdir
28903         ls -dn $dir/testdir
28904         # Need to remove trailing '.' when SELinux is enabled
28905         local dirperms=$(ls -dn $dir/testdir |
28906                          awk '{ sub(/\.$/, "", $1); print $1}')
28907         [ $dirperms == "drwxrwsrwt" ] ||
28908                 error "incorrect perms on $dir/testdir"
28909
28910         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28911                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28912         ls -n $dir/testdir/testfile
28913         local fileperms=$(ls -n $dir/testdir/testfile |
28914                           awk '{ sub(/\.$/, "", $1); print $1}')
28915         [ $fileperms == "-rwxr-xr-x" ] ||
28916                 error "incorrect perms on $dir/testdir/testfile"
28917
28918         umask $SAVE_UMASK
28919 }
28920 run_test 420 "clear SGID bit on non-directories for non-members"
28921
28922 test_421a() {
28923         local cnt
28924         local fid1
28925         local fid2
28926
28927         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28928                 skip "Need MDS version at least 2.12.54"
28929
28930         test_mkdir $DIR/$tdir
28931         createmany -o $DIR/$tdir/f 3
28932         cnt=$(ls -1 $DIR/$tdir | wc -l)
28933         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28934
28935         fid1=$(lfs path2fid $DIR/$tdir/f1)
28936         fid2=$(lfs path2fid $DIR/$tdir/f2)
28937         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28938
28939         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28940         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28941
28942         cnt=$(ls -1 $DIR/$tdir | wc -l)
28943         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28944
28945         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28946         createmany -o $DIR/$tdir/f 3
28947         cnt=$(ls -1 $DIR/$tdir | wc -l)
28948         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28949
28950         fid1=$(lfs path2fid $DIR/$tdir/f1)
28951         fid2=$(lfs path2fid $DIR/$tdir/f2)
28952         echo "remove using fsname $FSNAME"
28953         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28954
28955         cnt=$(ls -1 $DIR/$tdir | wc -l)
28956         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28957 }
28958 run_test 421a "simple rm by fid"
28959
28960 test_421b() {
28961         local cnt
28962         local FID1
28963         local FID2
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         createmany -o $DIR/$tdir/f 3
28970         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28971         MULTIPID=$!
28972
28973         FID1=$(lfs path2fid $DIR/$tdir/f1)
28974         FID2=$(lfs path2fid $DIR/$tdir/f2)
28975         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28976
28977         kill -USR1 $MULTIPID
28978         wait
28979
28980         cnt=$(ls $DIR/$tdir | wc -l)
28981         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28982 }
28983 run_test 421b "rm by fid on open file"
28984
28985 test_421c() {
28986         local cnt
28987         local FIDS
28988
28989         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28990                 skip "Need MDS version at least 2.12.54"
28991
28992         test_mkdir $DIR/$tdir
28993         createmany -o $DIR/$tdir/f 3
28994         touch $DIR/$tdir/$tfile
28995         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28996         cnt=$(ls -1 $DIR/$tdir | wc -l)
28997         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28998
28999         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29000         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29001
29002         cnt=$(ls $DIR/$tdir | wc -l)
29003         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29004 }
29005 run_test 421c "rm by fid against hardlinked files"
29006
29007 test_421d() {
29008         local cnt
29009         local FIDS
29010
29011         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29012                 skip "Need MDS version at least 2.12.54"
29013
29014         test_mkdir $DIR/$tdir
29015         createmany -o $DIR/$tdir/f 4097
29016         cnt=$(ls -1 $DIR/$tdir | wc -l)
29017         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29018
29019         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29020         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29021
29022         cnt=$(ls $DIR/$tdir | wc -l)
29023         rm -rf $DIR/$tdir
29024         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29025 }
29026 run_test 421d "rmfid en masse"
29027
29028 test_421e() {
29029         local cnt
29030         local FID
29031
29032         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29033         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29034                 skip "Need MDS version at least 2.12.54"
29035
29036         mkdir -p $DIR/$tdir
29037         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29038         createmany -o $DIR/$tdir/striped_dir/f 512
29039         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29040         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29041
29042         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29043                 sed "s/[/][^:]*://g")
29044         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29045
29046         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29047         rm -rf $DIR/$tdir
29048         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29049 }
29050 run_test 421e "rmfid in DNE"
29051
29052 test_421f() {
29053         local cnt
29054         local FID
29055
29056         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29057                 skip "Need MDS version at least 2.12.54"
29058
29059         test_mkdir $DIR/$tdir
29060         touch $DIR/$tdir/f
29061         cnt=$(ls -1 $DIR/$tdir | wc -l)
29062         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29063
29064         FID=$(lfs path2fid $DIR/$tdir/f)
29065         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29066         # rmfid should fail
29067         cnt=$(ls -1 $DIR/$tdir | wc -l)
29068         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29069
29070         chmod a+rw $DIR/$tdir
29071         ls -la $DIR/$tdir
29072         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29073         # rmfid should fail
29074         cnt=$(ls -1 $DIR/$tdir | wc -l)
29075         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29076
29077         rm -f $DIR/$tdir/f
29078         $RUNAS touch $DIR/$tdir/f
29079         FID=$(lfs path2fid $DIR/$tdir/f)
29080         echo "rmfid as root"
29081         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29082         cnt=$(ls -1 $DIR/$tdir | wc -l)
29083         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29084
29085         rm -f $DIR/$tdir/f
29086         $RUNAS touch $DIR/$tdir/f
29087         cnt=$(ls -1 $DIR/$tdir | wc -l)
29088         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29089         FID=$(lfs path2fid $DIR/$tdir/f)
29090         # rmfid w/o user_fid2path mount option should fail
29091         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29092         cnt=$(ls -1 $DIR/$tdir | wc -l)
29093         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29094
29095         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29096         stack_trap "rmdir $tmpdir"
29097         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29098                 error "failed to mount client'"
29099         stack_trap "umount_client $tmpdir"
29100
29101         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29102         # rmfid should succeed
29103         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29104         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29105
29106         # rmfid shouldn't allow to remove files due to dir's permission
29107         chmod a+rwx $tmpdir/$tdir
29108         touch $tmpdir/$tdir/f
29109         ls -la $tmpdir/$tdir
29110         FID=$(lfs path2fid $tmpdir/$tdir/f)
29111         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29112         return 0
29113 }
29114 run_test 421f "rmfid checks permissions"
29115
29116 test_421g() {
29117         local cnt
29118         local FIDS
29119
29120         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29121         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29122                 skip "Need MDS version at least 2.12.54"
29123
29124         mkdir -p $DIR/$tdir
29125         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29126         createmany -o $DIR/$tdir/striped_dir/f 512
29127         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29128         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29129
29130         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29131                 sed "s/[/][^:]*://g")
29132
29133         rm -f $DIR/$tdir/striped_dir/f1*
29134         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29135         removed=$((512 - cnt))
29136
29137         # few files have been just removed, so we expect
29138         # rmfid to fail on their fids
29139         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29140         [ $removed != $errors ] && error "$errors != $removed"
29141
29142         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29143         rm -rf $DIR/$tdir
29144         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29145 }
29146 run_test 421g "rmfid to return errors properly"
29147
29148 test_421h() {
29149         local mount_other
29150         local mount_ret
29151         local rmfid_ret
29152         local old_fid
29153         local fidA
29154         local fidB
29155         local fidC
29156         local fidD
29157
29158         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29159                 skip "Need MDS version at least 2.15.53"
29160
29161         test_mkdir $DIR/$tdir
29162         test_mkdir $DIR/$tdir/subdir
29163         touch $DIR/$tdir/subdir/file0
29164         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29165         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29166         rm -f $DIR/$tdir/subdir/file0
29167         touch $DIR/$tdir/subdir/fileA
29168         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29169         echo File $DIR/$tdir/subdir/fileA FID $fidA
29170         touch $DIR/$tdir/subdir/fileB
29171         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29172         echo File $DIR/$tdir/subdir/fileB FID $fidB
29173         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29174         touch $DIR/$tdir/subdir/fileC
29175         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29176         echo File $DIR/$tdir/subdir/fileC FID $fidC
29177         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29178         touch $DIR/$tdir/fileD
29179         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29180         echo File $DIR/$tdir/fileD FID $fidD
29181
29182         # mount another client mount point with subdirectory mount
29183         export FILESET=/$tdir/subdir
29184         mount_other=${MOUNT}_other
29185         mount_client $mount_other ${MOUNT_OPTS}
29186         mount_ret=$?
29187         export FILESET=""
29188         (( mount_ret == 0 )) || error "mount $mount_other failed"
29189
29190         echo Removing FIDs:
29191         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29192         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29193         rmfid_ret=$?
29194
29195         umount_client $mount_other || error "umount $mount_other failed"
29196
29197         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29198
29199         # fileA should have been deleted
29200         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29201
29202         # fileB should have been deleted
29203         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29204
29205         # fileC should not have been deleted, fid also exists outside of fileset
29206         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29207
29208         # fileD should not have been deleted, it exists outside of fileset
29209         stat $DIR/$tdir/fileD || error "fileD deleted"
29210 }
29211 run_test 421h "rmfid with fileset mount"
29212
29213 test_422() {
29214         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29215         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29216         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29217         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29218         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29219
29220         local amc=$(at_max_get client)
29221         local amo=$(at_max_get mds1)
29222         local timeout=`lctl get_param -n timeout`
29223
29224         at_max_set 0 client
29225         at_max_set 0 mds1
29226
29227 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29228         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29229                         fail_val=$(((2*timeout + 10)*1000))
29230         touch $DIR/$tdir/d3/file &
29231         sleep 2
29232 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29233         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29234                         fail_val=$((2*timeout + 5))
29235         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29236         local pid=$!
29237         sleep 1
29238         kill -9 $pid
29239         sleep $((2 * timeout))
29240         echo kill $pid
29241         kill -9 $pid
29242         lctl mark touch
29243         touch $DIR/$tdir/d2/file3
29244         touch $DIR/$tdir/d2/file4
29245         touch $DIR/$tdir/d2/file5
29246
29247         wait
29248         at_max_set $amc client
29249         at_max_set $amo mds1
29250
29251         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29252         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29253                 error "Watchdog is always throttled"
29254 }
29255 run_test 422 "kill a process with RPC in progress"
29256
29257 stat_test() {
29258     df -h $MOUNT &
29259     df -h $MOUNT &
29260     df -h $MOUNT &
29261     df -h $MOUNT &
29262     df -h $MOUNT &
29263     df -h $MOUNT &
29264 }
29265
29266 test_423() {
29267     local _stats
29268     # ensure statfs cache is expired
29269     sleep 2;
29270
29271     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29272     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29273
29274     return 0
29275 }
29276 run_test 423 "statfs should return a right data"
29277
29278 test_424() {
29279 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29280         $LCTL set_param fail_loc=0x80000522
29281         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29282         rm -f $DIR/$tfile
29283 }
29284 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29285
29286 test_425() {
29287         test_mkdir -c -1 $DIR/$tdir
29288         $LFS setstripe -c -1 $DIR/$tdir
29289
29290         lru_resize_disable "" 100
29291         stack_trap "lru_resize_enable" EXIT
29292
29293         sleep 5
29294
29295         for i in $(seq $((MDSCOUNT * 125))); do
29296                 local t=$DIR/$tdir/$tfile_$i
29297
29298                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29299                         error_noexit "Create file $t"
29300         done
29301         stack_trap "rm -rf $DIR/$tdir" EXIT
29302
29303         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29304                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29305                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29306
29307                 [ $lock_count -le $lru_size ] ||
29308                         error "osc lock count $lock_count > lru size $lru_size"
29309         done
29310
29311         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29312                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29313                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29314
29315                 [ $lock_count -le $lru_size ] ||
29316                         error "mdc lock count $lock_count > lru size $lru_size"
29317         done
29318 }
29319 run_test 425 "lock count should not exceed lru size"
29320
29321 test_426() {
29322         splice-test -r $DIR/$tfile
29323         splice-test -rd $DIR/$tfile
29324         splice-test $DIR/$tfile
29325         splice-test -d $DIR/$tfile
29326 }
29327 run_test 426 "splice test on Lustre"
29328
29329 test_427() {
29330         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29331         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29332                 skip "Need MDS version at least 2.12.4"
29333         local log
29334
29335         mkdir $DIR/$tdir
29336         mkdir $DIR/$tdir/1
29337         mkdir $DIR/$tdir/2
29338         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29339         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29340
29341         $LFS getdirstripe $DIR/$tdir/1/dir
29342
29343         #first setfattr for creating updatelog
29344         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29345
29346 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29347         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29348         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29349         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29350
29351         sleep 2
29352         fail mds2
29353         wait_recovery_complete mds2 $((2*TIMEOUT))
29354
29355         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29356         echo $log | grep "get update log failed" &&
29357                 error "update log corruption is detected" || true
29358 }
29359 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29360
29361 test_428() {
29362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29363         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29364                               awk '/^max_cached_mb/ { print $2 }')
29365         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29366
29367         $LCTL set_param -n llite.*.max_cached_mb=64
29368
29369         mkdir $DIR/$tdir
29370         $LFS setstripe -c 1 $DIR/$tdir
29371         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29372         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29373         #test write
29374         for f in $(seq 4); do
29375                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29376         done
29377         wait
29378
29379         cancel_lru_locks osc
29380         # Test read
29381         for f in $(seq 4); do
29382                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29383         done
29384         wait
29385 }
29386 run_test 428 "large block size IO should not hang"
29387
29388 test_429() { # LU-7915 / LU-10948
29389         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29390         local testfile=$DIR/$tfile
29391         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29392         local new_flag=1
29393         local first_rpc
29394         local second_rpc
29395         local third_rpc
29396
29397         $LCTL get_param $ll_opencache_threshold_count ||
29398                 skip "client does not have opencache parameter"
29399
29400         set_opencache $new_flag
29401         stack_trap "restore_opencache"
29402         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29403                 error "enable opencache failed"
29404         touch $testfile
29405         # drop MDC DLM locks
29406         cancel_lru_locks mdc
29407         # clear MDC RPC stats counters
29408         $LCTL set_param $mdc_rpcstats=clear
29409
29410         # According to the current implementation, we need to run 3 times
29411         # open & close file to verify if opencache is enabled correctly.
29412         # 1st, RPCs are sent for lookup/open and open handle is released on
29413         #      close finally.
29414         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29415         #      so open handle won't be released thereafter.
29416         # 3rd, No RPC is sent out.
29417         $MULTIOP $testfile oc || error "multiop failed"
29418         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29419         echo "1st: $first_rpc RPCs in flight"
29420
29421         $MULTIOP $testfile oc || error "multiop failed"
29422         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29423         echo "2nd: $second_rpc RPCs in flight"
29424
29425         $MULTIOP $testfile oc || error "multiop failed"
29426         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29427         echo "3rd: $third_rpc RPCs in flight"
29428
29429         #verify no MDC RPC is sent
29430         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29431 }
29432 run_test 429 "verify if opencache flag on client side does work"
29433
29434 lseek_test_430() {
29435         local offset
29436         local file=$1
29437
29438         # data at [200K, 400K)
29439         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29440                 error "256K->512K dd fails"
29441         # data at [2M, 3M)
29442         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29443                 error "2M->3M dd fails"
29444         # data at [4M, 5M)
29445         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29446                 error "4M->5M dd fails"
29447         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29448         # start at first component hole #1
29449         printf "Seeking hole from 1000 ... "
29450         offset=$(lseek_test -l 1000 $file)
29451         echo $offset
29452         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29453         printf "Seeking data from 1000 ... "
29454         offset=$(lseek_test -d 1000 $file)
29455         echo $offset
29456         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29457
29458         # start at first component data block
29459         printf "Seeking hole from 300000 ... "
29460         offset=$(lseek_test -l 300000 $file)
29461         echo $offset
29462         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29463         printf "Seeking data from 300000 ... "
29464         offset=$(lseek_test -d 300000 $file)
29465         echo $offset
29466         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29467
29468         # start at the first component but beyond end of object size
29469         printf "Seeking hole from 1000000 ... "
29470         offset=$(lseek_test -l 1000000 $file)
29471         echo $offset
29472         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29473         printf "Seeking data from 1000000 ... "
29474         offset=$(lseek_test -d 1000000 $file)
29475         echo $offset
29476         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29477
29478         # start at second component stripe 2 (empty file)
29479         printf "Seeking hole from 1500000 ... "
29480         offset=$(lseek_test -l 1500000 $file)
29481         echo $offset
29482         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29483         printf "Seeking data from 1500000 ... "
29484         offset=$(lseek_test -d 1500000 $file)
29485         echo $offset
29486         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29487
29488         # start at second component stripe 1 (all data)
29489         printf "Seeking hole from 3000000 ... "
29490         offset=$(lseek_test -l 3000000 $file)
29491         echo $offset
29492         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29493         printf "Seeking data from 3000000 ... "
29494         offset=$(lseek_test -d 3000000 $file)
29495         echo $offset
29496         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29497
29498         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29499                 error "2nd dd fails"
29500         echo "Add data block at 640K...1280K"
29501
29502         # start at before new data block, in hole
29503         printf "Seeking hole from 600000 ... "
29504         offset=$(lseek_test -l 600000 $file)
29505         echo $offset
29506         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29507         printf "Seeking data from 600000 ... "
29508         offset=$(lseek_test -d 600000 $file)
29509         echo $offset
29510         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29511
29512         # start at the first component new data block
29513         printf "Seeking hole from 1000000 ... "
29514         offset=$(lseek_test -l 1000000 $file)
29515         echo $offset
29516         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29517         printf "Seeking data from 1000000 ... "
29518         offset=$(lseek_test -d 1000000 $file)
29519         echo $offset
29520         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29521
29522         # start at second component stripe 2, new data
29523         printf "Seeking hole from 1200000 ... "
29524         offset=$(lseek_test -l 1200000 $file)
29525         echo $offset
29526         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29527         printf "Seeking data from 1200000 ... "
29528         offset=$(lseek_test -d 1200000 $file)
29529         echo $offset
29530         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29531
29532         # start beyond file end
29533         printf "Using offset > filesize ... "
29534         lseek_test -l 4000000 $file && error "lseek should fail"
29535         printf "Using offset > filesize ... "
29536         lseek_test -d 4000000 $file && error "lseek should fail"
29537
29538         printf "Done\n\n"
29539 }
29540
29541 test_430a() {
29542         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29543                 skip "MDT does not support SEEK_HOLE"
29544
29545         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29546                 skip "OST does not support SEEK_HOLE"
29547
29548         local file=$DIR/$tdir/$tfile
29549
29550         mkdir -p $DIR/$tdir
29551
29552         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29553         # OST stripe #1 will have continuous data at [1M, 3M)
29554         # OST stripe #2 is empty
29555         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29556         lseek_test_430 $file
29557         rm $file
29558         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29559         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29560         lseek_test_430 $file
29561         rm $file
29562         $LFS setstripe -c2 -S 512K $file
29563         echo "Two stripes, stripe size 512K"
29564         lseek_test_430 $file
29565         rm $file
29566         # FLR with stale mirror
29567         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29568                        -N -c2 -S 1M $file
29569         echo "Mirrored file:"
29570         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29571         echo "Plain 2 stripes 1M"
29572         lseek_test_430 $file
29573         rm $file
29574 }
29575 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29576
29577 test_430b() {
29578         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29579                 skip "OST does not support SEEK_HOLE"
29580
29581         local offset
29582         local file=$DIR/$tdir/$tfile
29583
29584         mkdir -p $DIR/$tdir
29585         # Empty layout lseek should fail
29586         $MCREATE $file
29587         # seek from 0
29588         printf "Seeking hole from 0 ... "
29589         lseek_test -l 0 $file && error "lseek should fail"
29590         printf "Seeking data from 0 ... "
29591         lseek_test -d 0 $file && error "lseek should fail"
29592         rm $file
29593
29594         # 1M-hole file
29595         $LFS setstripe -E 1M -c2 -E eof $file
29596         $TRUNCATE $file 1048576
29597         printf "Seeking hole from 1000000 ... "
29598         offset=$(lseek_test -l 1000000 $file)
29599         echo $offset
29600         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29601         printf "Seeking data from 1000000 ... "
29602         lseek_test -d 1000000 $file && error "lseek should fail"
29603         rm $file
29604
29605         # full component followed by non-inited one
29606         $LFS setstripe -E 1M -c2 -E eof $file
29607         dd if=/dev/urandom of=$file bs=1M count=1
29608         printf "Seeking hole from 1000000 ... "
29609         offset=$(lseek_test -l 1000000 $file)
29610         echo $offset
29611         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29612         printf "Seeking hole from 1048576 ... "
29613         lseek_test -l 1048576 $file && error "lseek should fail"
29614         # init second component and truncate back
29615         echo "123" >> $file
29616         $TRUNCATE $file 1048576
29617         printf "Seeking hole from 1000000 ... "
29618         offset=$(lseek_test -l 1000000 $file)
29619         echo $offset
29620         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29621         printf "Seeking hole from 1048576 ... "
29622         lseek_test -l 1048576 $file && error "lseek should fail"
29623         # boundary checks for big values
29624         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29625         offset=$(lseek_test -d 0 $file.10g)
29626         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29627         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29628         offset=$(lseek_test -d 0 $file.100g)
29629         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29630         return 0
29631 }
29632 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29633
29634 test_430c() {
29635         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29636                 skip "OST does not support SEEK_HOLE"
29637
29638         local file=$DIR/$tdir/$tfile
29639         local start
29640
29641         mkdir -p $DIR/$tdir
29642         stack_trap "rm -f $file $file.tmp"
29643         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29644
29645         # cp version 8.33+ prefers lseek over fiemap
29646         local ver=$(cp --version | awk '{ print $4; exit; }')
29647
29648         echo "cp $ver installed"
29649         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29650                 start=$SECONDS
29651                 time cp -v $file $file.tmp || error "cp $file failed"
29652                 (( SECONDS - start < 5 )) || {
29653                         strace cp $file $file.tmp |&
29654                                 grep -E "open|read|seek|FIEMAP" |
29655                                 grep -A 100 $file
29656                         error "cp: too long runtime $((SECONDS - start))"
29657                 }
29658         else
29659                 echo "cp test skipped due to $ver < 8.33"
29660         fi
29661
29662         # tar version 1.29+ supports SEEK_HOLE/DATA
29663         ver=$(tar --version | awk '{ print $4; exit; }')
29664         echo "tar $ver installed"
29665         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29666                 start=$SECONDS
29667                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29668                 (( SECONDS - start < 5 )) || {
29669                         strace tar cf $file.tmp --sparse $file |&
29670                                 grep -E "open|read|seek|FIEMAP" |
29671                                 grep -A 100 $file
29672                         error "tar: too long runtime $((SECONDS - start))"
29673                 }
29674         else
29675                 echo "tar test skipped due to $ver < 1.29"
29676         fi
29677 }
29678 run_test 430c "lseek: external tools check"
29679
29680 test_431() { # LU-14187
29681         local file=$DIR/$tdir/$tfile
29682
29683         mkdir -p $DIR/$tdir
29684         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29685         dd if=/dev/urandom of=$file bs=4k count=1
29686         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29687         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29688         #define OBD_FAIL_OST_RESTART_IO 0x251
29689         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29690         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29691         cp $file $file.0
29692         cancel_lru_locks
29693         sync_all_data
29694         echo 3 > /proc/sys/vm/drop_caches
29695         diff  $file $file.0 || error "data diff"
29696 }
29697 run_test 431 "Restart transaction for IO"
29698
29699 cleanup_test_432() {
29700         do_facet mgs $LCTL nodemap_activate 0
29701         wait_nm_sync active
29702 }
29703
29704 test_432() {
29705         local tmpdir=$TMP/dir432
29706
29707         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29708                 skip "Need MDS version at least 2.14.52"
29709
29710         stack_trap cleanup_test_432 EXIT
29711         mkdir $DIR/$tdir
29712         mkdir $tmpdir
29713
29714         do_facet mgs $LCTL nodemap_activate 1
29715         wait_nm_sync active
29716         do_facet mgs $LCTL nodemap_modify --name default \
29717                 --property admin --value 1
29718         do_facet mgs $LCTL nodemap_modify --name default \
29719                 --property trusted --value 1
29720         cancel_lru_locks mdc
29721         wait_nm_sync default admin_nodemap
29722         wait_nm_sync default trusted_nodemap
29723
29724         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29725                grep -ci "Operation not permitted") -ne 0 ]; then
29726                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29727         fi
29728 }
29729 run_test 432 "mv dir from outside Lustre"
29730
29731 test_433() {
29732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29733
29734         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29735                 skip "inode cache not supported"
29736
29737         $LCTL set_param llite.*.inode_cache=0
29738         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29739
29740         local count=256
29741         local before
29742         local after
29743
29744         cancel_lru_locks mdc
29745         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29746         createmany -m $DIR/$tdir/f $count
29747         createmany -d $DIR/$tdir/d $count
29748         ls -l $DIR/$tdir > /dev/null
29749         stack_trap "rm -rf $DIR/$tdir"
29750
29751         before=$(num_objects)
29752         cancel_lru_locks mdc
29753         after=$(num_objects)
29754
29755         # sometimes even @before is less than 2 * count
29756         while (( before - after < count )); do
29757                 sleep 1
29758                 after=$(num_objects)
29759                 wait=$((wait + 1))
29760                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29761                 if (( wait > 60 )); then
29762                         error "inode slab grew from $before to $after"
29763                 fi
29764         done
29765
29766         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29767 }
29768 run_test 433 "ldlm lock cancel releases dentries and inodes"
29769
29770 test_434() {
29771         local file
29772         local getxattr_count
29773         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29774         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29775
29776         [[ $(getenforce) == "Disabled" ]] ||
29777                 skip "lsm selinux module have to be disabled for this test"
29778
29779         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29780                 error "fail to create $DIR/$tdir/ on MDT0000"
29781
29782         touch $DIR/$tdir/$tfile-{001..100}
29783
29784         # disable the xattr cache
29785         save_lustre_params client "llite.*.xattr_cache" > $p
29786         lctl set_param llite.*.xattr_cache=0
29787         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29788
29789         # clear clients mdc stats
29790         clear_stats $mdc_stat_param ||
29791                 error "fail to clear stats on mdc MDT0000"
29792
29793         for file in $DIR/$tdir/$tfile-{001..100}; do
29794                 getfattr -n security.selinux $file |&
29795                         grep -q "Operation not supported" ||
29796                         error "getxattr on security.selinux should return EOPNOTSUPP"
29797         done
29798
29799         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29800         (( getxattr_count < 100 )) ||
29801                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29802 }
29803 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29804
29805 test_440() {
29806         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29807                 source $LUSTRE/scripts/bash-completion/lustre
29808         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29809                 source /usr/share/bash-completion/completions/lustre
29810         else
29811                 skip "bash completion scripts not found"
29812         fi
29813
29814         local lctl_completions
29815         local lfs_completions
29816
29817         lctl_completions=$(_lustre_cmds lctl)
29818         if [[ ! $lctl_completions =~ "get_param" ]]; then
29819                 error "lctl bash completion failed"
29820         fi
29821
29822         lfs_completions=$(_lustre_cmds lfs)
29823         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29824                 error "lfs bash completion failed"
29825         fi
29826 }
29827 run_test 440 "bash completion for lfs, lctl"
29828
29829 prep_801() {
29830         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29831         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29832                 skip "Need server version at least 2.9.55"
29833
29834         start_full_debug_logging
29835 }
29836
29837 post_801() {
29838         stop_full_debug_logging
29839 }
29840
29841 barrier_stat() {
29842         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29843                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29844                            awk '/The barrier for/ { print $7 }')
29845                 echo $st
29846         else
29847                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29848                 echo \'$st\'
29849         fi
29850 }
29851
29852 barrier_expired() {
29853         local expired
29854
29855         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29856                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29857                           awk '/will be expired/ { print $7 }')
29858         else
29859                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29860         fi
29861
29862         echo $expired
29863 }
29864
29865 test_801a() {
29866         prep_801
29867
29868         echo "Start barrier_freeze at: $(date)"
29869         #define OBD_FAIL_BARRIER_DELAY          0x2202
29870         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29871         # Do not reduce barrier time - See LU-11873
29872         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29873
29874         sleep 2
29875         local b_status=$(barrier_stat)
29876         echo "Got barrier status at: $(date)"
29877         [ "$b_status" = "'freezing_p1'" ] ||
29878                 error "(1) unexpected barrier status $b_status"
29879
29880         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29881         wait
29882         b_status=$(barrier_stat)
29883         [ "$b_status" = "'frozen'" ] ||
29884                 error "(2) unexpected barrier status $b_status"
29885
29886         local expired=$(barrier_expired)
29887         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29888         sleep $((expired + 3))
29889
29890         b_status=$(barrier_stat)
29891         [ "$b_status" = "'expired'" ] ||
29892                 error "(3) unexpected barrier status $b_status"
29893
29894         # Do not reduce barrier time - See LU-11873
29895         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29896                 error "(4) fail to freeze barrier"
29897
29898         b_status=$(barrier_stat)
29899         [ "$b_status" = "'frozen'" ] ||
29900                 error "(5) unexpected barrier status $b_status"
29901
29902         echo "Start barrier_thaw at: $(date)"
29903         #define OBD_FAIL_BARRIER_DELAY          0x2202
29904         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29905         do_facet mgs $LCTL barrier_thaw $FSNAME &
29906
29907         sleep 2
29908         b_status=$(barrier_stat)
29909         echo "Got barrier status at: $(date)"
29910         [ "$b_status" = "'thawing'" ] ||
29911                 error "(6) unexpected barrier status $b_status"
29912
29913         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29914         wait
29915         b_status=$(barrier_stat)
29916         [ "$b_status" = "'thawed'" ] ||
29917                 error "(7) unexpected barrier status $b_status"
29918
29919         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29920         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29921         do_facet mgs $LCTL barrier_freeze $FSNAME
29922
29923         b_status=$(barrier_stat)
29924         [ "$b_status" = "'failed'" ] ||
29925                 error "(8) unexpected barrier status $b_status"
29926
29927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29928         do_facet mgs $LCTL barrier_thaw $FSNAME
29929
29930         post_801
29931 }
29932 run_test 801a "write barrier user interfaces and stat machine"
29933
29934 test_801b() {
29935         prep_801
29936
29937         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29938         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29939         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29940         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29941         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29942
29943         cancel_lru_locks mdc
29944
29945         # 180 seconds should be long enough
29946         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29947
29948         local b_status=$(barrier_stat)
29949         [ "$b_status" = "'frozen'" ] ||
29950                 error "(6) unexpected barrier status $b_status"
29951
29952         mkdir $DIR/$tdir/d0/d10 &
29953         mkdir_pid=$!
29954
29955         touch $DIR/$tdir/d1/f13 &
29956         touch_pid=$!
29957
29958         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29959         ln_pid=$!
29960
29961         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29962         mv_pid=$!
29963
29964         rm -f $DIR/$tdir/d4/f12 &
29965         rm_pid=$!
29966
29967         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29968
29969         # To guarantee taht the 'stat' is not blocked
29970         b_status=$(barrier_stat)
29971         [ "$b_status" = "'frozen'" ] ||
29972                 error "(8) unexpected barrier status $b_status"
29973
29974         # let above commands to run at background
29975         sleep 5
29976
29977         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29978         ps -p $touch_pid || error "(10) touch should be blocked"
29979         ps -p $ln_pid || error "(11) link should be blocked"
29980         ps -p $mv_pid || error "(12) rename should be blocked"
29981         ps -p $rm_pid || error "(13) unlink should be blocked"
29982
29983         b_status=$(barrier_stat)
29984         [ "$b_status" = "'frozen'" ] ||
29985                 error "(14) unexpected barrier status $b_status"
29986
29987         do_facet mgs $LCTL barrier_thaw $FSNAME
29988         b_status=$(barrier_stat)
29989         [ "$b_status" = "'thawed'" ] ||
29990                 error "(15) unexpected barrier status $b_status"
29991
29992         wait $mkdir_pid || error "(16) mkdir should succeed"
29993         wait $touch_pid || error "(17) touch should succeed"
29994         wait $ln_pid || error "(18) link should succeed"
29995         wait $mv_pid || error "(19) rename should succeed"
29996         wait $rm_pid || error "(20) unlink should succeed"
29997
29998         post_801
29999 }
30000 run_test 801b "modification will be blocked by write barrier"
30001
30002 test_801c() {
30003         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30004
30005         prep_801
30006
30007         stop mds2 || error "(1) Fail to stop mds2"
30008
30009         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30010
30011         local b_status=$(barrier_stat)
30012         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30013                 do_facet mgs $LCTL barrier_thaw $FSNAME
30014                 error "(2) unexpected barrier status $b_status"
30015         }
30016
30017         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30018                 error "(3) Fail to rescan barrier bitmap"
30019
30020         # Do not reduce barrier time - See LU-11873
30021         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30022
30023         b_status=$(barrier_stat)
30024         [ "$b_status" = "'frozen'" ] ||
30025                 error "(4) unexpected barrier status $b_status"
30026
30027         do_facet mgs $LCTL barrier_thaw $FSNAME
30028         b_status=$(barrier_stat)
30029         [ "$b_status" = "'thawed'" ] ||
30030                 error "(5) unexpected barrier status $b_status"
30031
30032         local devname=$(mdsdevname 2)
30033
30034         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30035
30036         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30037                 error "(7) Fail to rescan barrier bitmap"
30038
30039         post_801
30040 }
30041 run_test 801c "rescan barrier bitmap"
30042
30043 test_802b() {
30044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30045         remote_mds_nodsh && skip "remote MDS with nodsh"
30046
30047         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30048                 skip "readonly option not available"
30049
30050         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30051
30052         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30053                 error "(2) Fail to copy"
30054
30055         # write back all cached data before setting MDT to readonly
30056         cancel_lru_locks
30057         sync_all_data
30058
30059         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30060         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30061
30062         echo "Modify should be refused"
30063         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30064
30065         echo "Read should be allowed"
30066         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30067                 error "(7) Read should succeed under ro mode"
30068
30069         # disable readonly
30070         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30071 }
30072 run_test 802b "be able to set MDTs to readonly"
30073
30074 test_803a() {
30075         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30076         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30077                 skip "MDS needs to be newer than 2.10.54"
30078
30079         mkdir_on_mdt0 $DIR/$tdir
30080         # Create some objects on all MDTs to trigger related logs objects
30081         for idx in $(seq $MDSCOUNT); do
30082                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30083                         $DIR/$tdir/dir${idx} ||
30084                         error "Fail to create $DIR/$tdir/dir${idx}"
30085         done
30086
30087         wait_delete_completed # ensure old test cleanups are finished
30088         sleep 3
30089         echo "before create:"
30090         $LFS df -i $MOUNT
30091         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30092
30093         for i in {1..10}; do
30094                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30095                         error "Fail to create $DIR/$tdir/foo$i"
30096         done
30097
30098         # sync ZFS-on-MDS to refresh statfs data
30099         wait_zfs_commit mds1
30100         sleep 3
30101         echo "after create:"
30102         $LFS df -i $MOUNT
30103         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30104
30105         # allow for an llog to be cleaned up during the test
30106         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30107                 error "before ($before_used) + 10 > after ($after_used)"
30108
30109         for i in {1..10}; do
30110                 rm -rf $DIR/$tdir/foo$i ||
30111                         error "Fail to remove $DIR/$tdir/foo$i"
30112         done
30113
30114         # sync ZFS-on-MDS to refresh statfs data
30115         wait_zfs_commit mds1
30116         wait_delete_completed
30117         sleep 3 # avoid MDT return cached statfs
30118         echo "after unlink:"
30119         $LFS df -i $MOUNT
30120         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30121
30122         # allow for an llog to be created during the test
30123         [ $after_used -le $((before_used + 1)) ] ||
30124                 error "after ($after_used) > before ($before_used) + 1"
30125 }
30126 run_test 803a "verify agent object for remote object"
30127
30128 test_803b() {
30129         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30130         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30131                 skip "MDS needs to be newer than 2.13.56"
30132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30133
30134         for i in $(seq 0 $((MDSCOUNT - 1))); do
30135                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30136         done
30137
30138         local before=0
30139         local after=0
30140
30141         local tmp
30142
30143         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30144         for i in $(seq 0 $((MDSCOUNT - 1))); do
30145                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30146                         awk '/getattr/ { print $2 }')
30147                 before=$((before + tmp))
30148         done
30149         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30150         for i in $(seq 0 $((MDSCOUNT - 1))); do
30151                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30152                         awk '/getattr/ { print $2 }')
30153                 after=$((after + tmp))
30154         done
30155
30156         [ $before -eq $after ] || error "getattr count $before != $after"
30157 }
30158 run_test 803b "remote object can getattr from cache"
30159
30160 test_804() {
30161         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30162         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30163                 skip "MDS needs to be newer than 2.10.54"
30164         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30165
30166         mkdir -p $DIR/$tdir
30167         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30168                 error "Fail to create $DIR/$tdir/dir0"
30169
30170         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30171         local dev=$(mdsdevname 2)
30172
30173         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30174                 grep ${fid} || error "NOT found agent entry for dir0"
30175
30176         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30177                 error "Fail to create $DIR/$tdir/dir1"
30178
30179         touch $DIR/$tdir/dir1/foo0 ||
30180                 error "Fail to create $DIR/$tdir/dir1/foo0"
30181         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30182         local rc=0
30183
30184         for idx in $(seq $MDSCOUNT); do
30185                 dev=$(mdsdevname $idx)
30186                 do_facet mds${idx} \
30187                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30188                         grep ${fid} && rc=$idx
30189         done
30190
30191         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30192                 error "Fail to rename foo0 to foo1"
30193         if [ $rc -eq 0 ]; then
30194                 for idx in $(seq $MDSCOUNT); do
30195                         dev=$(mdsdevname $idx)
30196                         do_facet mds${idx} \
30197                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30198                         grep ${fid} && rc=$idx
30199                 done
30200         fi
30201
30202         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30203                 error "Fail to rename foo1 to foo2"
30204         if [ $rc -eq 0 ]; then
30205                 for idx in $(seq $MDSCOUNT); do
30206                         dev=$(mdsdevname $idx)
30207                         do_facet mds${idx} \
30208                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30209                         grep ${fid} && rc=$idx
30210                 done
30211         fi
30212
30213         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30214
30215         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30216                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30217         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30218                 error "Fail to rename foo2 to foo0"
30219         unlink $DIR/$tdir/dir1/foo0 ||
30220                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30221         rm -rf $DIR/$tdir/dir0 ||
30222                 error "Fail to rm $DIR/$tdir/dir0"
30223
30224         for idx in $(seq $MDSCOUNT); do
30225                 rc=0
30226
30227                 stop mds${idx}
30228                 dev=$(mdsdevname $idx)
30229                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30230                         rc=$?
30231                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30232                         error "mount mds$idx failed"
30233                 df $MOUNT > /dev/null 2>&1
30234
30235                 # e2fsck should not return error
30236                 [ $rc -eq 0 ] ||
30237                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30238         done
30239 }
30240 run_test 804 "verify agent entry for remote entry"
30241
30242 cleanup_805() {
30243         do_facet $SINGLEMDS zfs set quota=$old $fsset
30244         unlinkmany $DIR/$tdir/f- 1000000
30245         trap 0
30246 }
30247
30248 test_805() {
30249         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30250         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30251         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30252                 skip "netfree not implemented before 0.7"
30253         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30254                 skip "Need MDS version at least 2.10.57"
30255
30256         local fsset
30257         local freekb
30258         local usedkb
30259         local old
30260         local quota
30261         local pref="osd-zfs.$FSNAME-MDT0000."
30262
30263         # limit available space on MDS dataset to meet nospace issue
30264         # quickly. then ZFS 0.7.2 can use reserved space if asked
30265         # properly (using netfree flag in osd_declare_destroy()
30266         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30267         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30268                 gawk '{print $3}')
30269         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30270         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30271         let "usedkb=usedkb-freekb"
30272         let "freekb=freekb/2"
30273         if let "freekb > 5000"; then
30274                 let "freekb=5000"
30275         fi
30276         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30277         trap cleanup_805 EXIT
30278         mkdir_on_mdt0 $DIR/$tdir
30279         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30280                 error "Can't set PFL layout"
30281         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30282         rm -rf $DIR/$tdir || error "not able to remove"
30283         do_facet $SINGLEMDS zfs set quota=$old $fsset
30284         trap 0
30285 }
30286 run_test 805 "ZFS can remove from full fs"
30287
30288 # Size-on-MDS test
30289 check_lsom_data()
30290 {
30291         local file=$1
30292         local expect=$(stat -c %s $file)
30293
30294         check_lsom_size $1 $expect
30295
30296         local blocks=$($LFS getsom -b $file)
30297         expect=$(stat -c %b $file)
30298         [[ $blocks == $expect ]] ||
30299                 error "$file expected blocks: $expect, got: $blocks"
30300 }
30301
30302 check_lsom_size()
30303 {
30304         local size
30305         local expect=$2
30306
30307         cancel_lru_locks mdc
30308
30309         size=$($LFS getsom -s $1)
30310         [[ $size == $expect ]] ||
30311                 error "$file expected size: $expect, got: $size"
30312 }
30313
30314 test_806() {
30315         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30316                 skip "Need MDS version at least 2.11.52"
30317
30318         local bs=1048576
30319
30320         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30321
30322         disable_opencache
30323         stack_trap "restore_opencache"
30324
30325         # single-threaded write
30326         echo "Test SOM for single-threaded write"
30327         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30328                 error "write $tfile failed"
30329         check_lsom_size $DIR/$tfile $bs
30330
30331         local num=32
30332         local size=$(($num * $bs))
30333         local offset=0
30334         local i
30335
30336         echo "Test SOM for single client multi-threaded($num) write"
30337         $TRUNCATE $DIR/$tfile 0
30338         for ((i = 0; i < $num; i++)); do
30339                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30340                 local pids[$i]=$!
30341                 offset=$((offset + $bs))
30342         done
30343         for (( i=0; i < $num; i++ )); do
30344                 wait ${pids[$i]}
30345         done
30346         check_lsom_size $DIR/$tfile $size
30347
30348         $TRUNCATE $DIR/$tfile 0
30349         for ((i = 0; i < $num; i++)); do
30350                 offset=$((offset - $bs))
30351                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30352                 local pids[$i]=$!
30353         done
30354         for (( i=0; i < $num; i++ )); do
30355                 wait ${pids[$i]}
30356         done
30357         check_lsom_size $DIR/$tfile $size
30358
30359         # multi-client writes
30360         num=$(get_node_count ${CLIENTS//,/ })
30361         size=$(($num * $bs))
30362         offset=0
30363         i=0
30364
30365         echo "Test SOM for multi-client ($num) writes"
30366         $TRUNCATE $DIR/$tfile 0
30367         for client in ${CLIENTS//,/ }; do
30368                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30369                 local pids[$i]=$!
30370                 i=$((i + 1))
30371                 offset=$((offset + $bs))
30372         done
30373         for (( i=0; i < $num; i++ )); do
30374                 wait ${pids[$i]}
30375         done
30376         check_lsom_size $DIR/$tfile $offset
30377
30378         i=0
30379         $TRUNCATE $DIR/$tfile 0
30380         for client in ${CLIENTS//,/ }; do
30381                 offset=$((offset - $bs))
30382                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30383                 local pids[$i]=$!
30384                 i=$((i + 1))
30385         done
30386         for (( i=0; i < $num; i++ )); do
30387                 wait ${pids[$i]}
30388         done
30389         check_lsom_size $DIR/$tfile $size
30390
30391         # verify SOM blocks count
30392         echo "Verify SOM block count"
30393         $TRUNCATE $DIR/$tfile 0
30394         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30395                 error "failed to write file $tfile with fdatasync and fstat"
30396         check_lsom_data $DIR/$tfile
30397
30398         $TRUNCATE $DIR/$tfile 0
30399         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30400                 error "failed to write file $tfile with fdatasync"
30401         check_lsom_data $DIR/$tfile
30402
30403         $TRUNCATE $DIR/$tfile 0
30404         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30405                 error "failed to write file $tfile with sync IO"
30406         check_lsom_data $DIR/$tfile
30407
30408         # verify truncate
30409         echo "Test SOM for truncate"
30410         # use ftruncate to sync blocks on close request
30411         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30412         check_lsom_size $DIR/$tfile 16384
30413         check_lsom_data $DIR/$tfile
30414
30415         $TRUNCATE $DIR/$tfile 1234
30416         check_lsom_size $DIR/$tfile 1234
30417         # sync blocks on the MDT
30418         $MULTIOP $DIR/$tfile oc
30419         check_lsom_data $DIR/$tfile
30420 }
30421 run_test 806 "Verify Lazy Size on MDS"
30422
30423 test_807() {
30424         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30425         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30426                 skip "Need MDS version at least 2.11.52"
30427
30428         # Registration step
30429         changelog_register || error "changelog_register failed"
30430         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30431         changelog_users $SINGLEMDS | grep -q $cl_user ||
30432                 error "User $cl_user not found in changelog_users"
30433
30434         rm -rf $DIR/$tdir || error "rm $tdir failed"
30435         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30436         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30437         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30438         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30439                 error "truncate $tdir/trunc failed"
30440
30441         local bs=1048576
30442         echo "Test SOM for single-threaded write with fsync"
30443         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30444                 error "write $tfile failed"
30445         sync;sync;sync
30446
30447         # multi-client wirtes
30448         local num=$(get_node_count ${CLIENTS//,/ })
30449         local offset=0
30450         local i=0
30451
30452         echo "Test SOM for multi-client ($num) writes"
30453         touch $DIR/$tfile || error "touch $tfile failed"
30454         $TRUNCATE $DIR/$tfile 0
30455         for client in ${CLIENTS//,/ }; do
30456                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30457                 local pids[$i]=$!
30458                 i=$((i + 1))
30459                 offset=$((offset + $bs))
30460         done
30461         for (( i=0; i < $num; i++ )); do
30462                 wait ${pids[$i]}
30463         done
30464
30465         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30466         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30467         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30468         check_lsom_data $DIR/$tdir/trunc
30469         check_lsom_data $DIR/$tdir/single_dd
30470         check_lsom_data $DIR/$tfile
30471
30472         rm -rf $DIR/$tdir
30473         # Deregistration step
30474         changelog_deregister || error "changelog_deregister failed"
30475 }
30476 run_test 807 "verify LSOM syncing tool"
30477
30478 check_som_nologged()
30479 {
30480         local lines=$($LFS changelog $FSNAME-MDT0000 |
30481                 grep 'x=trusted.som' | wc -l)
30482         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30483 }
30484
30485 test_808() {
30486         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30487                 skip "Need MDS version at least 2.11.55"
30488
30489         # Registration step
30490         changelog_register || error "changelog_register failed"
30491
30492         touch $DIR/$tfile || error "touch $tfile failed"
30493         check_som_nologged
30494
30495         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30496                 error "write $tfile failed"
30497         check_som_nologged
30498
30499         $TRUNCATE $DIR/$tfile 1234
30500         check_som_nologged
30501
30502         $TRUNCATE $DIR/$tfile 1048576
30503         check_som_nologged
30504
30505         # Deregistration step
30506         changelog_deregister || error "changelog_deregister failed"
30507 }
30508 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30509
30510 check_som_nodata()
30511 {
30512         $LFS getsom $1
30513         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30514 }
30515
30516 test_809() {
30517         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30518                 skip "Need MDS version at least 2.11.56"
30519
30520         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30521                 error "failed to create DoM-only file $DIR/$tfile"
30522         touch $DIR/$tfile || error "touch $tfile failed"
30523         check_som_nodata $DIR/$tfile
30524
30525         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30526                 error "write $tfile failed"
30527         check_som_nodata $DIR/$tfile
30528
30529         $TRUNCATE $DIR/$tfile 1234
30530         check_som_nodata $DIR/$tfile
30531
30532         $TRUNCATE $DIR/$tfile 4097
30533         check_som_nodata $DIR/$file
30534 }
30535 run_test 809 "Verify no SOM xattr store for DoM-only files"
30536
30537 test_810() {
30538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30539         $GSS && skip_env "could not run with gss"
30540         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30541                 skip "OST < 2.12.58 doesn't align checksum"
30542
30543         set_checksums 1
30544         stack_trap "set_checksums $ORIG_CSUM" EXIT
30545         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30546
30547         local csum
30548         local before
30549         local after
30550         for csum in $CKSUM_TYPES; do
30551                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30552                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30553                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30554                         eval set -- $i
30555                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30556                         before=$(md5sum $DIR/$tfile)
30557                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30558                         after=$(md5sum $DIR/$tfile)
30559                         [ "$before" == "$after" ] ||
30560                                 error "$csum: $before != $after bs=$1 seek=$2"
30561                 done
30562         done
30563 }
30564 run_test 810 "partial page writes on ZFS (LU-11663)"
30565
30566 test_812a() {
30567         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30568                 skip "OST < 2.12.51 doesn't support this fail_loc"
30569
30570         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30571         # ensure ost1 is connected
30572         stat $DIR/$tfile >/dev/null || error "can't stat"
30573         wait_osc_import_state client ost1 FULL
30574         # no locks, no reqs to let the connection idle
30575         cancel_lru_locks osc
30576
30577         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30578 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30579         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30580         wait_osc_import_state client ost1 CONNECTING
30581         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30582
30583         stat $DIR/$tfile >/dev/null || error "can't stat file"
30584 }
30585 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30586
30587 test_812b() { # LU-12378
30588         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30589                 skip "OST < 2.12.51 doesn't support this fail_loc"
30590
30591         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30592         # ensure ost1 is connected
30593         stat $DIR/$tfile >/dev/null || error "can't stat"
30594         wait_osc_import_state client ost1 FULL
30595         # no locks, no reqs to let the connection idle
30596         cancel_lru_locks osc
30597
30598         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30599 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30600         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30601         wait_osc_import_state client ost1 CONNECTING
30602         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30603
30604         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30605         wait_osc_import_state client ost1 IDLE
30606 }
30607 run_test 812b "do not drop no resend request for idle connect"
30608
30609 test_812c() {
30610         local old
30611
30612         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30613
30614         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30615         $LFS getstripe $DIR/$tfile
30616         $LCTL set_param osc.*.idle_timeout=10
30617         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30618         # ensure ost1 is connected
30619         stat $DIR/$tfile >/dev/null || error "can't stat"
30620         wait_osc_import_state client ost1 FULL
30621         # no locks, no reqs to let the connection idle
30622         cancel_lru_locks osc
30623
30624 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30625         $LCTL set_param fail_loc=0x80000533
30626         sleep 15
30627         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30628 }
30629 run_test 812c "idle import vs lock enqueue race"
30630
30631 test_813() {
30632         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30633         [ -z "$file_heat_sav" ] && skip "no file heat support"
30634
30635         local readsample
30636         local writesample
30637         local readbyte
30638         local writebyte
30639         local readsample1
30640         local writesample1
30641         local readbyte1
30642         local writebyte1
30643
30644         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30645         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30646
30647         $LCTL set_param -n llite.*.file_heat=1
30648         echo "Turn on file heat"
30649         echo "Period second: $period_second, Decay percentage: $decay_pct"
30650
30651         echo "QQQQ" > $DIR/$tfile
30652         echo "QQQQ" > $DIR/$tfile
30653         echo "QQQQ" > $DIR/$tfile
30654         cat $DIR/$tfile > /dev/null
30655         cat $DIR/$tfile > /dev/null
30656         cat $DIR/$tfile > /dev/null
30657         cat $DIR/$tfile > /dev/null
30658
30659         local out=$($LFS heat_get $DIR/$tfile)
30660
30661         $LFS heat_get $DIR/$tfile
30662         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30663         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30664         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30665         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30666
30667         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30668         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30669         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30670         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30671
30672         sleep $((period_second + 3))
30673         echo "Sleep $((period_second + 3)) seconds..."
30674         # The recursion formula to calculate the heat of the file f is as
30675         # follow:
30676         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30677         # Where Hi is the heat value in the period between time points i*I and
30678         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30679         # to the weight of Ci.
30680         out=$($LFS heat_get $DIR/$tfile)
30681         $LFS heat_get $DIR/$tfile
30682         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30683         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30684         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30685         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30686
30687         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30688                 error "read sample ($readsample) is wrong"
30689         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30690                 error "write sample ($writesample) is wrong"
30691         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30692                 error "read bytes ($readbyte) is wrong"
30693         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30694                 error "write bytes ($writebyte) is wrong"
30695
30696         echo "QQQQ" > $DIR/$tfile
30697         echo "QQQQ" > $DIR/$tfile
30698         echo "QQQQ" > $DIR/$tfile
30699         cat $DIR/$tfile > /dev/null
30700         cat $DIR/$tfile > /dev/null
30701         cat $DIR/$tfile > /dev/null
30702         cat $DIR/$tfile > /dev/null
30703
30704         sleep $((period_second + 3))
30705         echo "Sleep $((period_second + 3)) seconds..."
30706
30707         out=$($LFS heat_get $DIR/$tfile)
30708         $LFS heat_get $DIR/$tfile
30709         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30710         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30711         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30712         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30713
30714         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30715                 4 * $decay_pct) / 100") -eq 1 ] ||
30716                 error "read sample ($readsample1) is wrong"
30717         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30718                 3 * $decay_pct) / 100") -eq 1 ] ||
30719                 error "write sample ($writesample1) is wrong"
30720         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30721                 20 * $decay_pct) / 100") -eq 1 ] ||
30722                 error "read bytes ($readbyte1) is wrong"
30723         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30724                 15 * $decay_pct) / 100") -eq 1 ] ||
30725                 error "write bytes ($writebyte1) is wrong"
30726
30727         echo "Turn off file heat for the file $DIR/$tfile"
30728         $LFS heat_set -o $DIR/$tfile
30729
30730         echo "QQQQ" > $DIR/$tfile
30731         echo "QQQQ" > $DIR/$tfile
30732         echo "QQQQ" > $DIR/$tfile
30733         cat $DIR/$tfile > /dev/null
30734         cat $DIR/$tfile > /dev/null
30735         cat $DIR/$tfile > /dev/null
30736         cat $DIR/$tfile > /dev/null
30737
30738         out=$($LFS heat_get $DIR/$tfile)
30739         $LFS heat_get $DIR/$tfile
30740         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30741         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30742         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30743         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30744
30745         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30746         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30747         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30748         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30749
30750         echo "Trun on file heat for the file $DIR/$tfile"
30751         $LFS heat_set -O $DIR/$tfile
30752
30753         echo "QQQQ" > $DIR/$tfile
30754         echo "QQQQ" > $DIR/$tfile
30755         echo "QQQQ" > $DIR/$tfile
30756         cat $DIR/$tfile > /dev/null
30757         cat $DIR/$tfile > /dev/null
30758         cat $DIR/$tfile > /dev/null
30759         cat $DIR/$tfile > /dev/null
30760
30761         out=$($LFS heat_get $DIR/$tfile)
30762         $LFS heat_get $DIR/$tfile
30763         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30764         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30765         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30766         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30767
30768         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30769         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30770         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30771         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30772
30773         $LFS heat_set -c $DIR/$tfile
30774         $LCTL set_param -n llite.*.file_heat=0
30775         echo "Turn off file heat support for the Lustre filesystem"
30776
30777         echo "QQQQ" > $DIR/$tfile
30778         echo "QQQQ" > $DIR/$tfile
30779         echo "QQQQ" > $DIR/$tfile
30780         cat $DIR/$tfile > /dev/null
30781         cat $DIR/$tfile > /dev/null
30782         cat $DIR/$tfile > /dev/null
30783         cat $DIR/$tfile > /dev/null
30784
30785         out=$($LFS heat_get $DIR/$tfile)
30786         $LFS heat_get $DIR/$tfile
30787         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30788         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30789         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30790         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30791
30792         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30793         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30794         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30795         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30796
30797         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30798         rm -f $DIR/$tfile
30799 }
30800 run_test 813 "File heat verfication"
30801
30802 test_814()
30803 {
30804         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30805         echo -n y >> $DIR/$tfile
30806         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30807         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30808 }
30809 run_test 814 "sparse cp works as expected (LU-12361)"
30810
30811 test_815()
30812 {
30813         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30814         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30815 }
30816 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30817
30818 test_816() {
30819         local ost1_imp=$(get_osc_import_name client ost1)
30820         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30821                          cut -d'.' -f2)
30822
30823         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30824         # ensure ost1 is connected
30825
30826         stat $DIR/$tfile >/dev/null || error "can't stat"
30827         wait_osc_import_state client ost1 FULL
30828         # no locks, no reqs to let the connection idle
30829         cancel_lru_locks osc
30830         lru_resize_disable osc
30831         local before
30832         local now
30833         before=$($LCTL get_param -n \
30834                  ldlm.namespaces.$imp_name.lru_size)
30835
30836         wait_osc_import_state client ost1 IDLE
30837         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30838         now=$($LCTL get_param -n \
30839               ldlm.namespaces.$imp_name.lru_size)
30840         [ $before == $now ] || error "lru_size changed $before != $now"
30841 }
30842 run_test 816 "do not reset lru_resize on idle reconnect"
30843
30844 cleanup_817() {
30845         umount $tmpdir
30846         exportfs -u localhost:$DIR/nfsexp
30847         rm -rf $DIR/nfsexp
30848 }
30849
30850 test_817() {
30851         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30852
30853         mkdir -p $DIR/nfsexp
30854         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30855                 error "failed to export nfs"
30856
30857         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30858         stack_trap cleanup_817 EXIT
30859
30860         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30861                 error "failed to mount nfs to $tmpdir"
30862
30863         cp /bin/true $tmpdir
30864         $DIR/nfsexp/true || error "failed to execute 'true' command"
30865 }
30866 run_test 817 "nfsd won't cache write lock for exec file"
30867
30868 test_818() {
30869         test_mkdir -i0 -c1 $DIR/$tdir
30870         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30871         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30872         stop $SINGLEMDS
30873
30874         # restore osp-syn threads
30875         stack_trap "fail $SINGLEMDS"
30876
30877         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30878         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30879         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30880                 error "start $SINGLEMDS failed"
30881         rm -rf $DIR/$tdir
30882
30883         local testid=$(echo $TESTNAME | tr '_' ' ')
30884
30885         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30886                 grep "run LFSCK" || error "run LFSCK is not suggested"
30887 }
30888 run_test 818 "unlink with failed llog"
30889
30890 test_819a() {
30891         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30892         cancel_lru_locks osc
30893         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30894         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30895         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30896         rm -f $TDIR/$tfile
30897 }
30898 run_test 819a "too big niobuf in read"
30899
30900 test_819b() {
30901         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30902         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30903         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30904         cancel_lru_locks osc
30905         sleep 1
30906         rm -f $TDIR/$tfile
30907 }
30908 run_test 819b "too big niobuf in write"
30909
30910
30911 function test_820_start_ost() {
30912         sleep 5
30913
30914         for num in $(seq $OSTCOUNT); do
30915                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30916         done
30917 }
30918
30919 test_820() {
30920         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30921
30922         mkdir $DIR/$tdir
30923         umount_client $MOUNT || error "umount failed"
30924         for num in $(seq $OSTCOUNT); do
30925                 stop ost$num
30926         done
30927
30928         # mount client with no active OSTs
30929         # so that the client can't initialize max LOV EA size
30930         # from OSC notifications
30931         mount_client $MOUNT || error "mount failed"
30932         # delay OST starting to keep this 0 max EA size for a while
30933         test_820_start_ost &
30934
30935         # create a directory on MDS2
30936         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30937                 error "Failed to create directory"
30938         # open intent should update default EA size
30939         # see mdc_update_max_ea_from_body()
30940         # notice this is the very first RPC to MDS2
30941         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30942         ret=$?
30943         echo $out
30944         # With SSK, this situation can lead to -EPERM being returned.
30945         # In that case, simply retry.
30946         if [ $ret -ne 0 ] && $SHARED_KEY; then
30947                 if echo "$out" | grep -q "not permitted"; then
30948                         cp /etc/services $DIR/$tdir/mds2
30949                         ret=$?
30950                 fi
30951         fi
30952         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30953 }
30954 run_test 820 "update max EA from open intent"
30955
30956 test_823() {
30957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30958         local OST_MAX_PRECREATE=20000
30959
30960         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30961                 skip "Need MDS version at least 2.14.56"
30962
30963         save_lustre_params mds1 \
30964                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30965         do_facet $SINGLEMDS "$LCTL set_param -n \
30966                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30967         do_facet $SINGLEMDS "$LCTL set_param -n \
30968                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30969
30970         stack_trap "restore_lustre_params < $p; rm $p"
30971
30972         do_facet $SINGLEMDS "$LCTL set_param -n \
30973                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30974
30975         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30976                       osp.$FSNAME-OST0000*MDT0000.create_count")
30977         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30978                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30979         local expect_count=$(((($max/2)/256) * 256))
30980
30981         log "setting create_count to 100200:"
30982         log " -result- count: $count with max: $max, expecting: $expect_count"
30983
30984         [[ $count -eq expect_count ]] ||
30985                 error "Create count not set to max precreate."
30986 }
30987 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30988
30989 test_831() {
30990         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30991                 skip "Need MDS version 2.14.56"
30992
30993         local sync_changes=$(do_facet $SINGLEMDS \
30994                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30995
30996         [ "$sync_changes" -gt 100 ] &&
30997                 skip "Sync changes $sync_changes > 100 already"
30998
30999         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31000
31001         $LFS mkdir -i 0 $DIR/$tdir
31002         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31003
31004         save_lustre_params mds1 \
31005                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31006         save_lustre_params mds1 \
31007                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31008
31009         do_facet mds1 "$LCTL set_param -n \
31010                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31011                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31012         stack_trap "restore_lustre_params < $p" EXIT
31013
31014         createmany -o $DIR/$tdir/f- 1000
31015         unlinkmany $DIR/$tdir/f- 1000 &
31016         local UNLINK_PID=$!
31017
31018         while sleep 1; do
31019                 sync_changes=$(do_facet mds1 \
31020                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31021                 # the check in the code is racy, fail the test
31022                 # if the value above the limit by 10.
31023                 [ $sync_changes -gt 110 ] && {
31024                         kill -2 $UNLINK_PID
31025                         wait
31026                         error "osp changes throttling failed, $sync_changes>110"
31027                 }
31028                 kill -0 $UNLINK_PID 2> /dev/null || break
31029         done
31030         wait
31031 }
31032 run_test 831 "throttling unlink/setattr queuing on OSP"
31033
31034 test_832() {
31035         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31036         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31037                 skip "Need MDS version 2.15.52+"
31038         is_rmentry_supported || skip "rm_entry not supported"
31039
31040         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31041         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31042         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31043                 error "mkdir remote_dir failed"
31044         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31045                 error "mkdir striped_dir failed"
31046         touch $DIR/$tdir/file || error "touch file failed"
31047         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31048         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31049 }
31050 run_test 832 "lfs rm_entry"
31051
31052 test_833() {
31053         local file=$DIR/$tfile
31054
31055         stack_trap "rm -f $file" EXIT
31056         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31057
31058         local wpid
31059         local rpid
31060         local rpid2
31061
31062         # Buffered I/O write
31063         (
31064                 while [ ! -e $DIR/sanity.833.lck ]; do
31065                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31066                                 error "failed to write $file"
31067                         sleep 0.$((RANDOM % 4 + 1))
31068                 done
31069         )&
31070         wpid=$!
31071
31072         # Buffered I/O read
31073         (
31074                 while [ ! -e $DIR/sanity.833.lck ]; do
31075                         dd if=$file of=/dev/null bs=1M count=50 ||
31076                                 error "failed to read $file"
31077                         sleep 0.$((RANDOM % 4 + 1))
31078                 done
31079         )&
31080         rpid=$!
31081
31082         # Direct I/O read
31083         (
31084                 while [ ! -e $DIR/sanity.833.lck ]; do
31085                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31086                                 error "failed to read $file in direct I/O mode"
31087                         sleep 0.$((RANDOM % 4 + 1))
31088                 done
31089         )&
31090         rpid2=$!
31091
31092         sleep 30
31093         touch $DIR/sanity.833.lck
31094         wait $wpid || error "$?: buffered write failed"
31095         wait $rpid || error "$?: buffered read failed"
31096         wait $rpid2 || error "$?: direct read failed"
31097 }
31098 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31099
31100 #
31101 # tests that do cleanup/setup should be run at the end
31102 #
31103
31104 test_900() {
31105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31106         local ls
31107
31108         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31109         $LCTL set_param fail_loc=0x903
31110
31111         cancel_lru_locks MGC
31112
31113         FAIL_ON_ERROR=true cleanup
31114         FAIL_ON_ERROR=true setup
31115 }
31116 run_test 900 "umount should not race with any mgc requeue thread"
31117
31118 # LUS-6253/LU-11185
31119 test_901() {
31120         local old
31121         local count
31122         local oldc
31123         local newc
31124         local olds
31125         local news
31126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31127
31128         # some get_param have a bug to handle dot in param name
31129         cancel_lru_locks MGC
31130         old=$(mount -t lustre | wc -l)
31131         # 1 config+sptlrpc
31132         # 2 params
31133         # 3 nodemap
31134         # 4 IR
31135         old=$((old * 4))
31136         oldc=0
31137         count=0
31138         while [ $old -ne $oldc ]; do
31139                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31140                 sleep 1
31141                 ((count++))
31142                 if [ $count -ge $TIMEOUT ]; then
31143                         error "too large timeout"
31144                 fi
31145         done
31146         umount_client $MOUNT || error "umount failed"
31147         mount_client $MOUNT || error "mount failed"
31148         cancel_lru_locks MGC
31149         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31150
31151         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31152
31153         return 0
31154 }
31155 run_test 901 "don't leak a mgc lock on client umount"
31156
31157 # LU-13377
31158 test_902() {
31159         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31160                 skip "client does not have LU-13377 fix"
31161         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31162         $LCTL set_param fail_loc=0x1415
31163         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31164         cancel_lru_locks osc
31165         rm -f $DIR/$tfile
31166 }
31167 run_test 902 "test short write doesn't hang lustre"
31168
31169 # LU-14711
31170 test_903() {
31171         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31172         echo "blah" > $DIR/${tfile}-2
31173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31174         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31175         $LCTL set_param fail_loc=0x417 fail_val=20
31176
31177         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31178         sleep 1 # To start the destroy
31179         wait_destroy_complete 150 || error "Destroy taking too long"
31180         cat $DIR/$tfile > /dev/null || error "Evicted"
31181 }
31182 run_test 903 "Test long page discard does not cause evictions"
31183
31184 test_904() {
31185         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31186         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31187                 grep -q project || skip "skip project quota not supported"
31188
31189         local testfile="$DIR/$tdir/$tfile"
31190         local xattr="trusted.projid"
31191         local projid
31192         local mdts=$(comma_list $(mdts_nodes))
31193         local saved=$(do_facet mds1 $LCTL get_param -n \
31194                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31195
31196         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31197         stack_trap "do_nodes $mdts $LCTL set_param \
31198                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31199
31200         mkdir -p $DIR/$tdir
31201         touch $testfile
31202         #hide projid xattr on server
31203         $LFS project -p 1 $testfile ||
31204                 error "set $testfile project id failed"
31205         getfattr -m - $testfile | grep $xattr &&
31206                 error "do not show trusted.projid when disabled on server"
31207         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31208         #should be hidden when projid is 0
31209         $LFS project -p 0 $testfile ||
31210                 error "set $testfile project id failed"
31211         getfattr -m - $testfile | grep $xattr &&
31212                 error "do not show trusted.projid with project ID 0"
31213
31214         #still can getxattr explicitly
31215         projid=$(getfattr -n $xattr $testfile |
31216                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31217         [ $projid == "0" ] ||
31218                 error "projid expected 0 not $projid"
31219
31220         #set the projid via setxattr
31221         setfattr -n $xattr -v "1000" $testfile ||
31222                 error "setattr failed with $?"
31223         projid=($($LFS project $testfile))
31224         [ ${projid[0]} == "1000" ] ||
31225                 error "projid expected 1000 not $projid"
31226
31227         #check the new projid via getxattr
31228         $LFS project -p 1001 $testfile ||
31229                 error "set $testfile project id failed"
31230         getfattr -m - $testfile | grep $xattr ||
31231                 error "should show trusted.projid when project ID != 0"
31232         projid=$(getfattr -n $xattr $testfile |
31233                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31234         [ $projid == "1001" ] ||
31235                 error "projid expected 1001 not $projid"
31236
31237         #try to set invalid projid
31238         setfattr -n $xattr -v "4294967295" $testfile &&
31239                 error "set invalid projid should fail"
31240
31241         #remove the xattr means setting projid to 0
31242         setfattr -x $xattr $testfile ||
31243                 error "setfattr failed with $?"
31244         projid=($($LFS project $testfile))
31245         [ ${projid[0]} == "0" ] ||
31246                 error "projid expected 0 not $projid"
31247
31248         #should be hidden when parent has inherit flag and same projid
31249         $LFS project -srp 1002 $DIR/$tdir ||
31250                 error "set $tdir project id failed"
31251         getfattr -m - $testfile | grep $xattr &&
31252                 error "do not show trusted.projid with inherit flag"
31253
31254         #still can getxattr explicitly
31255         projid=$(getfattr -n $xattr $testfile |
31256                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31257         [ $projid == "1002" ] ||
31258                 error "projid expected 1002 not $projid"
31259 }
31260 run_test 904 "virtual project ID xattr"
31261
31262 # LU-8582
31263 test_905() {
31264         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31265                 skip "need OST version >= 2.15.50.220 for fail_loc"
31266
31267         remote_ost_nodsh && skip "remote OST with nodsh"
31268         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31269
31270         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31271
31272         #define OBD_FAIL_OST_OPCODE 0x253
31273         # OST_LADVISE = 21
31274         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31275         $LFS ladvise -a willread $DIR/$tfile &&
31276                 error "unexpected success of ladvise with fault injection"
31277         $LFS ladvise -a willread $DIR/$tfile |&
31278                 grep -q "Operation not supported"
31279         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31280 }
31281 run_test 905 "bad or new opcode should not stuck client"
31282
31283 test_906() {
31284         grep -q io_uring_setup /proc/kallsyms ||
31285                 skip "Client OS does not support io_uring I/O engine"
31286         io_uring_probe || skip "kernel does not support io_uring fully"
31287         which fio || skip_env "no fio installed"
31288         fio --enghelp | grep -q io_uring ||
31289                 skip_env "fio does not support io_uring I/O engine"
31290
31291         local file=$DIR/$tfile
31292         local ioengine="io_uring"
31293         local numjobs=2
31294         local size=50M
31295
31296         fio --name=seqwrite --ioengine=$ioengine        \
31297                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31298                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31299                 error "fio seqwrite $file failed"
31300
31301         fio --name=seqread --ioengine=$ioengine \
31302                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31303                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31304                 error "fio seqread $file failed"
31305
31306         rm -f $file || error "rm -f $file failed"
31307 }
31308 run_test 906 "Simple test for io_uring I/O engine via fio"
31309
31310 test_907() {
31311         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31312
31313         # set stripe size to max rpc size
31314         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31315         $LFS getstripe $DIR/$tfile
31316 #define OBD_FAIL_OST_EROFS               0x216
31317         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31318
31319         local bs=$((max_pages * PAGE_SIZE / 16))
31320
31321         # write full one stripe and one block
31322         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31323
31324         rm $DIR/$tfile || error "rm failed"
31325 }
31326 run_test 907 "write rpc error during unlink"
31327
31328 complete_test $SECONDS
31329 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31330 check_and_cleanup_lustre
31331 if [ "$I_MOUNTED" != "yes" ]; then
31332         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31333 fi
31334 exit_status