Whamcloud - gitweb
6598498a90a9d0b660d5914180bb89d94b70fb57
[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         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11502                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11503
11504         echo "Cancel LRU locks on lustre client to flush the client cache"
11505         cancel_lru_locks osc
11506         echo Enable read-ahead with ${ra_MB}MB
11507         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11508
11509         echo "Reading the test file $file with read-ahead enabled"
11510         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11511                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11512
11513         echo "read-ahead disabled time read $raOFF"
11514         echo "read-ahead enabled time read $raON"
11515
11516         rm -f $file
11517         wait_delete_completed
11518
11519         # use awk for this check instead of bash because it handles decimals
11520         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11521                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11522 }
11523 run_test 101d "file read with and without read-ahead enabled"
11524
11525 test_101e() {
11526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11527
11528         local file=$DIR/$tfile
11529         local size_KB=500  #KB
11530         local count=100
11531         local bsize=1024
11532
11533         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11534         local need_KB=$((count * size_KB))
11535         [[ $free_KB -le $need_KB ]] &&
11536                 skip_env "Need free space $need_KB, have $free_KB"
11537
11538         echo "Creating $count ${size_KB}K test files"
11539         for ((i = 0; i < $count; i++)); do
11540                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11541         done
11542
11543         echo "Cancel LRU locks on lustre client to flush the client cache"
11544         cancel_lru_locks $OSC
11545
11546         echo "Reset readahead stats"
11547         $LCTL set_param -n llite.*.read_ahead_stats=0
11548
11549         for ((i = 0; i < $count; i++)); do
11550                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11551         done
11552
11553         $LCTL get_param llite.*.max_cached_mb
11554         $LCTL get_param llite.*.read_ahead_stats
11555         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11556                      get_named_value 'misses' | calc_sum)
11557
11558         for ((i = 0; i < $count; i++)); do
11559                 rm -rf $file.$i 2>/dev/null
11560         done
11561
11562         #10000 means 20% reads are missing in readahead
11563         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11564 }
11565 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11566
11567 test_101f() {
11568         which iozone || skip_env "no iozone installed"
11569
11570         local old_debug=$($LCTL get_param debug)
11571         old_debug=${old_debug#*=}
11572         $LCTL set_param debug="reada mmap"
11573
11574         # create a test file
11575         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11576
11577         echo Cancel LRU locks on lustre client to flush the client cache
11578         cancel_lru_locks osc
11579
11580         echo Reset readahead stats
11581         $LCTL set_param -n llite.*.read_ahead_stats=0
11582
11583         echo mmap read the file with small block size
11584         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11585                 > /dev/null 2>&1
11586
11587         echo checking missing pages
11588         $LCTL get_param llite.*.read_ahead_stats
11589         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11590                         get_named_value 'misses' | calc_sum)
11591
11592         $LCTL set_param debug="$old_debug"
11593         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11594         rm -f $DIR/$tfile
11595 }
11596 run_test 101f "check mmap read performance"
11597
11598 test_101g_brw_size_test() {
11599         local mb=$1
11600         local pages=$((mb * 1048576 / PAGE_SIZE))
11601         local file=$DIR/$tfile
11602
11603         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11604                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11605         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11606                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11607                         return 2
11608         done
11609
11610         stack_trap "rm -f $file" EXIT
11611         $LCTL set_param -n osc.*.rpc_stats=0
11612
11613         # 10 RPCs should be enough for the test
11614         local count=10
11615         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11616                 { error "dd write ${mb} MB blocks failed"; return 3; }
11617         cancel_lru_locks osc
11618         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11619                 { error "dd write ${mb} MB blocks failed"; return 4; }
11620
11621         # calculate number of full-sized read and write RPCs
11622         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11623                 sed -n '/pages per rpc/,/^$/p' |
11624                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11625                 END { print reads,writes }'))
11626         # allow one extra full-sized read RPC for async readahead
11627         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11628                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11629         [[ ${rpcs[1]} == $count ]] ||
11630                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11631 }
11632
11633 test_101g() {
11634         remote_ost_nodsh && skip "remote OST with nodsh"
11635
11636         local rpcs
11637         local osts=$(get_facets OST)
11638         local list=$(comma_list $(osts_nodes))
11639         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11640         local brw_size="obdfilter.*.brw_size"
11641
11642         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11643
11644         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11645
11646         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11647                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11648                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11649            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11650                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11651                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11652
11653                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11654                         suffix="M"
11655
11656                 if [[ $orig_mb -lt 16 ]]; then
11657                         save_lustre_params $osts "$brw_size" > $p
11658                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11659                                 error "set 16MB RPC size failed"
11660
11661                         echo "remount client to enable new RPC size"
11662                         remount_client $MOUNT || error "remount_client failed"
11663                 fi
11664
11665                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11666                 # should be able to set brw_size=12, but no rpc_stats for that
11667                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11668         fi
11669
11670         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11671
11672         if [[ $orig_mb -lt 16 ]]; then
11673                 restore_lustre_params < $p
11674                 remount_client $MOUNT || error "remount_client restore failed"
11675         fi
11676
11677         rm -f $p $DIR/$tfile
11678 }
11679 run_test 101g "Big bulk(4/16 MiB) readahead"
11680
11681 test_101h() {
11682         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11683
11684         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11685                 error "dd 70M file failed"
11686         echo Cancel LRU locks on lustre client to flush the client cache
11687         cancel_lru_locks osc
11688
11689         echo "Reset readahead stats"
11690         $LCTL set_param -n llite.*.read_ahead_stats 0
11691
11692         echo "Read 10M of data but cross 64M bundary"
11693         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11694         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11695                      get_named_value 'misses' | calc_sum)
11696         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11697         rm -f $p $DIR/$tfile
11698 }
11699 run_test 101h "Readahead should cover current read window"
11700
11701 test_101i() {
11702         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11703                 error "dd 10M file failed"
11704
11705         local max_per_file_mb=$($LCTL get_param -n \
11706                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11707         cancel_lru_locks osc
11708         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11709         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11710                 error "set max_read_ahead_per_file_mb to 1 failed"
11711
11712         echo "Reset readahead stats"
11713         $LCTL set_param llite.*.read_ahead_stats=0
11714
11715         dd if=$DIR/$tfile of=/dev/null bs=2M
11716
11717         $LCTL get_param llite.*.read_ahead_stats
11718         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11719                      awk '/misses/ { print $2 }')
11720         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11721         rm -f $DIR/$tfile
11722 }
11723 run_test 101i "allow current readahead to exceed reservation"
11724
11725 test_101j() {
11726         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11727                 error "setstripe $DIR/$tfile failed"
11728         local file_size=$((1048576 * 16))
11729         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11730         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11731
11732         echo Disable read-ahead
11733         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11734
11735         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11736         for blk in $PAGE_SIZE 1048576 $file_size; do
11737                 cancel_lru_locks osc
11738                 echo "Reset readahead stats"
11739                 $LCTL set_param -n llite.*.read_ahead_stats=0
11740                 local count=$(($file_size / $blk))
11741                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11742                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11743                              get_named_value 'failed.to.fast.read' | calc_sum)
11744                 $LCTL get_param -n llite.*.read_ahead_stats
11745                 [ $miss -eq $count ] || error "expected $count got $miss"
11746         done
11747
11748         rm -f $p $DIR/$tfile
11749 }
11750 run_test 101j "A complete read block should be submitted when no RA"
11751
11752 test_readahead_base() {
11753         local file=$DIR/$tfile
11754         local size=$1
11755         local iosz
11756         local ramax
11757         local ranum
11758
11759         $LCTL set_param -n llite.*.read_ahead_stats=0
11760         # The first page is not accounted into readahead
11761         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11762         iosz=$(((size + 1048575) / 1048576 * 1048576))
11763         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11764
11765         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11766         fallocate -l $size $file || error "failed to fallocate $file"
11767         cancel_lru_locks osc
11768         $MULTIOP $file or${iosz}c || error "failed to read $file"
11769         $LCTL get_param -n llite.*.read_ahead_stats
11770         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11771                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11772         (( $ranum <= $ramax )) ||
11773                 error "read-ahead pages is $ranum more than $ramax"
11774         rm -rf $file || error "failed to remove $file"
11775 }
11776
11777 test_101m()
11778 {
11779         local file=$DIR/$tfile
11780         local ramax
11781         local ranum
11782         local size
11783         local iosz
11784
11785         check_set_fallocate_or_skip
11786         stack_trap "rm -f $file" EXIT
11787
11788         test_readahead_base 4096
11789
11790         # file size: 16K = 16384
11791         test_readahead_base 16384
11792         test_readahead_base 16385
11793         test_readahead_base 16383
11794
11795         # file size: 1M + 1 = 1048576 + 1
11796         test_readahead_base 1048577
11797         # file size: 1M + 16K
11798         test_readahead_base $((1048576 + 16384))
11799
11800         # file size: stripe_size * (stripe_count - 1) + 16K
11801         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11802         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11803         # file size: stripe_size * stripe_count + 16K
11804         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11805         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11806         # file size: 2 * stripe_size * stripe_count + 16K
11807         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11808         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11809 }
11810 run_test 101m "read ahead for small file and last stripe of the file"
11811
11812 setup_test102() {
11813         test_mkdir $DIR/$tdir
11814         chown $RUNAS_ID $DIR/$tdir
11815         STRIPE_SIZE=65536
11816         STRIPE_OFFSET=1
11817         STRIPE_COUNT=$OSTCOUNT
11818         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11819
11820         trap cleanup_test102 EXIT
11821         cd $DIR
11822         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11823         cd $DIR/$tdir
11824         for num in 1 2 3 4; do
11825                 for count in $(seq 1 $STRIPE_COUNT); do
11826                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11827                                 local size=`expr $STRIPE_SIZE \* $num`
11828                                 local file=file"$num-$idx-$count"
11829                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11830                         done
11831                 done
11832         done
11833
11834         cd $DIR
11835         $1 tar cf $TMP/f102.tar $tdir --xattrs
11836 }
11837
11838 cleanup_test102() {
11839         trap 0
11840         rm -f $TMP/f102.tar
11841         rm -rf $DIR/d0.sanity/d102
11842 }
11843
11844 test_102a() {
11845         [ "$UID" != 0 ] && skip "must run as root"
11846         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11847                 skip_env "must have user_xattr"
11848
11849         [ -z "$(which setfattr 2>/dev/null)" ] &&
11850                 skip_env "could not find setfattr"
11851
11852         local testfile=$DIR/$tfile
11853
11854         touch $testfile
11855         echo "set/get xattr..."
11856         setfattr -n trusted.name1 -v value1 $testfile ||
11857                 error "setfattr -n trusted.name1=value1 $testfile failed"
11858         getfattr -n trusted.name1 $testfile 2> /dev/null |
11859           grep "trusted.name1=.value1" ||
11860                 error "$testfile missing trusted.name1=value1"
11861
11862         setfattr -n user.author1 -v author1 $testfile ||
11863                 error "setfattr -n user.author1=author1 $testfile failed"
11864         getfattr -n user.author1 $testfile 2> /dev/null |
11865           grep "user.author1=.author1" ||
11866                 error "$testfile missing trusted.author1=author1"
11867
11868         echo "listxattr..."
11869         setfattr -n trusted.name2 -v value2 $testfile ||
11870                 error "$testfile unable to set trusted.name2"
11871         setfattr -n trusted.name3 -v value3 $testfile ||
11872                 error "$testfile unable to set trusted.name3"
11873         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11874             grep "trusted.name" | wc -l) -eq 3 ] ||
11875                 error "$testfile missing 3 trusted.name xattrs"
11876
11877         setfattr -n user.author2 -v author2 $testfile ||
11878                 error "$testfile unable to set user.author2"
11879         setfattr -n user.author3 -v author3 $testfile ||
11880                 error "$testfile unable to set user.author3"
11881         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11882             grep "user.author" | wc -l) -eq 3 ] ||
11883                 error "$testfile missing 3 user.author xattrs"
11884
11885         echo "remove xattr..."
11886         setfattr -x trusted.name1 $testfile ||
11887                 error "$testfile error deleting trusted.name1"
11888         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11889                 error "$testfile did not delete trusted.name1 xattr"
11890
11891         setfattr -x user.author1 $testfile ||
11892                 error "$testfile error deleting user.author1"
11893         echo "set lustre special xattr ..."
11894         $LFS setstripe -c1 $testfile
11895         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11896                 awk -F "=" '/trusted.lov/ { print $2 }' )
11897         setfattr -n "trusted.lov" -v $lovea $testfile ||
11898                 error "$testfile doesn't ignore setting trusted.lov again"
11899         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11900                 error "$testfile allow setting invalid trusted.lov"
11901         rm -f $testfile
11902 }
11903 run_test 102a "user xattr test =================================="
11904
11905 check_102b_layout() {
11906         local layout="$*"
11907         local testfile=$DIR/$tfile
11908
11909         echo "test layout '$layout'"
11910         $LFS setstripe $layout $testfile || error "setstripe failed"
11911         $LFS getstripe -y $testfile
11912
11913         echo "get/set/list trusted.lov xattr ..." # b=10930
11914         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11915         [[ "$value" =~ "trusted.lov" ]] ||
11916                 error "can't get trusted.lov from $testfile"
11917         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11918                 error "getstripe failed"
11919
11920         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11921
11922         value=$(cut -d= -f2 <<<$value)
11923         # LU-13168: truncated xattr should fail if short lov_user_md header
11924         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11925                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11926         for len in $lens; do
11927                 echo "setfattr $len $testfile.2"
11928                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11929                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11930         done
11931         local stripe_size=$($LFS getstripe -S $testfile.2)
11932         local stripe_count=$($LFS getstripe -c $testfile.2)
11933         [[ $stripe_size -eq 65536 ]] ||
11934                 error "stripe size $stripe_size != 65536"
11935         [[ $stripe_count -eq $stripe_count_orig ]] ||
11936                 error "stripe count $stripe_count != $stripe_count_orig"
11937         rm $testfile $testfile.2
11938 }
11939
11940 test_102b() {
11941         [ -z "$(which setfattr 2>/dev/null)" ] &&
11942                 skip_env "could not find setfattr"
11943         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11944
11945         # check plain layout
11946         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11947
11948         # and also check composite layout
11949         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11950
11951 }
11952 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11953
11954 test_102c() {
11955         [ -z "$(which setfattr 2>/dev/null)" ] &&
11956                 skip_env "could not find setfattr"
11957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11958
11959         # b10930: get/set/list lustre.lov xattr
11960         echo "get/set/list lustre.lov xattr ..."
11961         test_mkdir $DIR/$tdir
11962         chown $RUNAS_ID $DIR/$tdir
11963         local testfile=$DIR/$tdir/$tfile
11964         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11965                 error "setstripe failed"
11966         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11967                 error "getstripe failed"
11968         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11969         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11970
11971         local testfile2=${testfile}2
11972         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11973                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11974
11975         $RUNAS $MCREATE $testfile2
11976         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11977         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11978         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11979         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11980         [ $stripe_count -eq $STRIPECOUNT ] ||
11981                 error "stripe count $stripe_count != $STRIPECOUNT"
11982 }
11983 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11984
11985 compare_stripe_info1() {
11986         local stripe_index_all_zero=true
11987
11988         for num in 1 2 3 4; do
11989                 for count in $(seq 1 $STRIPE_COUNT); do
11990                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11991                                 local size=$((STRIPE_SIZE * num))
11992                                 local file=file"$num-$offset-$count"
11993                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11994                                 [[ $stripe_size -ne $size ]] &&
11995                                     error "$file: size $stripe_size != $size"
11996                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11997                                 # allow fewer stripes to be created, ORI-601
11998                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11999                                     error "$file: count $stripe_count != $count"
12000                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12001                                 [[ $stripe_index -ne 0 ]] &&
12002                                         stripe_index_all_zero=false
12003                         done
12004                 done
12005         done
12006         $stripe_index_all_zero &&
12007                 error "all files are being extracted starting from OST index 0"
12008         return 0
12009 }
12010
12011 have_xattrs_include() {
12012         tar --help | grep -q xattrs-include &&
12013                 echo --xattrs-include="lustre.*"
12014 }
12015
12016 test_102d() {
12017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12019
12020         XINC=$(have_xattrs_include)
12021         setup_test102
12022         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12023         cd $DIR/$tdir/$tdir
12024         compare_stripe_info1
12025 }
12026 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12027
12028 test_102f() {
12029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12030         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12031
12032         XINC=$(have_xattrs_include)
12033         setup_test102
12034         test_mkdir $DIR/$tdir.restore
12035         cd $DIR
12036         tar cf - --xattrs $tdir | tar xf - \
12037                 -C $DIR/$tdir.restore --xattrs $XINC
12038         cd $DIR/$tdir.restore/$tdir
12039         compare_stripe_info1
12040 }
12041 run_test 102f "tar copy files, not keep osts"
12042
12043 grow_xattr() {
12044         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12045                 skip "must have user_xattr"
12046         [ -z "$(which setfattr 2>/dev/null)" ] &&
12047                 skip_env "could not find setfattr"
12048         [ -z "$(which getfattr 2>/dev/null)" ] &&
12049                 skip_env "could not find getfattr"
12050
12051         local xsize=${1:-1024}  # in bytes
12052         local file=$DIR/$tfile
12053         local value="$(generate_string $xsize)"
12054         local xbig=trusted.big
12055         local toobig=$2
12056
12057         touch $file
12058         log "save $xbig on $file"
12059         if [ -z "$toobig" ]
12060         then
12061                 setfattr -n $xbig -v $value $file ||
12062                         error "saving $xbig on $file failed"
12063         else
12064                 setfattr -n $xbig -v $value $file &&
12065                         error "saving $xbig on $file succeeded"
12066                 return 0
12067         fi
12068
12069         local orig=$(get_xattr_value $xbig $file)
12070         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12071
12072         local xsml=trusted.sml
12073         log "save $xsml on $file"
12074         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12075
12076         local new=$(get_xattr_value $xbig $file)
12077         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12078
12079         log "grow $xsml on $file"
12080         setfattr -n $xsml -v "$value" $file ||
12081                 error "growing $xsml on $file failed"
12082
12083         new=$(get_xattr_value $xbig $file)
12084         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12085         log "$xbig still valid after growing $xsml"
12086
12087         rm -f $file
12088 }
12089
12090 test_102h() { # bug 15777
12091         grow_xattr 1024
12092 }
12093 run_test 102h "grow xattr from inside inode to external block"
12094
12095 test_102ha() {
12096         large_xattr_enabled || skip_env "ea_inode feature disabled"
12097
12098         echo "setting xattr of max xattr size: $(max_xattr_size)"
12099         grow_xattr $(max_xattr_size)
12100
12101         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12102         echo "This should fail:"
12103         grow_xattr $(($(max_xattr_size) + 10)) 1
12104 }
12105 run_test 102ha "grow xattr from inside inode to external inode"
12106
12107 test_102i() { # bug 17038
12108         [ -z "$(which getfattr 2>/dev/null)" ] &&
12109                 skip "could not find getfattr"
12110
12111         touch $DIR/$tfile
12112         ln -s $DIR/$tfile $DIR/${tfile}link
12113         getfattr -n trusted.lov $DIR/$tfile ||
12114                 error "lgetxattr on $DIR/$tfile failed"
12115         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12116                 grep -i "no such attr" ||
12117                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12118         rm -f $DIR/$tfile $DIR/${tfile}link
12119 }
12120 run_test 102i "lgetxattr test on symbolic link ============"
12121
12122 test_102j() {
12123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12125
12126         XINC=$(have_xattrs_include)
12127         setup_test102 "$RUNAS"
12128         chown $RUNAS_ID $DIR/$tdir
12129         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12130         cd $DIR/$tdir/$tdir
12131         compare_stripe_info1 "$RUNAS"
12132 }
12133 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12134
12135 test_102k() {
12136         [ -z "$(which setfattr 2>/dev/null)" ] &&
12137                 skip "could not find setfattr"
12138
12139         touch $DIR/$tfile
12140         # b22187 just check that does not crash for regular file.
12141         setfattr -n trusted.lov $DIR/$tfile
12142         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12143         local test_kdir=$DIR/$tdir
12144         test_mkdir $test_kdir
12145         local default_size=$($LFS getstripe -S $test_kdir)
12146         local default_count=$($LFS getstripe -c $test_kdir)
12147         local default_offset=$($LFS getstripe -i $test_kdir)
12148         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12149                 error 'dir setstripe failed'
12150         setfattr -n trusted.lov $test_kdir
12151         local stripe_size=$($LFS getstripe -S $test_kdir)
12152         local stripe_count=$($LFS getstripe -c $test_kdir)
12153         local stripe_offset=$($LFS getstripe -i $test_kdir)
12154         [ $stripe_size -eq $default_size ] ||
12155                 error "stripe size $stripe_size != $default_size"
12156         [ $stripe_count -eq $default_count ] ||
12157                 error "stripe count $stripe_count != $default_count"
12158         [ $stripe_offset -eq $default_offset ] ||
12159                 error "stripe offset $stripe_offset != $default_offset"
12160         rm -rf $DIR/$tfile $test_kdir
12161 }
12162 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12163
12164 test_102l() {
12165         [ -z "$(which getfattr 2>/dev/null)" ] &&
12166                 skip "could not find getfattr"
12167
12168         # LU-532 trusted. xattr is invisible to non-root
12169         local testfile=$DIR/$tfile
12170
12171         touch $testfile
12172
12173         echo "listxattr as user..."
12174         chown $RUNAS_ID $testfile
12175         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12176             grep -q "trusted" &&
12177                 error "$testfile trusted xattrs are user visible"
12178
12179         return 0;
12180 }
12181 run_test 102l "listxattr size test =================================="
12182
12183 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12184         local path=$DIR/$tfile
12185         touch $path
12186
12187         listxattr_size_check $path || error "listattr_size_check $path failed"
12188 }
12189 run_test 102m "Ensure listxattr fails on small bufffer ========"
12190
12191 cleanup_test102
12192
12193 getxattr() { # getxattr path name
12194         # Return the base64 encoding of the value of xattr name on path.
12195         local path=$1
12196         local name=$2
12197
12198         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12199         # file: $path
12200         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12201         #
12202         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12203
12204         getfattr --absolute-names --encoding=base64 --name=$name $path |
12205                 awk -F= -v name=$name '$1 == name {
12206                         print substr($0, index($0, "=") + 1);
12207         }'
12208 }
12209
12210 test_102n() { # LU-4101 mdt: protect internal xattrs
12211         [ -z "$(which setfattr 2>/dev/null)" ] &&
12212                 skip "could not find setfattr"
12213         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12214         then
12215                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12216         fi
12217
12218         local file0=$DIR/$tfile.0
12219         local file1=$DIR/$tfile.1
12220         local xattr0=$TMP/$tfile.0
12221         local xattr1=$TMP/$tfile.1
12222         local namelist="lov lma lmv link fid version som hsm"
12223         local name
12224         local value
12225
12226         rm -rf $file0 $file1 $xattr0 $xattr1
12227         touch $file0 $file1
12228
12229         # Get 'before' xattrs of $file1.
12230         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12231
12232         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12233                 namelist+=" lfsck_namespace"
12234         for name in $namelist; do
12235                 # Try to copy xattr from $file0 to $file1.
12236                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12237
12238                 setfattr --name=trusted.$name --value="$value" $file1 ||
12239                         error "setxattr 'trusted.$name' failed"
12240
12241                 # Try to set a garbage xattr.
12242                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12243
12244                 if [[ x$name == "xlov" ]]; then
12245                         setfattr --name=trusted.lov --value="$value" $file1 &&
12246                         error "setxattr invalid 'trusted.lov' success"
12247                 else
12248                         setfattr --name=trusted.$name --value="$value" $file1 ||
12249                                 error "setxattr invalid 'trusted.$name' failed"
12250                 fi
12251
12252                 # Try to remove the xattr from $file1. We don't care if this
12253                 # appears to succeed or fail, we just don't want there to be
12254                 # any changes or crashes.
12255                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12256         done
12257
12258         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12259         then
12260                 name="lfsck_ns"
12261                 # Try to copy xattr from $file0 to $file1.
12262                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12263
12264                 setfattr --name=trusted.$name --value="$value" $file1 ||
12265                         error "setxattr 'trusted.$name' failed"
12266
12267                 # Try to set a garbage xattr.
12268                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12269
12270                 setfattr --name=trusted.$name --value="$value" $file1 ||
12271                         error "setxattr 'trusted.$name' failed"
12272
12273                 # Try to remove the xattr from $file1. We don't care if this
12274                 # appears to succeed or fail, we just don't want there to be
12275                 # any changes or crashes.
12276                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12277         fi
12278
12279         # Get 'after' xattrs of file1.
12280         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12281
12282         if ! diff $xattr0 $xattr1; then
12283                 error "before and after xattrs of '$file1' differ"
12284         fi
12285
12286         rm -rf $file0 $file1 $xattr0 $xattr1
12287
12288         return 0
12289 }
12290 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12291
12292 test_102p() { # LU-4703 setxattr did not check ownership
12293         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12294                 skip "MDS needs to be at least 2.5.56"
12295
12296         local testfile=$DIR/$tfile
12297
12298         touch $testfile
12299
12300         echo "setfacl as user..."
12301         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12302         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12303
12304         echo "setfattr as user..."
12305         setfacl -m "u:$RUNAS_ID:---" $testfile
12306         $RUNAS setfattr -x system.posix_acl_access $testfile
12307         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12308 }
12309 run_test 102p "check setxattr(2) correctly fails without permission"
12310
12311 test_102q() {
12312         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12313                 skip "MDS needs to be at least 2.6.92"
12314
12315         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12316 }
12317 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12318
12319 test_102r() {
12320         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12321                 skip "MDS needs to be at least 2.6.93"
12322
12323         touch $DIR/$tfile || error "touch"
12324         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12325         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12326         rm $DIR/$tfile || error "rm"
12327
12328         #normal directory
12329         mkdir -p $DIR/$tdir || error "mkdir"
12330         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12331         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12332         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12333                 error "$testfile error deleting user.author1"
12334         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12335                 grep "user.$(basename $tdir)" &&
12336                 error "$tdir did not delete user.$(basename $tdir)"
12337         rmdir $DIR/$tdir || error "rmdir"
12338
12339         #striped directory
12340         test_mkdir $DIR/$tdir
12341         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12342         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12343         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12344                 error "$testfile error deleting user.author1"
12345         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12346                 grep "user.$(basename $tdir)" &&
12347                 error "$tdir did not delete user.$(basename $tdir)"
12348         rmdir $DIR/$tdir || error "rm striped dir"
12349 }
12350 run_test 102r "set EAs with empty values"
12351
12352 test_102s() {
12353         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12354                 skip "MDS needs to be at least 2.11.52"
12355
12356         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12357
12358         save_lustre_params client "llite.*.xattr_cache" > $save
12359
12360         for cache in 0 1; do
12361                 lctl set_param llite.*.xattr_cache=$cache
12362
12363                 rm -f $DIR/$tfile
12364                 touch $DIR/$tfile || error "touch"
12365                 for prefix in lustre security system trusted user; do
12366                         # Note getxattr() may fail with 'Operation not
12367                         # supported' or 'No such attribute' depending
12368                         # on prefix and cache.
12369                         getfattr -n $prefix.n102s $DIR/$tfile &&
12370                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12371                 done
12372         done
12373
12374         restore_lustre_params < $save
12375 }
12376 run_test 102s "getting nonexistent xattrs should fail"
12377
12378 test_102t() {
12379         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12380                 skip "MDS needs to be at least 2.11.52"
12381
12382         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12383
12384         save_lustre_params client "llite.*.xattr_cache" > $save
12385
12386         for cache in 0 1; do
12387                 lctl set_param llite.*.xattr_cache=$cache
12388
12389                 for buf_size in 0 256; do
12390                         rm -f $DIR/$tfile
12391                         touch $DIR/$tfile || error "touch"
12392                         setfattr -n user.multiop $DIR/$tfile
12393                         $MULTIOP $DIR/$tfile oa$buf_size ||
12394                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12395                 done
12396         done
12397
12398         restore_lustre_params < $save
12399 }
12400 run_test 102t "zero length xattr values handled correctly"
12401
12402 run_acl_subtest()
12403 {
12404         local test=$LUSTRE/tests/acl/$1.test
12405         local tmp=$(mktemp -t $1-XXXXXX).test
12406         local bin=$2
12407         local dmn=$3
12408         local grp=$4
12409         local nbd=$5
12410         export LANG=C
12411
12412
12413         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12414         local sedgroups="-e s/:users/:$grp/g"
12415         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12416
12417         sed $sedusers $sedgroups < $test > $tmp
12418         stack_trap "rm -f $tmp"
12419         [[ -s $tmp ]] || error "sed failed to create test script"
12420
12421         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12422         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12423 }
12424
12425 test_103a() {
12426         [ "$UID" != 0 ] && skip "must run as root"
12427         $GSS && skip_env "could not run under gss"
12428         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12429                 skip_env "must have acl enabled"
12430         which setfacl || skip_env "could not find setfacl"
12431         remote_mds_nodsh && skip "remote MDS with nodsh"
12432
12433         local mdts=$(comma_list $(mdts_nodes))
12434         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12435
12436         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12437         stack_trap "[[ -z \"$saved\" ]] || \
12438                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12439
12440         ACLBIN=${ACLBIN:-"bin"}
12441         ACLDMN=${ACLDMN:-"daemon"}
12442         ACLGRP=${ACLGRP:-"users"}
12443         ACLNBD=${ACLNBD:-"nobody"}
12444
12445         if ! id $ACLBIN ||
12446            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12447                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12448                 ACLBIN=$USER0
12449                 if ! id $ACLBIN ; then
12450                         cat /etc/passwd
12451                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12452                 fi
12453         fi
12454         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12455            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12456                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12457                 ACLDMN=$USER1
12458                 if ! id $ACLDMN ; then
12459                         cat /etc/passwd
12460                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12461                 fi
12462         fi
12463         if ! getent group $ACLGRP; then
12464                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12465                 ACLGRP="$TSTUSR"
12466                 if ! getent group $ACLGRP; then
12467                         echo "cannot find group '$ACLGRP', adding it"
12468                         cat /etc/group
12469                         add_group 60000 $ACLGRP
12470                 fi
12471         fi
12472
12473         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12474         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12475         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12476
12477         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12478                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12479                 ACLGRP="$TSTUSR"
12480                 if ! getent group $ACLGRP; then
12481                         echo "cannot find group '$ACLGRP', adding it"
12482                         cat /etc/group
12483                         add_group 60000 $ACLGRP
12484                 fi
12485                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12486                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12487                         cat /etc/group
12488                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12489                 fi
12490         fi
12491
12492         gpasswd -a $ACLDMN $ACLBIN ||
12493                 error "setting client group failed"             # LU-5641
12494         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12495                 error "setting MDS group failed"                # LU-5641
12496
12497         declare -a identity_old
12498
12499         for ((num = 1; num <= $MDSCOUNT; num++)); do
12500                 switch_identity $num true || identity_old[$num]=$?
12501         done
12502
12503         SAVE_UMASK=$(umask)
12504         umask 0022
12505         mkdir -p $DIR/$tdir
12506         cd $DIR/$tdir
12507
12508         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12509         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12510         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12511         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12512         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12513         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12514         if ! id -u $ACLNBD ||
12515            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12516                 ACLNBD="nfsnobody"
12517                 if ! id -u $ACLNBD; then
12518                         ACLNBD=""
12519                 fi
12520         fi
12521         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12522                 add_group $(id -u $ACLNBD) $ACLNBD
12523                 if ! getent group $ACLNBD; then
12524                         ACLNBD=""
12525                 fi
12526         fi
12527         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12528            [[ -n "$ACLNBD" ]] && which setfattr; then
12529                 run_acl_subtest permissions_xattr \
12530                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12531         elif [[ -z "$ACLNBD" ]]; then
12532                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12533         else
12534                 echo "skip 'permission_xattr' test - missing setfattr command"
12535         fi
12536         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12537
12538         # inheritance test got from HP
12539         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12540         chmod +x make-tree || error "chmod +x failed"
12541         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12542         rm -f make-tree
12543
12544         echo "LU-974 ignore umask when acl is enabled..."
12545         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12546         if [ $MDSCOUNT -ge 2 ]; then
12547                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12548         fi
12549
12550         echo "LU-2561 newly created file is same size as directory..."
12551         if [ "$mds1_FSTYPE" != "zfs" ]; then
12552                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12553         else
12554                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12555         fi
12556
12557         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12558
12559         cd $SAVE_PWD
12560         umask $SAVE_UMASK
12561
12562         for ((num = 1; num <= $MDSCOUNT; num++)); do
12563                 if [[ "${identity_old[$num]}" == 1 ]]; then
12564                         switch_identity $num false || identity_old[$num]=$?
12565                 fi
12566         done
12567 }
12568 run_test 103a "acl test"
12569
12570 test_103b() {
12571         declare -a pids
12572         local U
12573
12574         stack_trap "rm -f $DIR/$tfile.*"
12575         for U in {0..511}; do
12576                 {
12577                 local O=$(printf "%04o" $U)
12578
12579                 umask $(printf "%04o" $((511 ^ $O)))
12580                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12581                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12582
12583                 (( $S == ($O & 0666) )) ||
12584                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12585
12586                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12587                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12588                 (( $S == ($O & 0666) )) ||
12589                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12590
12591                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12592                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12593                 (( $S == ($O & 0666) )) ||
12594                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12595                 rm -f $DIR/$tfile.[smp]$0
12596                 } &
12597                 local pid=$!
12598
12599                 # limit the concurrently running threads to 64. LU-11878
12600                 local idx=$((U % 64))
12601                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12602                 pids[idx]=$pid
12603         done
12604         wait
12605 }
12606 run_test 103b "umask lfs setstripe"
12607
12608 test_103c() {
12609         mkdir -p $DIR/$tdir
12610         cp -rp $DIR/$tdir $DIR/$tdir.bak
12611
12612         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12613                 error "$DIR/$tdir shouldn't contain default ACL"
12614         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12615                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12616         true
12617 }
12618 run_test 103c "'cp -rp' won't set empty acl"
12619
12620 test_103e() {
12621         local numacl
12622         local fileacl
12623         local saved_debug=$($LCTL get_param -n debug)
12624
12625         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12626                 skip "MDS needs to be at least 2.14.52"
12627
12628         large_xattr_enabled || skip_env "ea_inode feature disabled"
12629
12630         mkdir -p $DIR/$tdir
12631         # add big LOV EA to cause reply buffer overflow earlier
12632         $LFS setstripe -C 1000 $DIR/$tdir
12633         lctl set_param mdc.*-mdc*.stats=clear
12634
12635         $LCTL set_param debug=0
12636         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12637         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12638
12639         # add a large number of default ACLs (expect 8000+ for 2.13+)
12640         for U in {2..7000}; do
12641                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12642                         error "Able to add just $U default ACLs"
12643         done
12644         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12645         echo "$numacl default ACLs created"
12646
12647         stat $DIR/$tdir || error "Cannot stat directory"
12648         # check file creation
12649         touch $DIR/$tdir/$tfile ||
12650                 error "failed to create $tfile with $numacl default ACLs"
12651         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12652         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12653         echo "$fileacl ACLs were inherited"
12654         (( $fileacl == $numacl )) ||
12655                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12656         # check that new ACLs creation adds new ACLs to inherited ACLs
12657         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12658                 error "Cannot set new ACL"
12659         numacl=$((numacl + 1))
12660         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12661         (( $fileacl == $numacl )) ||
12662                 error "failed to add new ACL: $fileacl != $numacl as expected"
12663         # adds more ACLs to a file to reach their maximum at 8000+
12664         numacl=0
12665         for U in {20000..25000}; do
12666                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12667                 numacl=$((numacl + 1))
12668         done
12669         echo "Added $numacl more ACLs to the file"
12670         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12671         echo "Total $fileacl ACLs in file"
12672         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12673         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12674         rmdir $DIR/$tdir || error "Cannot remove directory"
12675 }
12676 run_test 103e "inheritance of big amount of default ACLs"
12677
12678 test_103f() {
12679         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12680                 skip "MDS needs to be at least 2.14.51"
12681
12682         large_xattr_enabled || skip_env "ea_inode feature disabled"
12683
12684         # enable changelog to consume more internal MDD buffers
12685         changelog_register
12686
12687         mkdir -p $DIR/$tdir
12688         # add big LOV EA
12689         $LFS setstripe -C 1000 $DIR/$tdir
12690         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12691         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12692         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12693         rmdir $DIR/$tdir || error "Cannot remove directory"
12694 }
12695 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12696
12697 test_104a() {
12698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12699
12700         touch $DIR/$tfile
12701         lfs df || error "lfs df failed"
12702         lfs df -ih || error "lfs df -ih failed"
12703         lfs df -h $DIR || error "lfs df -h $DIR failed"
12704         lfs df -i $DIR || error "lfs df -i $DIR failed"
12705         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12706         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12707
12708         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12709         lctl --device %$OSC deactivate
12710         lfs df || error "lfs df with deactivated OSC failed"
12711         lctl --device %$OSC activate
12712         # wait the osc back to normal
12713         wait_osc_import_ready client ost
12714
12715         lfs df || error "lfs df with reactivated OSC failed"
12716         rm -f $DIR/$tfile
12717 }
12718 run_test 104a "lfs df [-ih] [path] test ========================="
12719
12720 test_104b() {
12721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12722         [ $RUNAS_ID -eq $UID ] &&
12723                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12724
12725         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12726                         grep "Permission denied" | wc -l)))
12727         if [ $denied_cnt -ne 0 ]; then
12728                 error "lfs check servers test failed"
12729         fi
12730 }
12731 run_test 104b "$RUNAS lfs check servers test ===================="
12732
12733 #
12734 # Verify $1 is within range of $2.
12735 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12736 # $1 is <= 2% of $2. Else Fail.
12737 #
12738 value_in_range() {
12739         # Strip all units (M, G, T)
12740         actual=$(echo $1 | tr -d A-Z)
12741         expect=$(echo $2 | tr -d A-Z)
12742
12743         expect_lo=$(($expect * 98 / 100)) # 2% below
12744         expect_hi=$(($expect * 102 / 100)) # 2% above
12745
12746         # permit 2% drift above and below
12747         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12748 }
12749
12750 test_104c() {
12751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12752         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12753
12754         local ost_param="osd-zfs.$FSNAME-OST0000."
12755         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12756         local ofacets=$(get_facets OST)
12757         local mfacets=$(get_facets MDS)
12758         local saved_ost_blocks=
12759         local saved_mdt_blocks=
12760
12761         echo "Before recordsize change"
12762         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12763         df=($(df -h | grep "$MOUNT"$))
12764
12765         # For checking.
12766         echo "lfs output : ${lfs_df[*]}"
12767         echo "df  output : ${df[*]}"
12768
12769         for facet in ${ofacets//,/ }; do
12770                 if [ -z $saved_ost_blocks ]; then
12771                         saved_ost_blocks=$(do_facet $facet \
12772                                 lctl get_param -n $ost_param.blocksize)
12773                         echo "OST Blocksize: $saved_ost_blocks"
12774                 fi
12775                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12776                 do_facet $facet zfs set recordsize=32768 $ost
12777         done
12778
12779         # BS too small. Sufficient for functional testing.
12780         for facet in ${mfacets//,/ }; do
12781                 if [ -z $saved_mdt_blocks ]; then
12782                         saved_mdt_blocks=$(do_facet $facet \
12783                                 lctl get_param -n $mdt_param.blocksize)
12784                         echo "MDT Blocksize: $saved_mdt_blocks"
12785                 fi
12786                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12787                 do_facet $facet zfs set recordsize=32768 $mdt
12788         done
12789
12790         # Give new values chance to reflect change
12791         sleep 2
12792
12793         echo "After recordsize change"
12794         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12795         df_after=($(df -h | grep "$MOUNT"$))
12796
12797         # For checking.
12798         echo "lfs output : ${lfs_df_after[*]}"
12799         echo "df  output : ${df_after[*]}"
12800
12801         # Verify lfs df
12802         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12803                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12804         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12805                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12806         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12807                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12808
12809         # Verify df
12810         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12811                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12812         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12813                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12814         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12815                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12816
12817         # Restore MDT recordize back to original
12818         for facet in ${mfacets//,/ }; do
12819                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12820                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12821         done
12822
12823         # Restore OST recordize back to original
12824         for facet in ${ofacets//,/ }; do
12825                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12826                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12827         done
12828
12829         return 0
12830 }
12831 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12832
12833 test_104d() {
12834         (( $RUNAS_ID != $UID )) ||
12835                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12836
12837         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12838                 skip "lustre version doesn't support lctl dl with non-root"
12839
12840         # debugfs only allows root users to access files, so the
12841         # previous move of the "devices" file to debugfs broke
12842         # "lctl dl" for non-root users. The LU-9680 Netlink
12843         # interface again allows non-root users to list devices.
12844         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12845                 error "lctl dl doesn't work for non root"
12846
12847         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12848         [ "$ost_count" -eq $OSTCOUNT ]  ||
12849                 error "lctl dl reports wrong number of OST devices"
12850
12851         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12852         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12853                 error "lctl dl reports wrong number of MDT devices"
12854 }
12855 run_test 104d "$RUNAS lctl dl test"
12856
12857 test_105a() {
12858         # doesn't work on 2.4 kernels
12859         touch $DIR/$tfile
12860         if $(flock_is_enabled); then
12861                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12862         else
12863                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12864         fi
12865         rm -f $DIR/$tfile
12866 }
12867 run_test 105a "flock when mounted without -o flock test ========"
12868
12869 test_105b() {
12870         touch $DIR/$tfile
12871         if $(flock_is_enabled); then
12872                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12873         else
12874                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12875         fi
12876         rm -f $DIR/$tfile
12877 }
12878 run_test 105b "fcntl when mounted without -o flock test ========"
12879
12880 test_105c() {
12881         touch $DIR/$tfile
12882         if $(flock_is_enabled); then
12883                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12884         else
12885                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12886         fi
12887         rm -f $DIR/$tfile
12888 }
12889 run_test 105c "lockf when mounted without -o flock test"
12890
12891 test_105d() { # bug 15924
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893
12894         test_mkdir $DIR/$tdir
12895         flock_is_enabled || skip_env "mount w/o flock enabled"
12896         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12897         $LCTL set_param fail_loc=0x80000315
12898         flocks_test 2 $DIR/$tdir
12899 }
12900 run_test 105d "flock race (should not freeze) ========"
12901
12902 test_105e() { # bug 22660 && 22040
12903         flock_is_enabled || skip_env "mount w/o flock enabled"
12904
12905         touch $DIR/$tfile
12906         flocks_test 3 $DIR/$tfile
12907 }
12908 run_test 105e "Two conflicting flocks from same process"
12909
12910 test_106() { #bug 10921
12911         test_mkdir $DIR/$tdir
12912         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12913         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12914 }
12915 run_test 106 "attempt exec of dir followed by chown of that dir"
12916
12917 test_107() {
12918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12919
12920         CDIR=`pwd`
12921         local file=core
12922
12923         cd $DIR
12924         rm -f $file
12925
12926         local save_pattern=$(sysctl -n kernel.core_pattern)
12927         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12928         sysctl -w kernel.core_pattern=$file
12929         sysctl -w kernel.core_uses_pid=0
12930
12931         ulimit -c unlimited
12932         sleep 60 &
12933         SLEEPPID=$!
12934
12935         sleep 1
12936
12937         kill -s 11 $SLEEPPID
12938         wait $SLEEPPID
12939         if [ -e $file ]; then
12940                 size=`stat -c%s $file`
12941                 [ $size -eq 0 ] && error "Fail to create core file $file"
12942         else
12943                 error "Fail to create core file $file"
12944         fi
12945         rm -f $file
12946         sysctl -w kernel.core_pattern=$save_pattern
12947         sysctl -w kernel.core_uses_pid=$save_uses_pid
12948         cd $CDIR
12949 }
12950 run_test 107 "Coredump on SIG"
12951
12952 test_110() {
12953         test_mkdir $DIR/$tdir
12954         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12955         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12956                 error "mkdir with 256 char should fail, but did not"
12957         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12958                 error "create with 255 char failed"
12959         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12960                 error "create with 256 char should fail, but did not"
12961
12962         ls -l $DIR/$tdir
12963         rm -rf $DIR/$tdir
12964 }
12965 run_test 110 "filename length checking"
12966
12967 test_116a() { # was previously test_116()
12968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12969         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12970         remote_mds_nodsh && skip "remote MDS with nodsh"
12971
12972         echo -n "Free space priority "
12973         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12974                 head -n1
12975         declare -a AVAIL
12976         free_min_max
12977
12978         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12979         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12980         stack_trap simple_cleanup_common
12981
12982         # Check if we need to generate uneven OSTs
12983         test_mkdir -p $DIR/$tdir/OST${MINI}
12984         local FILL=$((MINV / 4))
12985         local DIFF=$((MAXV - MINV))
12986         local DIFF2=$((DIFF * 100 / MINV))
12987
12988         local threshold=$(do_facet $SINGLEMDS \
12989                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12990         threshold=${threshold%%%}
12991         echo -n "Check for uneven OSTs: "
12992         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12993
12994         if [[ $DIFF2 -gt $threshold ]]; then
12995                 echo "ok"
12996                 echo "Don't need to fill OST$MINI"
12997         else
12998                 # generate uneven OSTs. Write 2% over the QOS threshold value
12999                 echo "no"
13000                 DIFF=$((threshold - DIFF2 + 2))
13001                 DIFF2=$((MINV * DIFF / 100))
13002                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13003                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13004                         error "setstripe failed"
13005                 DIFF=$((DIFF2 / 2048))
13006                 i=0
13007                 while [ $i -lt $DIFF ]; do
13008                         i=$((i + 1))
13009                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13010                                 bs=2M count=1 2>/dev/null
13011                         echo -n .
13012                 done
13013                 echo .
13014                 sync
13015                 sleep_maxage
13016                 free_min_max
13017         fi
13018
13019         DIFF=$((MAXV - MINV))
13020         DIFF2=$((DIFF * 100 / MINV))
13021         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13022         if [ $DIFF2 -gt $threshold ]; then
13023                 echo "ok"
13024         else
13025                 skip "QOS imbalance criteria not met"
13026         fi
13027
13028         MINI1=$MINI
13029         MINV1=$MINV
13030         MAXI1=$MAXI
13031         MAXV1=$MAXV
13032
13033         # now fill using QOS
13034         $LFS setstripe -c 1 $DIR/$tdir
13035         FILL=$((FILL / 200))
13036         if [ $FILL -gt 600 ]; then
13037                 FILL=600
13038         fi
13039         echo "writing $FILL files to QOS-assigned OSTs"
13040         i=0
13041         while [ $i -lt $FILL ]; do
13042                 i=$((i + 1))
13043                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13044                         count=1 2>/dev/null
13045                 echo -n .
13046         done
13047         echo "wrote $i 200k files"
13048         sync
13049         sleep_maxage
13050
13051         echo "Note: free space may not be updated, so measurements might be off"
13052         free_min_max
13053         DIFF2=$((MAXV - MINV))
13054         echo "free space delta: orig $DIFF final $DIFF2"
13055         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13056         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13057         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13058         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13059         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13060         if [[ $DIFF -gt 0 ]]; then
13061                 FILL=$((DIFF2 * 100 / DIFF - 100))
13062                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13063         fi
13064
13065         # Figure out which files were written where
13066         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13067                awk '/'$MINI1': / {print $2; exit}')
13068         echo $UUID
13069         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13070         echo "$MINC files created on smaller OST $MINI1"
13071         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13072                awk '/'$MAXI1': / {print $2; exit}')
13073         echo $UUID
13074         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13075         echo "$MAXC files created on larger OST $MAXI1"
13076         if [[ $MINC -gt 0 ]]; then
13077                 FILL=$((MAXC * 100 / MINC - 100))
13078                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13079         fi
13080         [[ $MAXC -gt $MINC ]] ||
13081                 error_ignore LU-9 "stripe QOS didn't balance free space"
13082 }
13083 run_test 116a "stripe QOS: free space balance ==================="
13084
13085 test_116b() { # LU-2093
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087         remote_mds_nodsh && skip "remote MDS with nodsh"
13088
13089 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13090         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13091                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13092         [ -z "$old_rr" ] && skip "no QOS"
13093         do_facet $SINGLEMDS lctl set_param \
13094                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13095         mkdir -p $DIR/$tdir
13096         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13097         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13098         do_facet $SINGLEMDS lctl set_param fail_loc=0
13099         rm -rf $DIR/$tdir
13100         do_facet $SINGLEMDS lctl set_param \
13101                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13102 }
13103 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13104
13105 test_117() # bug 10891
13106 {
13107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13108
13109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13110         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13111         lctl set_param fail_loc=0x21e
13112         > $DIR/$tfile || error "truncate failed"
13113         lctl set_param fail_loc=0
13114         echo "Truncate succeeded."
13115         rm -f $DIR/$tfile
13116 }
13117 run_test 117 "verify osd extend =========="
13118
13119 NO_SLOW_RESENDCOUNT=4
13120 export OLD_RESENDCOUNT=""
13121 set_resend_count () {
13122         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13123         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13124         lctl set_param -n $PROC_RESENDCOUNT $1
13125         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13126 }
13127
13128 # for reduce test_118* time (b=14842)
13129 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13130
13131 # Reset async IO behavior after error case
13132 reset_async() {
13133         FILE=$DIR/reset_async
13134
13135         # Ensure all OSCs are cleared
13136         $LFS setstripe -c -1 $FILE
13137         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13138         sync
13139         rm $FILE
13140 }
13141
13142 test_118a() #bug 11710
13143 {
13144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13145
13146         reset_async
13147
13148         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13149         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13150         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13151
13152         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13153                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13154                 return 1;
13155         fi
13156         rm -f $DIR/$tfile
13157 }
13158 run_test 118a "verify O_SYNC works =========="
13159
13160 test_118b()
13161 {
13162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13163         remote_ost_nodsh && skip "remote OST with nodsh"
13164
13165         reset_async
13166
13167         #define OBD_FAIL_SRV_ENOENT 0x217
13168         set_nodes_failloc "$(osts_nodes)" 0x217
13169         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13170         RC=$?
13171         set_nodes_failloc "$(osts_nodes)" 0
13172         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13173         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13174                     grep -c writeback)
13175
13176         if [[ $RC -eq 0 ]]; then
13177                 error "Must return error due to dropped pages, rc=$RC"
13178                 return 1;
13179         fi
13180
13181         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13182                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13183                 return 1;
13184         fi
13185
13186         echo "Dirty pages not leaked on ENOENT"
13187
13188         # Due to the above error the OSC will issue all RPCs syncronously
13189         # until a subsequent RPC completes successfully without error.
13190         $MULTIOP $DIR/$tfile Ow4096yc
13191         rm -f $DIR/$tfile
13192
13193         return 0
13194 }
13195 run_test 118b "Reclaim dirty pages on fatal error =========="
13196
13197 test_118c()
13198 {
13199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13200
13201         # for 118c, restore the original resend count, LU-1940
13202         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13203                                 set_resend_count $OLD_RESENDCOUNT
13204         remote_ost_nodsh && skip "remote OST with nodsh"
13205
13206         reset_async
13207
13208         #define OBD_FAIL_OST_EROFS               0x216
13209         set_nodes_failloc "$(osts_nodes)" 0x216
13210
13211         # multiop should block due to fsync until pages are written
13212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13213         MULTIPID=$!
13214         sleep 1
13215
13216         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13217                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13218         fi
13219
13220         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13221                     grep -c writeback)
13222         if [[ $WRITEBACK -eq 0 ]]; then
13223                 error "No page in writeback, writeback=$WRITEBACK"
13224         fi
13225
13226         set_nodes_failloc "$(osts_nodes)" 0
13227         wait $MULTIPID
13228         RC=$?
13229         if [[ $RC -ne 0 ]]; then
13230                 error "Multiop fsync failed, rc=$RC"
13231         fi
13232
13233         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13234         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13235                     grep -c writeback)
13236         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13237                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13238         fi
13239
13240         rm -f $DIR/$tfile
13241         echo "Dirty pages flushed via fsync on EROFS"
13242         return 0
13243 }
13244 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13245
13246 # continue to use small resend count to reduce test_118* time (b=14842)
13247 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13248
13249 test_118d()
13250 {
13251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13252         remote_ost_nodsh && skip "remote OST with nodsh"
13253
13254         reset_async
13255
13256         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13257         set_nodes_failloc "$(osts_nodes)" 0x214
13258         # multiop should block due to fsync until pages are written
13259         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13260         MULTIPID=$!
13261         sleep 1
13262
13263         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13264                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13265         fi
13266
13267         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13268                     grep -c writeback)
13269         if [[ $WRITEBACK -eq 0 ]]; then
13270                 error "No page in writeback, writeback=$WRITEBACK"
13271         fi
13272
13273         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13274         set_nodes_failloc "$(osts_nodes)" 0
13275
13276         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13277         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13278                     grep -c writeback)
13279         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13280                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13281         fi
13282
13283         rm -f $DIR/$tfile
13284         echo "Dirty pages gaurenteed flushed via fsync"
13285         return 0
13286 }
13287 run_test 118d "Fsync validation inject a delay of the bulk =========="
13288
13289 test_118f() {
13290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13291
13292         reset_async
13293
13294         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13295         lctl set_param fail_loc=0x8000040a
13296
13297         # Should simulate EINVAL error which is fatal
13298         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13299         RC=$?
13300         if [[ $RC -eq 0 ]]; then
13301                 error "Must return error due to dropped pages, rc=$RC"
13302         fi
13303
13304         lctl set_param fail_loc=0x0
13305
13306         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13307         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13308         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13309                     grep -c writeback)
13310         if [[ $LOCKED -ne 0 ]]; then
13311                 error "Locked pages remain in cache, locked=$LOCKED"
13312         fi
13313
13314         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13315                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13316         fi
13317
13318         rm -f $DIR/$tfile
13319         echo "No pages locked after fsync"
13320
13321         reset_async
13322         return 0
13323 }
13324 run_test 118f "Simulate unrecoverable OSC side error =========="
13325
13326 test_118g() {
13327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13328
13329         reset_async
13330
13331         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13332         lctl set_param fail_loc=0x406
13333
13334         # simulate local -ENOMEM
13335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13336         RC=$?
13337
13338         lctl set_param fail_loc=0
13339         if [[ $RC -eq 0 ]]; then
13340                 error "Must return error due to dropped pages, rc=$RC"
13341         fi
13342
13343         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13344         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13345         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13346                         grep -c writeback)
13347         if [[ $LOCKED -ne 0 ]]; then
13348                 error "Locked pages remain in cache, locked=$LOCKED"
13349         fi
13350
13351         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13352                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13353         fi
13354
13355         rm -f $DIR/$tfile
13356         echo "No pages locked after fsync"
13357
13358         reset_async
13359         return 0
13360 }
13361 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13362
13363 test_118h() {
13364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13365         remote_ost_nodsh && skip "remote OST with nodsh"
13366
13367         reset_async
13368
13369         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13370         set_nodes_failloc "$(osts_nodes)" 0x20e
13371         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13372         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13373         RC=$?
13374
13375         set_nodes_failloc "$(osts_nodes)" 0
13376         if [[ $RC -eq 0 ]]; then
13377                 error "Must return error due to dropped pages, rc=$RC"
13378         fi
13379
13380         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13381         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13382         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13383                     grep -c writeback)
13384         if [[ $LOCKED -ne 0 ]]; then
13385                 error "Locked pages remain in cache, locked=$LOCKED"
13386         fi
13387
13388         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13389                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13390         fi
13391
13392         rm -f $DIR/$tfile
13393         echo "No pages locked after fsync"
13394
13395         return 0
13396 }
13397 run_test 118h "Verify timeout in handling recoverables errors  =========="
13398
13399 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13400
13401 test_118i() {
13402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13403         remote_ost_nodsh && skip "remote OST with nodsh"
13404
13405         reset_async
13406
13407         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13408         set_nodes_failloc "$(osts_nodes)" 0x20e
13409
13410         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13411         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13412         PID=$!
13413         sleep 5
13414         set_nodes_failloc "$(osts_nodes)" 0
13415
13416         wait $PID
13417         RC=$?
13418         if [[ $RC -ne 0 ]]; then
13419                 error "got error, but should be not, rc=$RC"
13420         fi
13421
13422         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13423         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13424         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13425         if [[ $LOCKED -ne 0 ]]; then
13426                 error "Locked pages remain in cache, locked=$LOCKED"
13427         fi
13428
13429         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13430                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13431         fi
13432
13433         rm -f $DIR/$tfile
13434         echo "No pages locked after fsync"
13435
13436         return 0
13437 }
13438 run_test 118i "Fix error before timeout in recoverable error  =========="
13439
13440 [ "$SLOW" = "no" ] && set_resend_count 4
13441
13442 test_118j() {
13443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13444         remote_ost_nodsh && skip "remote OST with nodsh"
13445
13446         reset_async
13447
13448         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13449         set_nodes_failloc "$(osts_nodes)" 0x220
13450
13451         # return -EIO from OST
13452         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13453         RC=$?
13454         set_nodes_failloc "$(osts_nodes)" 0x0
13455         if [[ $RC -eq 0 ]]; then
13456                 error "Must return error due to dropped pages, rc=$RC"
13457         fi
13458
13459         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13460         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13461         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13462         if [[ $LOCKED -ne 0 ]]; then
13463                 error "Locked pages remain in cache, locked=$LOCKED"
13464         fi
13465
13466         # in recoverable error on OST we want resend and stay until it finished
13467         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13468                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13469         fi
13470
13471         rm -f $DIR/$tfile
13472         echo "No pages locked after fsync"
13473
13474         return 0
13475 }
13476 run_test 118j "Simulate unrecoverable OST side error =========="
13477
13478 test_118k()
13479 {
13480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13481         remote_ost_nodsh && skip "remote OSTs with nodsh"
13482
13483         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13484         set_nodes_failloc "$(osts_nodes)" 0x20e
13485         test_mkdir $DIR/$tdir
13486
13487         for ((i=0;i<10;i++)); do
13488                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13489                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13490                 SLEEPPID=$!
13491                 sleep 0.500s
13492                 kill $SLEEPPID
13493                 wait $SLEEPPID
13494         done
13495
13496         set_nodes_failloc "$(osts_nodes)" 0
13497         rm -rf $DIR/$tdir
13498 }
13499 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13500
13501 test_118l() # LU-646
13502 {
13503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13504
13505         test_mkdir $DIR/$tdir
13506         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13507         rm -rf $DIR/$tdir
13508 }
13509 run_test 118l "fsync dir"
13510
13511 test_118m() # LU-3066
13512 {
13513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13514
13515         test_mkdir $DIR/$tdir
13516         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13517         rm -rf $DIR/$tdir
13518 }
13519 run_test 118m "fdatasync dir ========="
13520
13521 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13522
13523 test_118n()
13524 {
13525         local begin
13526         local end
13527
13528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13529         remote_ost_nodsh && skip "remote OSTs with nodsh"
13530
13531         # Sleep to avoid a cached response.
13532         #define OBD_STATFS_CACHE_SECONDS 1
13533         sleep 2
13534
13535         # Inject a 10 second delay in the OST_STATFS handler.
13536         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13537         set_nodes_failloc "$(osts_nodes)" 0x242
13538
13539         begin=$SECONDS
13540         stat --file-system $MOUNT > /dev/null
13541         end=$SECONDS
13542
13543         set_nodes_failloc "$(osts_nodes)" 0
13544
13545         if ((end - begin > 20)); then
13546             error "statfs took $((end - begin)) seconds, expected 10"
13547         fi
13548 }
13549 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13550
13551 test_119a() # bug 11737
13552 {
13553         BSIZE=$((512 * 1024))
13554         directio write $DIR/$tfile 0 1 $BSIZE
13555         # We ask to read two blocks, which is more than a file size.
13556         # directio will indicate an error when requested and actual
13557         # sizes aren't equeal (a normal situation in this case) and
13558         # print actual read amount.
13559         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13560         if [ "$NOB" != "$BSIZE" ]; then
13561                 error "read $NOB bytes instead of $BSIZE"
13562         fi
13563         rm -f $DIR/$tfile
13564 }
13565 run_test 119a "Short directIO read must return actual read amount"
13566
13567 test_119b() # bug 11737
13568 {
13569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13570
13571         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13573         sync
13574         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13575                 error "direct read failed"
13576         rm -f $DIR/$tfile
13577 }
13578 run_test 119b "Sparse directIO read must return actual read amount"
13579
13580 test_119c() # bug 13099
13581 {
13582         BSIZE=1048576
13583         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13584         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13585         rm -f $DIR/$tfile
13586 }
13587 run_test 119c "Testing for direct read hitting hole"
13588
13589 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13590 # Maloo test history
13591
13592 test_119e()
13593 {
13594         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13595                 skip "Need server version at least 2.15.58"
13596         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13597
13598         local stripe_size=$((1024 * 1024)) #1 MiB
13599         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13600         local file_size=$((25 * stripe_size))
13601         local bsizes
13602
13603         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13604         stack_trap "rm -f $DIR/$tfile*"
13605
13606         # Just a bit bigger than the largest size in the test set below
13607         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13608                 error "buffered i/o to create file failed"
13609
13610         # trivial test of unaligned DIO
13611         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13612                 iflag=direct oflag=direct ||
13613                 error "trivial unaligned dio failed"
13614
13615         # Test of disabling unaligned DIO support
13616         $LCTL set_param llite.*.unaligned_dio=0
13617         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13618         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13619         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13620                 iflag=direct oflag=direct &&
13621                 error "unaligned dio succeeded when disabled"
13622         $LCTL set_param llite.*.unaligned_dio=1
13623
13624         # Clean up before next part of test
13625         rm -f $DIR/$tfile.2
13626
13627         if zfs_or_rotational; then
13628                 # DIO on ZFS can take up to 2 seconds per IO
13629                 # rotational is better, but still slow.
13630                 # Limit testing on those media to larger sizes
13631                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13632                         $((stripe_size + 1024))"
13633         else
13634                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13635                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13636                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13637                         $((stripe_size - 1)) $stripe_size \
13638                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13639                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13640         fi
13641
13642         for bs in $bsizes; do
13643                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13644                 echo "Read/write with DIO at size $bs"
13645                 # Read and write with DIO from source to dest
13646                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13647                         iflag=direct oflag=direct ||
13648                         error "dio failed"
13649
13650                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13651                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13652                         error "size incorrect, file copy read/write bsize: $bs"
13653                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13654                         error "files differ, bsize $bs"
13655                 rm -f $DIR/$tfile.2
13656         done
13657 }
13658 run_test 119e "Basic tests of dio read and write at various sizes"
13659
13660 test_119f()
13661 {
13662         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13663
13664         local stripe_size=$((1024 * 1024)) #1 MiB
13665         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13666         local file_size=$((25 * stripe_size))
13667         local bsizes
13668
13669         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13670         stack_trap "rm -f $DIR/$tfile*"
13671
13672         # Just a bit bigger than the largest size in the test set below
13673         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13674                 error "buffered i/o to create file failed"
13675
13676         if zfs_or_rotational; then
13677                 # DIO on ZFS can take up to 2 seconds per IO
13678                 # rotational is better, but still slow.
13679                 # Limit testing on those media to larger sizes
13680                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13681                         $((stripe_size + 1024))"
13682         else
13683                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13684                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13685                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13686                         $((stripe_size - 1)) $stripe_size \
13687                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13688                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13689         fi
13690
13691         for bs in $bsizes; do
13692                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13693                 # Read and write with DIO from source to dest in two
13694                 # threads - should give correct copy of file
13695
13696                 echo "bs: $bs"
13697                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13698                         oflag=direct conv=notrunc &
13699                 pid_dio1=$!
13700                 # Note block size is different here for a more interesting race
13701                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13702                         iflag=direct oflag=direct conv=notrunc &
13703                 pid_dio2=$!
13704                 wait $pid_dio1
13705                 rc1=$?
13706                 wait $pid_dio2
13707                 rc2=$?
13708                 if (( rc1 != 0 )); then
13709                         error "dio copy 1 w/bsize $bs failed: $rc1"
13710                 fi
13711                 if (( rc2 != 0 )); then
13712                         error "dio copy 2 w/bsize $bs failed: $rc2"
13713                 fi
13714
13715
13716                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13717                         error "size incorrect, file copy read/write bsize: $bs"
13718                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13719                         error "files differ, bsize $bs"
13720                 rm -f $DIR/$tfile.2
13721         done
13722 }
13723 run_test 119f "dio vs dio race"
13724
13725 test_119g()
13726 {
13727         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13728
13729         local stripe_size=$((1024 * 1024)) #1 MiB
13730         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13731         local file_size=$((25 * stripe_size))
13732         local bsizes
13733
13734         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13735         stack_trap "rm -f $DIR/$tfile*"
13736
13737         # Just a bit bigger than the largest size in the test set below
13738         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13739                 error "buffered i/o to create file failed"
13740
13741         if zfs_or_rotational; then
13742                 # DIO on ZFS can take up to 2 seconds per IO
13743                 # rotational is better, but still slow.
13744                 # Limit testing on those media to larger sizes
13745                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13746                         $((stripe_size + 1024))"
13747         else
13748                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13749                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13750                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13751                         $((stripe_size - 1)) $stripe_size \
13752                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13753                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13754         fi
13755
13756         for bs in $bsizes; do
13757                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13758                 echo "bs: $bs"
13759                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13760                         oflag=direct conv=notrunc &
13761                 pid_dio1=$!
13762                 # Buffered I/O with similar but not the same block size
13763                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13764                 pid_bio2=$!
13765                 wait $pid_dio1
13766                 rc1=$?
13767                 wait $pid_bio2
13768                 rc2=$?
13769                 if (( rc1 != 0 )); then
13770                         error "dio copy 1 w/bsize $bs failed: $rc1"
13771                 fi
13772                 if (( rc2 != 0 )); then
13773                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13774                 fi
13775
13776                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13777                         error "size incorrect"
13778                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13779                         error "files differ, bsize $bs"
13780                 rm -f $DIR/$tfile.2
13781         done
13782 }
13783 run_test 119g "dio vs buffered I/O race"
13784
13785 test_119h()
13786 {
13787         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13788
13789         local stripe_size=$((1024 * 1024)) #1 MiB
13790         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13791         local file_size=$((25 * stripe_size))
13792         local bsizes
13793
13794         stack_trap "rm -f $DIR/$tfile.*"
13795
13796         if zfs_or_rotational; then
13797                 # DIO on ZFS can take up to 2 seconds per IO
13798                 # rotational is better, but still slow.
13799                 # Limit testing on those media to larger sizes
13800                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13801                         $((stripe_size + 1024))"
13802         else
13803                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13804                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13805                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13806                         $((stripe_size - 1)) $stripe_size \
13807                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13808                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13809         fi
13810
13811         for bs in $bsizes; do
13812                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13813                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13814                 echo "unaligned writes of blocksize: $bs"
13815                 # Write a file with unaligned DIO and regular DIO, and compare
13816                 # them
13817                 # with 'u', multiop randomly unaligns the io from the buffer
13818                 $MULTIOP $DIR/$tfile.1 \
13819                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13820                         error "multiop memory unaligned write failed, $bs"
13821                 $MULTIOP $DIR/$tfile.2 \
13822                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13823                         error "multiop memory aligned write failed, $bs"
13824
13825                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13826                         error "files differ, bsize $bs"
13827                 rm -f $DIR/$tfile.*
13828         done
13829
13830         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13831         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13832                 error "dd to create source file for read failed"
13833
13834         # Just a few quick tests to make sure unaligned DIO reads don't crash
13835         for bs in $bsizes; do
13836
13837                 echo "unaligned reads of blocksize: $bs"
13838                 # with 'u', multiop randomly unaligns the io from the buffer
13839                 $MULTIOP $DIR/$tfile.1 \
13840                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13841                         error "multiop memory unaligned read failed, $bs"
13842
13843         done
13844         rm -f $DIR/$tfile*
13845 }
13846 run_test 119h "basic tests of memory unaligned dio"
13847
13848 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13849 test_119i()
13850 {
13851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13852         which aiocp || skip_env "no aiocp installed"
13853
13854         local stripe_size=$((1024 * 1024)) #1 MiB
13855         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13856         local file_size=$((25 * stripe_size))
13857         local bsizes
13858
13859         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13860         stack_trap "rm -f $DIR/$tfile.*"
13861
13862         # Just a bit bigger than the largest size in the test set below
13863         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13864                 error "buffered i/o to create file failed"
13865
13866         if zfs_or_rotational; then
13867                 # DIO on ZFS can take up to 2 seconds per IO
13868                 # rotational is better, but still slow.
13869                 # Limit testing on those media to larger sizes
13870                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13871                         $((stripe_size + 1024))"
13872         else
13873                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13874                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13875                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13876                         $((stripe_size - 1)) $stripe_size \
13877                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13878                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13879         fi
13880
13881         # Do page aligned and NOT page aligned AIO
13882         for align in 8 512 $((PAGE_SIZE)); do
13883         # Deliberately includes a few aligned sizes
13884         for bs in $bsizes; do
13885                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13886
13887                 echo "bs: $bs, align: $align, file_size $file_size"
13888                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13889                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13890                         error "unaligned aio failed, bs: $bs, align: $align"
13891
13892                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13893                         error "size incorrect"
13894                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13895                         error "files differ"
13896                 rm -f $DIR/$tfile.2
13897         done
13898         done
13899 }
13900 run_test 119i "test unaligned aio at varying sizes"
13901
13902 test_120a() {
13903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13904         remote_mds_nodsh && skip "remote MDS with nodsh"
13905         test_mkdir -i0 -c1 $DIR/$tdir
13906         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13907                 skip_env "no early lock cancel on server"
13908
13909         lru_resize_disable mdc
13910         lru_resize_disable osc
13911         cancel_lru_locks mdc
13912         # asynchronous object destroy at MDT could cause bl ast to client
13913         cancel_lru_locks osc
13914
13915         stat $DIR/$tdir > /dev/null
13916         can1=$(do_facet mds1 \
13917                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13918                awk '/ldlm_cancel/ {print $2}')
13919         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13920                awk '/ldlm_bl_callback/ {print $2}')
13921         test_mkdir -i0 -c1 $DIR/$tdir/d1
13922         can2=$(do_facet mds1 \
13923                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13924                awk '/ldlm_cancel/ {print $2}')
13925         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13926                awk '/ldlm_bl_callback/ {print $2}')
13927         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13928         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13929         lru_resize_enable mdc
13930         lru_resize_enable osc
13931 }
13932 run_test 120a "Early Lock Cancel: mkdir test"
13933
13934 test_120b() {
13935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13936         remote_mds_nodsh && skip "remote MDS with nodsh"
13937         test_mkdir $DIR/$tdir
13938         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13939                 skip_env "no early lock cancel on server"
13940
13941         lru_resize_disable mdc
13942         lru_resize_disable osc
13943         cancel_lru_locks mdc
13944         stat $DIR/$tdir > /dev/null
13945         can1=$(do_facet $SINGLEMDS \
13946                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13947                awk '/ldlm_cancel/ {print $2}')
13948         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13949                awk '/ldlm_bl_callback/ {print $2}')
13950         touch $DIR/$tdir/f1
13951         can2=$(do_facet $SINGLEMDS \
13952                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13953                awk '/ldlm_cancel/ {print $2}')
13954         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13955                awk '/ldlm_bl_callback/ {print $2}')
13956         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13957         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13958         lru_resize_enable mdc
13959         lru_resize_enable osc
13960 }
13961 run_test 120b "Early Lock Cancel: create test"
13962
13963 test_120c() {
13964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13965         remote_mds_nodsh && skip "remote MDS with nodsh"
13966         test_mkdir -i0 -c1 $DIR/$tdir
13967         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13968                 skip "no early lock cancel on server"
13969
13970         lru_resize_disable mdc
13971         lru_resize_disable osc
13972         test_mkdir -i0 -c1 $DIR/$tdir/d1
13973         test_mkdir -i0 -c1 $DIR/$tdir/d2
13974         touch $DIR/$tdir/d1/f1
13975         cancel_lru_locks mdc
13976         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13977         can1=$(do_facet mds1 \
13978                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13979                awk '/ldlm_cancel/ {print $2}')
13980         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13981                awk '/ldlm_bl_callback/ {print $2}')
13982         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13983         can2=$(do_facet mds1 \
13984                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13985                awk '/ldlm_cancel/ {print $2}')
13986         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13987                awk '/ldlm_bl_callback/ {print $2}')
13988         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13989         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13990         lru_resize_enable mdc
13991         lru_resize_enable osc
13992 }
13993 run_test 120c "Early Lock Cancel: link test"
13994
13995 test_120d() {
13996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13997         remote_mds_nodsh && skip "remote MDS with nodsh"
13998         test_mkdir -i0 -c1 $DIR/$tdir
13999         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14000                 skip_env "no early lock cancel on server"
14001
14002         lru_resize_disable mdc
14003         lru_resize_disable osc
14004         touch $DIR/$tdir
14005         cancel_lru_locks mdc
14006         stat $DIR/$tdir > /dev/null
14007         can1=$(do_facet mds1 \
14008                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14009                awk '/ldlm_cancel/ {print $2}')
14010         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14011                awk '/ldlm_bl_callback/ {print $2}')
14012         chmod a+x $DIR/$tdir
14013         can2=$(do_facet mds1 \
14014                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14015                awk '/ldlm_cancel/ {print $2}')
14016         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14017                awk '/ldlm_bl_callback/ {print $2}')
14018         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14019         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14020         lru_resize_enable mdc
14021         lru_resize_enable osc
14022 }
14023 run_test 120d "Early Lock Cancel: setattr test"
14024
14025 test_120e() {
14026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14027         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14028                 skip_env "no early lock cancel on server"
14029         remote_mds_nodsh && skip "remote MDS with nodsh"
14030
14031         local dlmtrace_set=false
14032
14033         test_mkdir -i0 -c1 $DIR/$tdir
14034         lru_resize_disable mdc
14035         lru_resize_disable osc
14036         ! $LCTL get_param debug | grep -q dlmtrace &&
14037                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14038         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14039         cancel_lru_locks mdc
14040         cancel_lru_locks osc
14041         dd if=$DIR/$tdir/f1 of=/dev/null
14042         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14043         # XXX client can not do early lock cancel of OST lock
14044         # during unlink (LU-4206), so cancel osc lock now.
14045         sleep 2
14046         cancel_lru_locks osc
14047         can1=$(do_facet mds1 \
14048                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14049                awk '/ldlm_cancel/ {print $2}')
14050         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14051                awk '/ldlm_bl_callback/ {print $2}')
14052         unlink $DIR/$tdir/f1
14053         sleep 5
14054         can2=$(do_facet mds1 \
14055                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14056                awk '/ldlm_cancel/ {print $2}')
14057         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14058                awk '/ldlm_bl_callback/ {print $2}')
14059         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14060                 $LCTL dk $TMP/cancel.debug.txt
14061         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14062                 $LCTL dk $TMP/blocking.debug.txt
14063         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14064         lru_resize_enable mdc
14065         lru_resize_enable osc
14066 }
14067 run_test 120e "Early Lock Cancel: unlink test"
14068
14069 test_120f() {
14070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14071         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14072                 skip_env "no early lock cancel on server"
14073         remote_mds_nodsh && skip "remote MDS with nodsh"
14074
14075         test_mkdir -i0 -c1 $DIR/$tdir
14076         lru_resize_disable mdc
14077         lru_resize_disable osc
14078         test_mkdir -i0 -c1 $DIR/$tdir/d1
14079         test_mkdir -i0 -c1 $DIR/$tdir/d2
14080         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14081         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14082         cancel_lru_locks mdc
14083         cancel_lru_locks osc
14084         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14085         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14086         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14087         # XXX client can not do early lock cancel of OST lock
14088         # during rename (LU-4206), so cancel osc lock now.
14089         sleep 2
14090         cancel_lru_locks osc
14091         can1=$(do_facet mds1 \
14092                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14093                awk '/ldlm_cancel/ {print $2}')
14094         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14095                awk '/ldlm_bl_callback/ {print $2}')
14096         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14097         sleep 5
14098         can2=$(do_facet mds1 \
14099                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14100                awk '/ldlm_cancel/ {print $2}')
14101         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14102                awk '/ldlm_bl_callback/ {print $2}')
14103         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14104         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14105         lru_resize_enable mdc
14106         lru_resize_enable osc
14107 }
14108 run_test 120f "Early Lock Cancel: rename test"
14109
14110 test_120g() {
14111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14112         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14113                 skip_env "no early lock cancel on server"
14114         remote_mds_nodsh && skip "remote MDS with nodsh"
14115
14116         lru_resize_disable mdc
14117         lru_resize_disable osc
14118         count=10000
14119         echo create $count files
14120         test_mkdir $DIR/$tdir
14121         cancel_lru_locks mdc
14122         cancel_lru_locks osc
14123         t0=$(date +%s)
14124
14125         can0=$(do_facet $SINGLEMDS \
14126                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14127                awk '/ldlm_cancel/ {print $2}')
14128         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14129                awk '/ldlm_bl_callback/ {print $2}')
14130         createmany -o $DIR/$tdir/f $count
14131         sync
14132         can1=$(do_facet $SINGLEMDS \
14133                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14134                awk '/ldlm_cancel/ {print $2}')
14135         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14136                awk '/ldlm_bl_callback/ {print $2}')
14137         t1=$(date +%s)
14138         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14139         echo rm $count files
14140         rm -r $DIR/$tdir
14141         sync
14142         can2=$(do_facet $SINGLEMDS \
14143                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14144                awk '/ldlm_cancel/ {print $2}')
14145         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14146                awk '/ldlm_bl_callback/ {print $2}')
14147         t2=$(date +%s)
14148         echo total: $count removes in $((t2-t1))
14149         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14150         sleep 2
14151         # wait for commitment of removal
14152         lru_resize_enable mdc
14153         lru_resize_enable osc
14154 }
14155 run_test 120g "Early Lock Cancel: performance test"
14156
14157 test_121() { #bug #10589
14158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14159
14160         rm -rf $DIR/$tfile
14161         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14162 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14163         lctl set_param fail_loc=0x310
14164         cancel_lru_locks osc > /dev/null
14165         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14166         lctl set_param fail_loc=0
14167         [[ $reads -eq $writes ]] ||
14168                 error "read $reads blocks, must be $writes blocks"
14169 }
14170 run_test 121 "read cancel race ========="
14171
14172 test_123a_base() { # was test 123, statahead(bug 11401)
14173         local lsx="$1"
14174
14175         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14176
14177         SLOWOK=0
14178         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14179                 log "testing UP system. Performance may be lower than expected."
14180                 SLOWOK=1
14181         fi
14182         running_in_vm && SLOWOK=1
14183
14184         $LCTL set_param mdc.*.batch_stats=0
14185
14186         rm -rf $DIR/$tdir
14187         test_mkdir $DIR/$tdir
14188         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14189         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14190         MULT=10
14191         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14192                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14193
14194                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14195                 lctl set_param -n llite.*.statahead_max 0
14196                 lctl get_param llite.*.statahead_max
14197                 cancel_lru_locks mdc
14198                 cancel_lru_locks osc
14199                 stime=$(date +%s)
14200                 time $lsx $DIR/$tdir | wc -l
14201                 etime=$(date +%s)
14202                 delta=$((etime - stime))
14203                 log "$lsx $i files without statahead: $delta sec"
14204                 lctl set_param llite.*.statahead_max=$max
14205
14206                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14207                          awk '/statahead.wrong:/ { print $NF }')
14208                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14209                 cancel_lru_locks mdc
14210                 cancel_lru_locks osc
14211                 stime=$(date +%s)
14212                 time $lsx $DIR/$tdir | wc -l
14213                 etime=$(date +%s)
14214                 delta_sa=$((etime - stime))
14215                 log "$lsx $i files with statahead: $delta_sa sec"
14216                 lctl get_param -n llite.*.statahead_stats
14217                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14218                          awk '/statahead.wrong:/ { print $NF }')
14219
14220                 [[ $swrong -lt $ewrong ]] &&
14221                         log "statahead was stopped, maybe too many locks held!"
14222                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14223
14224                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14225                         max=$(lctl get_param -n llite.*.statahead_max |
14226                                 head -n 1)
14227                         lctl set_param -n llite.*.statahead_max 0
14228                         lctl get_param llite.*.statahead_max
14229                         cancel_lru_locks mdc
14230                         cancel_lru_locks osc
14231                         stime=$(date +%s)
14232                         time $lsx $DIR/$tdir | wc -l
14233                         etime=$(date +%s)
14234                         delta=$((etime - stime))
14235                         log "$lsx $i files again without statahead: $delta sec"
14236                         lctl set_param llite.*.statahead_max=$max
14237                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14238                                 if [ $SLOWOK -eq 0 ]; then
14239                                         error "$lsx $i files is slower with statahead!"
14240                                 else
14241                                         log "$lsx $i files is slower with statahead!"
14242                                 fi
14243                                 break
14244                         fi
14245                 fi
14246
14247                 [ $delta -gt 20 ] && break
14248                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14249                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14250         done
14251         log "$lsx done"
14252
14253         stime=$(date +%s)
14254         rm -r $DIR/$tdir
14255         sync
14256         etime=$(date +%s)
14257         delta=$((etime - stime))
14258         log "rm -r $DIR/$tdir/: $delta seconds"
14259         log "rm done"
14260         lctl get_param -n llite.*.statahead_stats
14261         $LCTL get_param mdc.*.batch_stats
14262 }
14263
14264 test_123aa() {
14265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14266
14267         test_123a_base "ls -l"
14268 }
14269 run_test 123aa "verify statahead work"
14270
14271 test_123ab() {
14272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14273
14274         statx_supported || skip_env "Test must be statx() syscall supported"
14275
14276         test_123a_base "$STATX -l"
14277 }
14278 run_test 123ab "verify statahead work by using statx"
14279
14280 test_123ac() {
14281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14282
14283         statx_supported || skip_env "Test must be statx() syscall supported"
14284
14285         local rpcs_before
14286         local rpcs_after
14287         local agl_before
14288         local agl_after
14289
14290         cancel_lru_locks $OSC
14291         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14292         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14293                      awk '/agl.total:/ { print $NF }')
14294         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14295         test_123a_base "$STATX --cached=always -D"
14296         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14297                     awk '/agl.total:/ { print $NF }')
14298         [ $agl_before -eq $agl_after ] ||
14299                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14300         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14301         [ $rpcs_after -eq $rpcs_before ] ||
14302                 error "$STATX should not send glimpse RPCs to $OSC"
14303 }
14304 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14305
14306 test_batch_statahead() {
14307         local max=$1
14308         local batch_max=$2
14309         local num=10000
14310         local batch_rpcs
14311         local unbatch_rpcs
14312         local hit_total
14313
14314         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14315         $LCTL set_param mdc.*.batch_stats=0
14316         $LCTL set_param llite.*.statahead_max=$max
14317         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14318         # Verify that batched statahead is faster than one without statahead
14319         test_123a_base "ls -l"
14320
14321         stack_trap "rm -rf $DIR/$tdir" EXIT
14322         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14323         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14324
14325         # unbatched statahead
14326         $LCTL set_param llite.*.statahead_batch_max=0
14327         $LCTL set_param llite.*.statahead_stats=clear
14328         $LCTL set_param mdc.*.stats=clear
14329         cancel_lru_locks mdc
14330         cancel_lru_locks osc
14331         time ls -l $DIR/$tdir | wc -l
14332         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14333         sleep 2
14334         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14335                     awk '/hit.total:/ { print $NF }')
14336         # hit ratio should be larger than 75% (7500).
14337         (( $hit_total > 7500 )) ||
14338                 error "unbatched statahead hit count ($hit_total) is too low"
14339
14340         # batched statahead
14341         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14342         $LCTL set_param llite.*.statahead_stats=clear
14343         $LCTL set_param mdc.*.batch_stats=clear
14344         $LCTL set_param mdc.*.stats=clear
14345         cancel_lru_locks mdc
14346         cancel_lru_locks osc
14347         time ls -l $DIR/$tdir | wc -l
14348         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14349         # wait for statahead thread to quit and update statahead stats
14350         sleep 2
14351         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14352                     awk '/hit.total:/ { print $NF }')
14353         # hit ratio should be larger than 75% (7500).
14354         (( $hit_total > 7500 )) ||
14355                 error "batched statahead hit count ($hit_total) is too low"
14356
14357         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14358         (( $unbatch_rpcs > $batch_rpcs )) ||
14359                 error "batched statahead does not reduce RPC count"
14360         $LCTL get_param mdc.*.batch_stats
14361 }
14362
14363 test_123ad() {
14364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14365
14366         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14367                 skip "Need server version at least 2.15.53"
14368
14369         local max
14370         local batch_max
14371
14372         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14373         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14374
14375         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14376         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14377
14378         test_batch_statahead 32 32
14379         test_batch_statahead 2048 256
14380 }
14381 run_test 123ad "Verify batching statahead works correctly"
14382
14383 test_123b () { # statahead(bug 15027)
14384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14385
14386         test_mkdir $DIR/$tdir
14387         createmany -o $DIR/$tdir/$tfile-%d 1000
14388
14389         cancel_lru_locks mdc
14390         cancel_lru_locks osc
14391
14392 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14393         lctl set_param fail_loc=0x80000803
14394         ls -lR $DIR/$tdir > /dev/null
14395         log "ls done"
14396         lctl set_param fail_loc=0x0
14397         lctl get_param -n llite.*.statahead_stats
14398         rm -r $DIR/$tdir
14399         sync
14400
14401 }
14402 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14403
14404 test_123c() {
14405         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14406
14407         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14408         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14409         touch $DIR/$tdir.1/{1..3}
14410         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14411
14412         remount_client $MOUNT
14413
14414         $MULTIOP $DIR/$tdir.0 Q
14415
14416         # let statahead to complete
14417         ls -l $DIR/$tdir.0 > /dev/null
14418
14419         testid=$(echo $TESTNAME | tr '_' ' ')
14420         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14421                 error "statahead warning" || true
14422 }
14423 run_test 123c "Can not initialize inode warning on DNE statahead"
14424
14425 test_123d() {
14426         local num=100
14427         local swrong
14428         local ewrong
14429
14430         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14431         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14432                 error "setdirstripe $DIR/$tdir failed"
14433         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14434         remount_client $MOUNT
14435         $LCTL get_param llite.*.statahead_max
14436         $LCTL set_param llite.*.statahead_stats=0 ||
14437                 error "clear statahead_stats failed"
14438         swrong=$(lctl get_param -n llite.*.statahead_stats |
14439                  awk '/statahead.wrong:/ { print $NF }')
14440         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14441         # wait for statahead thread finished to update hit/miss stats.
14442         sleep 1
14443         $LCTL get_param -n llite.*.statahead_stats
14444         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14445                  awk '/statahead.wrong:/ { print $NF }')
14446         (( $swrong == $ewrong )) ||
14447                 log "statahead was stopped, maybe too many locks held!"
14448 }
14449 run_test 123d "Statahead on striped directories works correctly"
14450
14451 test_123e() {
14452         local max
14453         local batch_max
14454         local dir=$DIR/$tdir
14455
14456         mkdir $dir || error "mkdir $dir failed"
14457         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14458         stack_trap "rm -rf $dir"
14459
14460         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14461
14462         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14463         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14464         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14465         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14466
14467         $LCTL set_param llite.*.statahead_max=2048
14468         $LCTL set_param llite.*.statahead_batch_max=1024
14469
14470         ls -l $dir
14471         $LCTL get_param mdc.*.batch_stats
14472         $LCTL get_param llite.*.statahead_*
14473 }
14474 run_test 123e "statahead with large wide striping"
14475
14476 test_123f() {
14477         local max
14478         local batch_max
14479         local dir=$DIR/$tdir
14480
14481         mkdir $dir || error "mkdir $dir failed"
14482         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14483         stack_trap "rm -rf $dir"
14484
14485         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14486
14487         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14488         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14489
14490         $LCTL set_param llite.*.statahead_max=64
14491         $LCTL set_param llite.*.statahead_batch_max=64
14492
14493         ls -l $dir
14494         lctl get_param mdc.*.batch_stats
14495         lctl get_param llite.*.statahead_*
14496
14497         $LCTL set_param llite.*.statahead_max=$max
14498         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14499 }
14500 run_test 123f "Retry mechanism with large wide striping files"
14501
14502 test_123g() {
14503         local dir=$DIR/$tdir
14504         local num=1000
14505
14506         mkdir $dir || error "failed to mkdir $dir"
14507         createmany -o $dir/$tfile $num || error "failed creatmany files"
14508         cancel_lru_locks mdc
14509         cancel_lru_locks osc
14510
14511         $LCTL set_param llite.*.statahead_stats=clear
14512         $LCTL set_param mdc.*.batch_stats=clear
14513         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14514                 error "aheadmany $dir with $tfile failed"
14515         wait_update_facet client "pgrep ll_sa" "" 35 ||
14516                 error "ll_sa thread is still running"
14517         $LCTL get_param -n llite.*.statahead_stats
14518         $LCTL get_param -n mdc.*.batch_stats
14519
14520         local count
14521
14522         count=$($LCTL get_param -n llite.*.statahead_stats |
14523                 awk '/hit.total:/ {print $2}')
14524         echo "Hit total: $count"
14525         # Hit ratio should be >= 75%
14526         (( $count > num * 75 / 100)) ||
14527                 error "hit total $count is be > 75% of $num"
14528 }
14529 run_test 123g "Test for stat-ahead advise"
14530
14531 test_124a() {
14532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14533         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14534                 skip_env "no lru resize on server"
14535
14536         local NR=2000
14537
14538         test_mkdir $DIR/$tdir
14539
14540         log "create $NR files at $DIR/$tdir"
14541         createmany -o $DIR/$tdir/f $NR ||
14542                 error "failed to create $NR files in $DIR/$tdir"
14543
14544         cancel_lru_locks mdc
14545         ls -l $DIR/$tdir > /dev/null
14546
14547         local NSDIR=""
14548         local LRU_SIZE=0
14549         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14550                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14551                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14552                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14553                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14554                         log "NSDIR=$NSDIR"
14555                         log "NS=$(basename $NSDIR)"
14556                         break
14557                 fi
14558         done
14559
14560         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14561                 skip "Not enough cached locks created!"
14562         fi
14563         log "LRU=$LRU_SIZE"
14564
14565         local SLEEP=30
14566
14567         # We know that lru resize allows one client to hold $LIMIT locks
14568         # for 10h. After that locks begin to be killed by client.
14569         local MAX_HRS=10
14570         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14571         log "LIMIT=$LIMIT"
14572         if [ $LIMIT -lt $LRU_SIZE ]; then
14573                 skip "Limit is too small $LIMIT"
14574         fi
14575
14576         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14577         # killing locks. Some time was spent for creating locks. This means
14578         # that up to the moment of sleep finish we must have killed some of
14579         # them (10-100 locks). This depends on how fast ther were created.
14580         # Many of them were touched in almost the same moment and thus will
14581         # be killed in groups.
14582         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14583
14584         # Use $LRU_SIZE_B here to take into account real number of locks
14585         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14586         local LRU_SIZE_B=$LRU_SIZE
14587         log "LVF=$LVF"
14588         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14589         log "OLD_LVF=$OLD_LVF"
14590         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14591
14592         # Let's make sure that we really have some margin. Client checks
14593         # cached locks every 10 sec.
14594         SLEEP=$((SLEEP+20))
14595         log "Sleep ${SLEEP} sec"
14596         local SEC=0
14597         while ((SEC<$SLEEP)); do
14598                 echo -n "..."
14599                 sleep 5
14600                 SEC=$((SEC+5))
14601                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14602                 echo -n "$LRU_SIZE"
14603         done
14604         echo ""
14605         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14606         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14607
14608         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14609                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14610                 unlinkmany $DIR/$tdir/f $NR
14611                 return
14612         }
14613
14614         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14615         log "unlink $NR files at $DIR/$tdir"
14616         unlinkmany $DIR/$tdir/f $NR
14617 }
14618 run_test 124a "lru resize ======================================="
14619
14620 get_max_pool_limit()
14621 {
14622         local limit=$($LCTL get_param \
14623                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14624         local max=0
14625         for l in $limit; do
14626                 if [[ $l -gt $max ]]; then
14627                         max=$l
14628                 fi
14629         done
14630         echo $max
14631 }
14632
14633 test_124b() {
14634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14635         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14636                 skip_env "no lru resize on server"
14637
14638         LIMIT=$(get_max_pool_limit)
14639
14640         NR=$(($(default_lru_size)*20))
14641         if [[ $NR -gt $LIMIT ]]; then
14642                 log "Limit lock number by $LIMIT locks"
14643                 NR=$LIMIT
14644         fi
14645
14646         IFree=$(mdsrate_inodes_available)
14647         if [ $IFree -lt $NR ]; then
14648                 log "Limit lock number by $IFree inodes"
14649                 NR=$IFree
14650         fi
14651
14652         lru_resize_disable mdc
14653         test_mkdir -p $DIR/$tdir/disable_lru_resize
14654
14655         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14656         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14657         cancel_lru_locks mdc
14658         stime=`date +%s`
14659         PID=""
14660         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14661         PID="$PID $!"
14662         sleep 2
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         wait $PID
14669         etime=`date +%s`
14670         nolruresize_delta=$((etime-stime))
14671         log "ls -la time: $nolruresize_delta seconds"
14672         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14673         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14674
14675         lru_resize_enable mdc
14676         test_mkdir -p $DIR/$tdir/enable_lru_resize
14677
14678         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14679         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14680         cancel_lru_locks mdc
14681         stime=`date +%s`
14682         PID=""
14683         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14684         PID="$PID $!"
14685         sleep 2
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         wait $PID
14692         etime=`date +%s`
14693         lruresize_delta=$((etime-stime))
14694         log "ls -la time: $lruresize_delta seconds"
14695         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14696
14697         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14698                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14699         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14700                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14701         else
14702                 log "lru resize performs the same with no lru resize"
14703         fi
14704         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14705 }
14706 run_test 124b "lru resize (performance test) ======================="
14707
14708 test_124c() {
14709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14710         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14711                 skip_env "no lru resize on server"
14712
14713         # cache ununsed locks on client
14714         local nr=100
14715         cancel_lru_locks mdc
14716         test_mkdir $DIR/$tdir
14717         createmany -o $DIR/$tdir/f $nr ||
14718                 error "failed to create $nr files in $DIR/$tdir"
14719         ls -l $DIR/$tdir > /dev/null
14720
14721         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14722         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14723         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14724         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14725         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14726
14727         # set lru_max_age to 1 sec
14728         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14729         echo "sleep $((recalc_p * 2)) seconds..."
14730         sleep $((recalc_p * 2))
14731
14732         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14733         # restore lru_max_age
14734         $LCTL set_param -n $nsdir.lru_max_age $max_age
14735         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14736         unlinkmany $DIR/$tdir/f $nr
14737 }
14738 run_test 124c "LRUR cancel very aged locks"
14739
14740 test_124d() {
14741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14742         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14743                 skip_env "no lru resize on server"
14744
14745         # cache ununsed locks on client
14746         local nr=100
14747
14748         lru_resize_disable mdc
14749         stack_trap "lru_resize_enable mdc" EXIT
14750
14751         cancel_lru_locks mdc
14752
14753         # asynchronous object destroy at MDT could cause bl ast to client
14754         test_mkdir $DIR/$tdir
14755         createmany -o $DIR/$tdir/f $nr ||
14756                 error "failed to create $nr files in $DIR/$tdir"
14757         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14758
14759         ls -l $DIR/$tdir > /dev/null
14760
14761         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14762         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14763         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14764         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14765
14766         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14767
14768         # set lru_max_age to 1 sec
14769         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14770         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14771
14772         echo "sleep $((recalc_p * 2)) seconds..."
14773         sleep $((recalc_p * 2))
14774
14775         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14776
14777         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14778 }
14779 run_test 124d "cancel very aged locks if lru-resize disabled"
14780
14781 test_125() { # 13358
14782         $LCTL get_param -n llite.*.client_type | grep -q local ||
14783                 skip "must run as local client"
14784         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14785                 skip_env "must have acl enabled"
14786         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14787         id $USER0 || skip_env "missing user $USER0"
14788
14789         test_mkdir $DIR/$tdir
14790         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14791         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14792                 error "setfacl $DIR/$tdir failed"
14793         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14794 }
14795 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14796
14797 test_126() { # bug 12829/13455
14798         $GSS && skip_env "must run as gss disabled"
14799         $LCTL get_param -n llite.*.client_type | grep -q local ||
14800                 skip "must run as local client"
14801         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14802
14803         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14804         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14805         rm -f $DIR/$tfile
14806         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14807 }
14808 run_test 126 "check that the fsgid provided by the client is taken into account"
14809
14810 test_127a() { # bug 15521
14811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14812         local name count samp unit min max sum sumsq
14813         local tmpfile=$TMP/$tfile.tmp
14814
14815         # enable stats header if it is disabled
14816         $LCTL set_param enable_stats_header=1
14817
14818         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14819         echo "stats before reset"
14820         stack_trap "rm -f $tmpfile"
14821         local now=$(date +%s)
14822
14823         $LCTL get_param osc.*.stats | tee $tmpfile
14824
14825         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14826         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14827         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14828         local uptime=$(awk '{ print $1 }' /proc/uptime)
14829
14830         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14831         (( ${snapshot_time%\.*} >= $now - 5 &&
14832            ${snapshot_time%\.*} <= $now + 5 )) ||
14833                 error "snapshot_time=$snapshot_time != now=$now"
14834         # elapsed _should_ be from mount, but at least less than uptime
14835         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14836                 error "elapsed=$elapsed > uptime=$uptime"
14837         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14838            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14839                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14840
14841         $LCTL set_param osc.*.stats=0
14842         local reset=$(date +%s)
14843         local fsize=$((2048 * 1024))
14844
14845         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14846         cancel_lru_locks osc
14847         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14848
14849         now=$(date +%s)
14850         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14851         while read name count samp unit min max sum sumsq; do
14852                 [[ "$samp" == "samples" ]] || continue
14853
14854                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14855                 [ ! $min ] && error "Missing min value for $name proc entry"
14856                 eval $name=$count || error "Wrong proc format"
14857
14858                 case $name in
14859                 read_bytes|write_bytes)
14860                         [[ "$unit" =~ "bytes" ]] ||
14861                                 error "unit is not 'bytes': $unit"
14862                         (( $min >= 4096 )) || error "min is too small: $min"
14863                         (( $min <= $fsize )) || error "min is too big: $min"
14864                         (( $max >= 4096 )) || error "max is too small: $max"
14865                         (( $max <= $fsize )) || error "max is too big: $max"
14866                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14867                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14868                                 error "sumsquare is too small: $sumsq"
14869                         (( $sumsq <= $fsize * $fsize )) ||
14870                                 error "sumsquare is too big: $sumsq"
14871                         ;;
14872                 ost_read|ost_write)
14873                         [[ "$unit" =~ "usec" ]] ||
14874                                 error "unit is not 'usec': $unit"
14875                         ;;
14876                 *)      ;;
14877                 esac
14878         done < $tmpfile
14879
14880         #check that we actually got some stats
14881         [ "$read_bytes" ] || error "Missing read_bytes stats"
14882         [ "$write_bytes" ] || error "Missing write_bytes stats"
14883         [ "$read_bytes" != 0 ] || error "no read done"
14884         [ "$write_bytes" != 0 ] || error "no write done"
14885
14886         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14887         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14888         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14889
14890         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14891         (( ${snapshot_time%\.*} >= $now - 5 &&
14892            ${snapshot_time%\.*} <= $now + 5 )) ||
14893                 error "reset snapshot_time=$snapshot_time != now=$now"
14894         # elapsed should be from time of stats reset
14895         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14896            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14897                 error "reset elapsed=$elapsed > $now - $reset"
14898         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14899            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14900                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14901 }
14902 run_test 127a "verify the client stats are sane"
14903
14904 test_127b() { # bug LU-333
14905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14906         local name count samp unit min max sum sumsq
14907
14908         echo "stats before reset"
14909         $LCTL get_param llite.*.stats
14910         $LCTL set_param llite.*.stats=0
14911
14912         # perform 2 reads and writes so MAX is different from SUM.
14913         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14914         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14915         cancel_lru_locks osc
14916         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14917         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14918
14919         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14920         stack_trap "rm -f $TMP/$tfile.tmp"
14921         while read name count samp unit min max sum sumsq; do
14922                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14923                 eval $name=$count || error "Wrong proc format"
14924
14925                 case $name in
14926                 read_bytes|write_bytes)
14927                         [[ "$unit" =~ "bytes" ]] ||
14928                                 error "unit is not 'bytes': $unit"
14929                         (( $count == 2 )) || error "count is not 2: $count"
14930                         (( $min == $PAGE_SIZE )) ||
14931                                 error "min is not $PAGE_SIZE: $min"
14932                         (( $max == $PAGE_SIZE )) ||
14933                                 error "max is not $PAGE_SIZE: $max"
14934                         (( $sum == $PAGE_SIZE * 2 )) ||
14935                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14936                         ;;
14937                 read|write)
14938                         [[ "$unit" =~ "usec" ]] ||
14939                                 error "unit is not 'usec': $unit"
14940                         ;;
14941                 *)      ;;
14942                 esac
14943         done < $TMP/$tfile.tmp
14944
14945         #check that we actually got some stats
14946         [ "$read_bytes" ] || error "Missing read_bytes stats"
14947         [ "$write_bytes" ] || error "Missing write_bytes stats"
14948         [ "$read_bytes" != 0 ] || error "no read done"
14949         [ "$write_bytes" != 0 ] || error "no write done"
14950 }
14951 run_test 127b "verify the llite client stats are sane"
14952
14953 test_127c() { # LU-12394
14954         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14955         local size
14956         local bsize
14957         local reads
14958         local writes
14959         local count
14960
14961         $LCTL set_param llite.*.extents_stats=1
14962         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14963
14964         # Use two stripes so there is enough space in default config
14965         $LFS setstripe -c 2 $DIR/$tfile
14966
14967         # Extent stats start at 0-4K and go in power of two buckets
14968         # LL_HIST_START = 12 --> 2^12 = 4K
14969         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14970         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14971         # small configs
14972         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14973                 do
14974                 # Write and read, 2x each, second time at a non-zero offset
14975                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14976                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14977                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14978                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14979                 rm -f $DIR/$tfile
14980         done
14981
14982         $LCTL get_param llite.*.extents_stats
14983
14984         count=2
14985         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14986                 do
14987                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14988                                 grep -m 1 $bsize)
14989                 reads=$(echo $bucket | awk '{print $5}')
14990                 writes=$(echo $bucket | awk '{print $9}')
14991                 [ "$reads" -eq $count ] ||
14992                         error "$reads reads in < $bsize bucket, expect $count"
14993                 [ "$writes" -eq $count ] ||
14994                         error "$writes writes in < $bsize bucket, expect $count"
14995         done
14996
14997         # Test mmap write and read
14998         $LCTL set_param llite.*.extents_stats=c
14999         size=512
15000         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15001         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15002         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15003
15004         $LCTL get_param llite.*.extents_stats
15005
15006         count=$(((size*1024) / PAGE_SIZE))
15007
15008         bsize=$((2 * PAGE_SIZE / 1024))K
15009
15010         bucket=$($LCTL get_param -n llite.*.extents_stats |
15011                         grep -m 1 $bsize)
15012         reads=$(echo $bucket | awk '{print $5}')
15013         writes=$(echo $bucket | awk '{print $9}')
15014         # mmap writes fault in the page first, creating an additonal read
15015         [ "$reads" -eq $((2 * count)) ] ||
15016                 error "$reads reads in < $bsize bucket, expect $count"
15017         [ "$writes" -eq $count ] ||
15018                 error "$writes writes in < $bsize bucket, expect $count"
15019 }
15020 run_test 127c "test llite extent stats with regular & mmap i/o"
15021
15022 test_128() { # bug 15212
15023         touch $DIR/$tfile
15024         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15025                 find $DIR/$tfile
15026                 find $DIR/$tfile
15027         EOF
15028
15029         result=$(grep error $TMP/$tfile.log)
15030         rm -f $DIR/$tfile $TMP/$tfile.log
15031         [ -z "$result" ] ||
15032                 error "consecutive find's under interactive lfs failed"
15033 }
15034 run_test 128 "interactive lfs for 2 consecutive find's"
15035
15036 set_dir_limits () {
15037         local mntdev
15038         local canondev
15039         local node
15040
15041         local ldproc=/proc/fs/ldiskfs
15042         local facets=$(get_facets MDS)
15043
15044         for facet in ${facets//,/ }; do
15045                 canondev=$(ldiskfs_canon \
15046                            *.$(convert_facet2label $facet).mntdev $facet)
15047                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15048                         ldproc=/sys/fs/ldiskfs
15049                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15050                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15051         done
15052 }
15053
15054 check_mds_dmesg() {
15055         local facets=$(get_facets MDS)
15056         for facet in ${facets//,/ }; do
15057                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15058         done
15059         return 1
15060 }
15061
15062 test_129() {
15063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15064         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15065                 skip "Need MDS version with at least 2.5.56"
15066         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15067                 skip_env "ldiskfs only test"
15068         fi
15069         remote_mds_nodsh && skip "remote MDS with nodsh"
15070
15071         local ENOSPC=28
15072         local has_warning=false
15073
15074         rm -rf $DIR/$tdir
15075         mkdir -p $DIR/$tdir
15076
15077         # block size of mds1
15078         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15079         set_dir_limits $maxsize $((maxsize * 6 / 8))
15080         stack_trap "set_dir_limits 0 0"
15081         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15082         local dirsize=$(stat -c%s "$DIR/$tdir")
15083         local nfiles=0
15084         while (( $dirsize <= $maxsize )); do
15085                 $MCREATE $DIR/$tdir/file_base_$nfiles
15086                 rc=$?
15087                 # check two errors:
15088                 # ENOSPC for ext4 max_dir_size, which has been used since
15089                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15090                 if (( rc == ENOSPC )); then
15091                         set_dir_limits 0 0
15092                         echo "rc=$rc returned as expected after $nfiles files"
15093
15094                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15095                                 error "create failed w/o dir size limit"
15096
15097                         # messages may be rate limited if test is run repeatedly
15098                         check_mds_dmesg '"is approaching max"' ||
15099                                 echo "warning message should be output"
15100                         check_mds_dmesg '"has reached max"' ||
15101                                 echo "reached message should be output"
15102
15103                         dirsize=$(stat -c%s "$DIR/$tdir")
15104
15105                         [[ $dirsize -ge $maxsize ]] && return 0
15106                         error "dirsize $dirsize < $maxsize after $nfiles files"
15107                 elif (( rc != 0 )); then
15108                         break
15109                 fi
15110                 nfiles=$((nfiles + 1))
15111                 dirsize=$(stat -c%s "$DIR/$tdir")
15112         done
15113
15114         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15115 }
15116 run_test 129 "test directory size limit ========================"
15117
15118 OLDIFS="$IFS"
15119 cleanup_130() {
15120         trap 0
15121         IFS="$OLDIFS"
15122         rm -f $DIR/$tfile
15123 }
15124
15125 test_130a() {
15126         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15127         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15128
15129         trap cleanup_130 EXIT RETURN
15130
15131         local fm_file=$DIR/$tfile
15132         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15133         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15134                 error "dd failed for $fm_file"
15135
15136         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15137         filefrag -ves $fm_file
15138         local rc=$?
15139         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15140                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15141         (( $rc == 0 )) || error "filefrag $fm_file failed"
15142
15143         filefrag_op=$(filefrag -ve -k $fm_file |
15144                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15145         local lun=$($LFS getstripe -i $fm_file)
15146
15147         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15148         IFS=$'\n'
15149         local tot_len=0
15150         for line in $filefrag_op; do
15151                 local frag_lun=$(echo $line | cut -d: -f5)
15152                 local ext_len=$(echo $line | cut -d: -f4)
15153
15154                 if (( $frag_lun != $lun )); then
15155                         error "FIEMAP on 1-stripe file($fm_file) failed"
15156                         return
15157                 fi
15158                 (( tot_len += ext_len ))
15159         done
15160
15161         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15162                 error "FIEMAP on 1-stripe file($fm_file) failed"
15163                 return
15164         fi
15165
15166         echo "FIEMAP on single striped file succeeded"
15167 }
15168 run_test 130a "FIEMAP (1-stripe file)"
15169
15170 test_130b() {
15171         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15172
15173         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15174         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15175         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15176                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15177
15178         trap cleanup_130 EXIT RETURN
15179
15180         local fm_file=$DIR/$tfile
15181         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15182                 error "setstripe on $fm_file"
15183
15184         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15185                 error "dd failed on $fm_file"
15186
15187         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15188         filefrag_op=$(filefrag -ve -k $fm_file |
15189                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15190
15191         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15192                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15193
15194         IFS=$'\n'
15195         local tot_len=0
15196         local num_luns=1
15197
15198         for line in $filefrag_op; do
15199                 local frag_lun=$(echo $line | cut -d: -f5 |
15200                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15201                 local ext_len=$(echo $line | cut -d: -f4)
15202                 if (( $frag_lun != $last_lun )); then
15203                         if (( tot_len != 1024 )); then
15204                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15205                                 return
15206                         else
15207                                 (( num_luns += 1 ))
15208                                 tot_len=0
15209                         fi
15210                 fi
15211                 (( tot_len += ext_len ))
15212                 last_lun=$frag_lun
15213         done
15214         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15215                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15216                 return
15217         fi
15218
15219         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15220 }
15221 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15222
15223 test_130c() {
15224         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15225
15226         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15227         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15228         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15229                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15230
15231         trap cleanup_130 EXIT RETURN
15232
15233         local fm_file=$DIR/$tfile
15234         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15235
15236         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15237                 error "dd failed on $fm_file"
15238
15239         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15240         filefrag_op=$(filefrag -ve -k $fm_file |
15241                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15242
15243         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15244                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15245
15246         IFS=$'\n'
15247         local tot_len=0
15248         local num_luns=1
15249         for line in $filefrag_op; do
15250                 local frag_lun=$(echo $line | cut -d: -f5 |
15251                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15252                 local ext_len=$(echo $line | cut -d: -f4)
15253                 if (( $frag_lun != $last_lun )); then
15254                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15255                         if (( logical != 512 )); then
15256                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15257                                 return
15258                         fi
15259                         if (( tot_len != 512 )); then
15260                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15261                                 return
15262                         else
15263                                 (( num_luns += 1 ))
15264                                 tot_len=0
15265                         fi
15266                 fi
15267                 (( tot_len += ext_len ))
15268                 last_lun=$frag_lun
15269         done
15270         if (( num_luns != 2 || tot_len != 512 )); then
15271                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15272                 return
15273         fi
15274
15275         echo "FIEMAP on 2-stripe file with hole succeeded"
15276 }
15277 run_test 130c "FIEMAP (2-stripe file with hole)"
15278
15279 test_130d() {
15280         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15281
15282         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15283         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15284         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15285                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15286
15287         trap cleanup_130 EXIT RETURN
15288
15289         local fm_file=$DIR/$tfile
15290         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15291                         error "setstripe on $fm_file"
15292
15293         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15294         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15295                 error "dd failed on $fm_file"
15296
15297         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15298         filefrag_op=$(filefrag -ve -k $fm_file |
15299                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15300
15301         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15302                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15303
15304         IFS=$'\n'
15305         local tot_len=0
15306         local num_luns=1
15307         for line in $filefrag_op; do
15308                 local frag_lun=$(echo $line | cut -d: -f5 |
15309                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15310                 local ext_len=$(echo $line | cut -d: -f4)
15311                 if (( $frag_lun != $last_lun )); then
15312                         if (( tot_len != 1024 )); then
15313                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15314                                 return
15315                         else
15316                                 (( num_luns += 1 ))
15317                                 local tot_len=0
15318                         fi
15319                 fi
15320                 (( tot_len += ext_len ))
15321                 last_lun=$frag_lun
15322         done
15323         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15324                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15325                 return
15326         fi
15327
15328         echo "FIEMAP on N-stripe file succeeded"
15329 }
15330 run_test 130d "FIEMAP (N-stripe file)"
15331
15332 test_130e() {
15333         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15334
15335         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15336         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15337         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15338                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15339
15340         trap cleanup_130 EXIT RETURN
15341
15342         local fm_file=$DIR/$tfile
15343         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15344         stack_trap "rm -f $fm_file"
15345
15346         local num_blks=512
15347         local expected_len=$(( (num_blks / 2) * 64 ))
15348         for ((i = 0; i < $num_blks; i++)); do
15349                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15350                         conv=notrunc > /dev/null 2>&1
15351         done
15352
15353         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15354         filefrag_op=$(filefrag -ve -k $fm_file |
15355                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15356
15357         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15358
15359         IFS=$'\n'
15360         local tot_len=0
15361         local num_luns=1
15362         for line in $filefrag_op; do
15363                 local frag_lun=$(echo $line | cut -d: -f5)
15364                 local ext_len=$(echo $line | cut -d: -f4)
15365                 if (( $frag_lun != $last_lun )); then
15366                         if (( tot_len != $expected_len )); then
15367                                 error "OST$last_lun $tot_len != $expected_len"
15368                         else
15369                                 (( num_luns += 1 ))
15370                                 tot_len=0
15371                         fi
15372                 fi
15373                 (( tot_len += ext_len ))
15374                 last_lun=$frag_lun
15375         done
15376         if (( num_luns != 2 || tot_len != $expected_len )); then
15377                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15378         fi
15379
15380         echo "FIEMAP with continuation calls succeeded"
15381 }
15382 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15383
15384 test_130f() {
15385         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15386         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15387         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15388                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15389
15390         local fm_file=$DIR/$tfile
15391         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15392                 error "multiop create with lov_delay_create on $fm_file"
15393
15394         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15395         filefrag_extents=$(filefrag -vek $fm_file |
15396                            awk '/extents? found/ { print $2 }')
15397         if (( $filefrag_extents != 0 )); then
15398                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15399         fi
15400
15401         rm -f $fm_file
15402 }
15403 run_test 130f "FIEMAP (unstriped file)"
15404
15405 test_130g() {
15406         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15407                 skip "Need MDS version with at least 2.12.53 for overstriping"
15408         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15409         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15410         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15411                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15412
15413         local file=$DIR/$tfile
15414         local nr=$((OSTCOUNT * 100))
15415
15416         $LFS setstripe -C $nr -S1M $file ||
15417                 error "failed to setstripe -C $nr $file"
15418
15419         stack_trap "rm -f $file"
15420         dd if=/dev/zero of=$file count=$nr bs=1M
15421         sync
15422         nr=$($LFS getstripe -c $file)
15423
15424         local extents=$(filefrag -v $file |
15425                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15426
15427         echo "filefrag list $extents extents in file with stripecount $nr"
15428         if (( extents < nr )); then
15429                 $LFS getstripe $file
15430                 filefrag -v $file
15431                 error "filefrag printed $extents < $nr extents"
15432         fi
15433 }
15434 run_test 130g "FIEMAP (overstripe file)"
15435
15436 # Test for writev/readv
15437 test_131a() {
15438         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15439                 error "writev test failed"
15440         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15441                 error "readv failed"
15442         rm -f $DIR/$tfile
15443 }
15444 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15445
15446 test_131b() {
15447         local fsize=$((524288 + 1048576 + 1572864))
15448         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15449                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15450                         error "append writev test failed"
15451
15452         ((fsize += 1572864 + 1048576))
15453         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15454                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15455                         error "append writev test failed"
15456         rm -f $DIR/$tfile
15457 }
15458 run_test 131b "test append writev"
15459
15460 test_131c() {
15461         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15462         error "NOT PASS"
15463 }
15464 run_test 131c "test read/write on file w/o objects"
15465
15466 test_131d() {
15467         rwv -f $DIR/$tfile -w -n 1 1572864
15468         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15469         if [ "$NOB" != 1572864 ]; then
15470                 error "Short read filed: read $NOB bytes instead of 1572864"
15471         fi
15472         rm -f $DIR/$tfile
15473 }
15474 run_test 131d "test short read"
15475
15476 test_131e() {
15477         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15478         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15479         error "read hitting hole failed"
15480         rm -f $DIR/$tfile
15481 }
15482 run_test 131e "test read hitting hole"
15483
15484 check_stats() {
15485         local facet=$1
15486         local op=$2
15487         local want=${3:-0}
15488         local res
15489
15490         # open             11 samples [usecs] 468 4793 13658 35791898
15491         case $facet in
15492         mds*) res=($(do_facet $facet \
15493                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15494                  ;;
15495         ost*) res=($(do_facet $facet \
15496                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15497                  ;;
15498         *) error "Wrong facet '$facet'" ;;
15499         esac
15500         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15501         # if $want is zero, it means any stat increment is ok.
15502         if (( $want > 0 )); then
15503                 local count=${res[1]}
15504
15505                 if (( $count != $want )); then
15506                         if [[ $facet =~ "mds" ]]; then
15507                                 do_nodes $(comma_list $(mdts_nodes)) \
15508                                         $LCTL get_param mdt.*.md_stats
15509                         else
15510                                 do_nodes $(comma_list $(osts-nodes)) \
15511                                         $LCTL get_param obdfilter.*.stats
15512                         fi
15513                         error "The $op counter on $facet is $count, not $want"
15514                 fi
15515         fi
15516 }
15517
15518 test_133a() {
15519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15520         remote_ost_nodsh && skip "remote OST with nodsh"
15521         remote_mds_nodsh && skip "remote MDS with nodsh"
15522         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15523                 skip_env "MDS doesn't support rename stats"
15524
15525         local testdir=$DIR/${tdir}/stats_testdir
15526
15527         mkdir -p $DIR/${tdir}
15528
15529         # clear stats.
15530         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15531         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15532
15533         # verify mdt stats first.
15534         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15535         check_stats $SINGLEMDS "mkdir" 1
15536
15537         # clear "open" from "lfs mkdir" above
15538         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15539         touch ${testdir}/${tfile} || error "touch failed"
15540         check_stats $SINGLEMDS "open" 1
15541         check_stats $SINGLEMDS "close" 1
15542         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15543                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15544                 check_stats $SINGLEMDS "mknod" 2
15545         }
15546         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15547         check_stats $SINGLEMDS "unlink" 1
15548         rm -f ${testdir}/${tfile} || error "file remove failed"
15549         check_stats $SINGLEMDS "unlink" 2
15550
15551         # remove working dir and check mdt stats again.
15552         rmdir ${testdir} || error "rmdir failed"
15553         check_stats $SINGLEMDS "rmdir" 1
15554
15555         local testdir1=$DIR/${tdir}/stats_testdir1
15556         mkdir_on_mdt0 -p ${testdir}
15557         mkdir_on_mdt0 -p ${testdir1}
15558         touch ${testdir1}/test1
15559         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15560         check_stats $SINGLEMDS "crossdir_rename" 1
15561
15562         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15563         check_stats $SINGLEMDS "samedir_rename" 1
15564
15565         rm -rf $DIR/${tdir}
15566 }
15567 run_test 133a "Verifying MDT stats ========================================"
15568
15569 test_133b() {
15570         local res
15571
15572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15573         remote_ost_nodsh && skip "remote OST with nodsh"
15574         remote_mds_nodsh && skip "remote MDS with nodsh"
15575
15576         local testdir=$DIR/${tdir}/stats_testdir
15577
15578         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15579         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15580         touch ${testdir}/${tfile} || error "touch failed"
15581         cancel_lru_locks mdc
15582
15583         # clear stats.
15584         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15585         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15586
15587         # extra mdt stats verification.
15588         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15589         check_stats $SINGLEMDS "setattr" 1
15590         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15591         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15592         then            # LU-1740
15593                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15594                 check_stats $SINGLEMDS "getattr" 1
15595         fi
15596         rm -rf $DIR/${tdir}
15597
15598         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15599         # so the check below is not reliable
15600         [ $MDSCOUNT -eq 1 ] || return 0
15601
15602         # Sleep to avoid a cached response.
15603         #define OBD_STATFS_CACHE_SECONDS 1
15604         sleep 2
15605         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15606         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15607         $LFS df || error "lfs failed"
15608         check_stats $SINGLEMDS "statfs" 1
15609
15610         # check aggregated statfs (LU-10018)
15611         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15612                 return 0
15613         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15614                 return 0
15615         sleep 2
15616         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15617         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15618         df $DIR
15619         check_stats $SINGLEMDS "statfs" 1
15620
15621         # We want to check that the client didn't send OST_STATFS to
15622         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15623         # extra care is needed here.
15624         if remote_mds; then
15625                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15626                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15627
15628                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15629                 [ "$res" ] && error "OST got STATFS"
15630         fi
15631
15632         return 0
15633 }
15634 run_test 133b "Verifying extra MDT stats =================================="
15635
15636 test_133c() {
15637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15638         remote_ost_nodsh && skip "remote OST with nodsh"
15639         remote_mds_nodsh && skip "remote MDS with nodsh"
15640
15641         local testdir=$DIR/$tdir/stats_testdir
15642
15643         test_mkdir -p $testdir
15644
15645         # verify obdfilter stats.
15646         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15647         sync
15648         cancel_lru_locks osc
15649         wait_delete_completed
15650
15651         # clear stats.
15652         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15653         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15654
15655         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15656                 error "dd failed"
15657         sync
15658         cancel_lru_locks osc
15659         check_stats ost1 "write" 1
15660
15661         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15662         check_stats ost1 "read" 1
15663
15664         > $testdir/$tfile || error "truncate failed"
15665         check_stats ost1 "punch" 1
15666
15667         rm -f $testdir/$tfile || error "file remove failed"
15668         wait_delete_completed
15669         check_stats ost1 "destroy" 1
15670
15671         rm -rf $DIR/$tdir
15672 }
15673 run_test 133c "Verifying OST stats ========================================"
15674
15675 order_2() {
15676         local value=$1
15677         local orig=$value
15678         local order=1
15679
15680         while [ $value -ge 2 ]; do
15681                 order=$((order*2))
15682                 value=$((value/2))
15683         done
15684
15685         if [ $orig -gt $order ]; then
15686                 order=$((order*2))
15687         fi
15688         echo $order
15689 }
15690
15691 size_in_KMGT() {
15692     local value=$1
15693     local size=('K' 'M' 'G' 'T');
15694     local i=0
15695     local size_string=$value
15696
15697     while [ $value -ge 1024 ]; do
15698         if [ $i -gt 3 ]; then
15699             #T is the biggest unit we get here, if that is bigger,
15700             #just return XXXT
15701             size_string=${value}T
15702             break
15703         fi
15704         value=$((value >> 10))
15705         if [ $value -lt 1024 ]; then
15706             size_string=${value}${size[$i]}
15707             break
15708         fi
15709         i=$((i + 1))
15710     done
15711
15712     echo $size_string
15713 }
15714
15715 get_rename_size() {
15716         local size=$1
15717         local context=${2:-.}
15718         local sample=$(do_facet $SINGLEMDS $LCTL \
15719                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15720                 grep -A1 $context |
15721                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15722         echo $sample
15723 }
15724
15725 test_133d() {
15726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15727         remote_ost_nodsh && skip "remote OST with nodsh"
15728         remote_mds_nodsh && skip "remote MDS with nodsh"
15729         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15730                 skip_env "MDS doesn't support rename stats"
15731
15732         local testdir1=$DIR/${tdir}/stats_testdir1
15733         local testdir2=$DIR/${tdir}/stats_testdir2
15734         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15735
15736         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15737
15738         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15739         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15740
15741         createmany -o $testdir1/test 512 || error "createmany failed"
15742
15743         # check samedir rename size
15744         mv ${testdir1}/test0 ${testdir1}/test_0
15745
15746         local testdir1_size=$(ls -l $DIR/${tdir} |
15747                 awk '/stats_testdir1/ {print $5}')
15748         local testdir2_size=$(ls -l $DIR/${tdir} |
15749                 awk '/stats_testdir2/ {print $5}')
15750
15751         testdir1_size=$(order_2 $testdir1_size)
15752         testdir2_size=$(order_2 $testdir2_size)
15753
15754         testdir1_size=$(size_in_KMGT $testdir1_size)
15755         testdir2_size=$(size_in_KMGT $testdir2_size)
15756
15757         echo "source rename dir size: ${testdir1_size}"
15758         echo "target rename dir size: ${testdir2_size}"
15759
15760         local cmd="do_facet $SINGLEMDS $LCTL "
15761         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15762
15763         eval $cmd || error "$cmd failed"
15764         local samedir=$($cmd | grep 'same_dir')
15765         local same_sample=$(get_rename_size $testdir1_size)
15766         [ -z "$samedir" ] && error "samedir_rename_size count error"
15767         [[ $same_sample -eq 1 ]] ||
15768                 error "samedir_rename_size error $same_sample"
15769         echo "Check same dir rename stats success"
15770
15771         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15772
15773         # check crossdir rename size
15774         mv ${testdir1}/test_0 ${testdir2}/test_0
15775
15776         testdir1_size=$(ls -l $DIR/${tdir} |
15777                 awk '/stats_testdir1/ {print $5}')
15778         testdir2_size=$(ls -l $DIR/${tdir} |
15779                 awk '/stats_testdir2/ {print $5}')
15780
15781         testdir1_size=$(order_2 $testdir1_size)
15782         testdir2_size=$(order_2 $testdir2_size)
15783
15784         testdir1_size=$(size_in_KMGT $testdir1_size)
15785         testdir2_size=$(size_in_KMGT $testdir2_size)
15786
15787         echo "source rename dir size: ${testdir1_size}"
15788         echo "target rename dir size: ${testdir2_size}"
15789
15790         eval $cmd || error "$cmd failed"
15791         local crossdir=$($cmd | grep 'crossdir')
15792         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15793         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15794         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15795         [[ $src_sample -eq 1 ]] ||
15796                 error "crossdir_rename_size error $src_sample"
15797         [[ $tgt_sample -eq 1 ]] ||
15798                 error "crossdir_rename_size error $tgt_sample"
15799         echo "Check cross dir rename stats success"
15800         rm -rf $DIR/${tdir}
15801 }
15802 run_test 133d "Verifying rename_stats ========================================"
15803
15804 test_133e() {
15805         remote_mds_nodsh && skip "remote MDS with nodsh"
15806         remote_ost_nodsh && skip "remote OST with nodsh"
15807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15808
15809         local testdir=$DIR/${tdir}/stats_testdir
15810         local ctr f0 f1 bs=32768 count=42 sum
15811
15812         mkdir -p ${testdir} || error "mkdir failed"
15813
15814         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15815
15816         for ctr in {write,read}_bytes; do
15817                 sync
15818                 cancel_lru_locks osc
15819
15820                 do_facet ost1 $LCTL set_param -n \
15821                         "obdfilter.*.exports.clear=clear"
15822
15823                 if [ $ctr = write_bytes ]; then
15824                         f0=/dev/zero
15825                         f1=${testdir}/${tfile}
15826                 else
15827                         f0=${testdir}/${tfile}
15828                         f1=/dev/null
15829                 fi
15830
15831                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15832                         error "dd failed"
15833                 sync
15834                 cancel_lru_locks osc
15835
15836                 sum=$(do_facet ost1 $LCTL get_param \
15837                         "obdfilter.*.exports.*.stats" |
15838                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15839                                 $1 == ctr { sum += $7 }
15840                                 END { printf("%0.0f", sum) }')
15841
15842                 if ((sum != bs * count)); then
15843                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15844                 fi
15845         done
15846
15847         rm -rf $DIR/${tdir}
15848 }
15849 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15850
15851 test_133f() {
15852         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15853                 skip "too old lustre for get_param -R ($facet_ver)"
15854
15855         # verifying readability.
15856         $LCTL get_param -R '*' &> /dev/null
15857
15858         # Verifing writability with badarea_io.
15859         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15860         local skipped_params='force_lbug|changelog_mask|daemon_file'
15861         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15862                 egrep -v "$skipped_params" |
15863                 xargs -n 1 find $proc_dirs -name |
15864                 xargs -n 1 badarea_io ||
15865                 error "client badarea_io failed"
15866
15867         # remount the FS in case writes/reads /proc break the FS
15868         cleanup || error "failed to unmount"
15869         setup || error "failed to setup"
15870 }
15871 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15872
15873 test_133g() {
15874         remote_mds_nodsh && skip "remote MDS with nodsh"
15875         remote_ost_nodsh && skip "remote OST with nodsh"
15876
15877         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15878         local proc_dirs_str=$(eval echo $proc_dirs)
15879         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15880         local facet
15881         for facet in mds1 ost1; do
15882                 local facet_ver=$(lustre_version_code $facet)
15883                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15884                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15885                 else
15886                         log "$facet: too old lustre for get_param -R"
15887                 fi
15888                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15889                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15890                                 tr -d = | egrep -v $skipped_params |
15891                                 xargs -n 1 find $proc_dirs_str -name |
15892                                 xargs -n 1 badarea_io" ||
15893                                         error "$facet badarea_io failed"
15894                 else
15895                         skip_noexit "$facet: too old lustre for get_param -R"
15896                 fi
15897         done
15898
15899         # remount the FS in case writes/reads /proc break the FS
15900         cleanup || error "failed to unmount"
15901         setup || error "failed to setup"
15902 }
15903 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15904
15905 test_133h() {
15906         remote_mds_nodsh && skip "remote MDS with nodsh"
15907         remote_ost_nodsh && skip "remote OST with nodsh"
15908         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15909                 skip "Need MDS version at least 2.9.54"
15910
15911         local facet
15912         for facet in client mds1 ost1; do
15913                 # Get the list of files that are missing the terminating newline
15914                 local plist=$(do_facet $facet
15915                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15916                 local ent
15917                 for ent in $plist; do
15918                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15919                                 awk -v FS='\v' -v RS='\v\v' \
15920                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15921                                         print FILENAME}'" 2>/dev/null)
15922                         [ -z $missing ] || {
15923                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15924                                 error "file does not end with newline: $facet-$ent"
15925                         }
15926                 done
15927         done
15928 }
15929 run_test 133h "Proc files should end with newlines"
15930
15931 test_134a() {
15932         remote_mds_nodsh && skip "remote MDS with nodsh"
15933         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15934                 skip "Need MDS version at least 2.7.54"
15935
15936         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15937         cancel_lru_locks mdc
15938
15939         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15940         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15941         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15942
15943         local nr=1000
15944         createmany -o $DIR/$tdir/f $nr ||
15945                 error "failed to create $nr files in $DIR/$tdir"
15946         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15947
15948         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15949         do_facet mds1 $LCTL set_param fail_loc=0x327
15950         do_facet mds1 $LCTL set_param fail_val=500
15951         touch $DIR/$tdir/m
15952
15953         echo "sleep 10 seconds ..."
15954         sleep 10
15955         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15956
15957         do_facet mds1 $LCTL set_param fail_loc=0
15958         do_facet mds1 $LCTL set_param fail_val=0
15959         [ $lck_cnt -lt $unused ] ||
15960                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15961
15962         rm $DIR/$tdir/m
15963         unlinkmany $DIR/$tdir/f $nr
15964 }
15965 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15966
15967 test_134b() {
15968         remote_mds_nodsh && skip "remote MDS with nodsh"
15969         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15970                 skip "Need MDS version at least 2.7.54"
15971
15972         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15973         cancel_lru_locks mdc
15974
15975         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15976                         ldlm.lock_reclaim_threshold_mb)
15977         # disable reclaim temporarily
15978         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15979
15980         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15981         do_facet mds1 $LCTL set_param fail_loc=0x328
15982         do_facet mds1 $LCTL set_param fail_val=500
15983
15984         $LCTL set_param debug=+trace
15985
15986         local nr=600
15987         createmany -o $DIR/$tdir/f $nr &
15988         local create_pid=$!
15989
15990         echo "Sleep $TIMEOUT seconds ..."
15991         sleep $TIMEOUT
15992         if ! ps -p $create_pid  > /dev/null 2>&1; then
15993                 do_facet mds1 $LCTL set_param fail_loc=0
15994                 do_facet mds1 $LCTL set_param fail_val=0
15995                 do_facet mds1 $LCTL set_param \
15996                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15997                 error "createmany finished incorrectly!"
15998         fi
15999         do_facet mds1 $LCTL set_param fail_loc=0
16000         do_facet mds1 $LCTL set_param fail_val=0
16001         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16002         wait $create_pid || return 1
16003
16004         unlinkmany $DIR/$tdir/f $nr
16005 }
16006 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16007
16008 test_135() {
16009         remote_mds_nodsh && skip "remote MDS with nodsh"
16010         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16011                 skip "Need MDS version at least 2.13.50"
16012         local fname
16013
16014         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16015
16016 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16017         #set only one record at plain llog
16018         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16019
16020         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16021
16022         #fill already existed plain llog each 64767
16023         #wrapping whole catalog
16024         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16025
16026         createmany -o $DIR/$tdir/$tfile_ 64700
16027         for (( i = 0; i < 64700; i = i + 2 ))
16028         do
16029                 rm $DIR/$tdir/$tfile_$i &
16030                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16031                 local pid=$!
16032                 wait $pid
16033         done
16034
16035         #waiting osp synchronization
16036         wait_delete_completed
16037 }
16038 run_test 135 "Race catalog processing"
16039
16040 test_136() {
16041         remote_mds_nodsh && skip "remote MDS with nodsh"
16042         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16043                 skip "Need MDS version at least 2.13.50"
16044         local fname
16045
16046         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16047         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16048         #set only one record at plain llog
16049 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16050         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16051
16052         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16053
16054         #fill already existed 2 plain llogs each 64767
16055         #wrapping whole catalog
16056         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16057         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16058         wait_delete_completed
16059
16060         createmany -o $DIR/$tdir/$tfile_ 10
16061         sleep 25
16062
16063         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16064         for (( i = 0; i < 10; i = i + 3 ))
16065         do
16066                 rm $DIR/$tdir/$tfile_$i &
16067                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16068                 local pid=$!
16069                 wait $pid
16070                 sleep 7
16071                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16072         done
16073
16074         #waiting osp synchronization
16075         wait_delete_completed
16076 }
16077 run_test 136 "Race catalog processing 2"
16078
16079 test_140() { #bug-17379
16080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16081
16082         test_mkdir $DIR/$tdir
16083         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16084         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16085
16086         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16087         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16088         local i=0
16089         while i=$((i + 1)); do
16090                 test_mkdir $i
16091                 cd $i || error "Changing to $i"
16092                 ln -s ../stat stat || error "Creating stat symlink"
16093                 # Read the symlink until ELOOP present,
16094                 # not LBUGing the system is considered success,
16095                 # we didn't overrun the stack.
16096                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16097                 if [ $ret -ne 0 ]; then
16098                         if [ $ret -eq 40 ]; then
16099                                 break  # -ELOOP
16100                         else
16101                                 error "Open stat symlink"
16102                                         return
16103                         fi
16104                 fi
16105         done
16106         i=$((i - 1))
16107         echo "The symlink depth = $i"
16108         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16109                 error "Invalid symlink depth"
16110
16111         # Test recursive symlink
16112         ln -s symlink_self symlink_self
16113         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16114         echo "open symlink_self returns $ret"
16115         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16116 }
16117 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16118
16119 test_150a() {
16120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16121
16122         local TF="$TMP/$tfile"
16123
16124         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16125         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16126         cp $TF $DIR/$tfile
16127         cancel_lru_locks $OSC
16128         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16129         remount_client $MOUNT
16130         df -P $MOUNT
16131         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16132
16133         $TRUNCATE $TF 6000
16134         $TRUNCATE $DIR/$tfile 6000
16135         cancel_lru_locks $OSC
16136         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16137
16138         echo "12345" >>$TF
16139         echo "12345" >>$DIR/$tfile
16140         cancel_lru_locks $OSC
16141         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16142
16143         echo "12345" >>$TF
16144         echo "12345" >>$DIR/$tfile
16145         cancel_lru_locks $OSC
16146         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16147 }
16148 run_test 150a "truncate/append tests"
16149
16150 test_150b() {
16151         check_set_fallocate_or_skip
16152         local out
16153
16154         touch $DIR/$tfile
16155         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16156         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16157                 skip_eopnotsupp "$out|check_fallocate failed"
16158 }
16159 run_test 150b "Verify fallocate (prealloc) functionality"
16160
16161 test_150bb() {
16162         check_set_fallocate_or_skip
16163
16164         touch $DIR/$tfile
16165         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16166         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16167         > $DIR/$tfile
16168         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16169         # precomputed md5sum for 20MB of zeroes
16170         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16171         local sum=($(md5sum $DIR/$tfile))
16172
16173         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16174
16175         check_set_fallocate 1
16176
16177         > $DIR/$tfile
16178         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16179         sum=($(md5sum $DIR/$tfile))
16180
16181         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16182 }
16183 run_test 150bb "Verify fallocate modes both zero space"
16184
16185 test_150c() {
16186         check_set_fallocate_or_skip
16187         local striping="-c2"
16188
16189         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16190         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16191         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16192         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16193         local want=$((OSTCOUNT * 1048576))
16194
16195         # Must allocate all requested space, not more than 5% extra
16196         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16197                 error "bytes $bytes is not $want"
16198
16199         rm -f $DIR/$tfile
16200
16201         echo "verify fallocate on PFL file"
16202
16203         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16204
16205         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16206                 error "Create $DIR/$tfile failed"
16207         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16208         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16209         want=$((512 * 1048576))
16210
16211         # Must allocate all requested space, not more than 5% extra
16212         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16213                 error "bytes $bytes is not $want"
16214 }
16215 run_test 150c "Verify fallocate Size and Blocks"
16216
16217 test_150d() {
16218         check_set_fallocate_or_skip
16219         local striping="-c2"
16220
16221         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16222
16223         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16224         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16225                 error "setstripe failed"
16226         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16227         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16228         local want=$((OSTCOUNT * 1048576))
16229
16230         # Must allocate all requested space, not more than 5% extra
16231         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16232                 error "bytes $bytes is not $want"
16233 }
16234 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16235
16236 test_150e() {
16237         check_set_fallocate_or_skip
16238
16239         echo "df before:"
16240         $LFS df
16241         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16242         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16243                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16244
16245         # Find OST with Minimum Size
16246         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16247                        sort -un | head -1)
16248
16249         # Get 100MB per OST of the available space to reduce run time
16250         # else 60% of the available space if we are running SLOW tests
16251         if [ $SLOW == "no" ]; then
16252                 local space=$((1024 * 100 * OSTCOUNT))
16253         else
16254                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16255         fi
16256
16257         fallocate -l${space}k $DIR/$tfile ||
16258                 error "fallocate ${space}k $DIR/$tfile failed"
16259         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16260
16261         # get size immediately after fallocate. This should be correctly
16262         # updated
16263         local size=$(stat -c '%s' $DIR/$tfile)
16264         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16265
16266         # Sleep for a while for statfs to get updated. And not pull from cache.
16267         sleep 2
16268
16269         echo "df after fallocate:"
16270         $LFS df
16271
16272         (( size / 1024 == space )) || error "size $size != requested $space"
16273         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16274                 error "used $used < space $space"
16275
16276         rm $DIR/$tfile || error "rm failed"
16277         sync
16278         wait_delete_completed
16279
16280         echo "df after unlink:"
16281         $LFS df
16282 }
16283 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16284
16285 test_150f() {
16286         local size
16287         local blocks
16288         local want_size_before=20480 # in bytes
16289         local want_blocks_before=40 # 512 sized blocks
16290         local want_blocks_after=24  # 512 sized blocks
16291         local length=$(((want_blocks_before - want_blocks_after) * 512))
16292
16293         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16294                 skip "need at least 2.14.0 for fallocate punch"
16295
16296         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16297                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16298         fi
16299
16300         check_set_fallocate_or_skip
16301         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16302
16303         [[ "x$DOM" == "xyes" ]] &&
16304                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16305
16306         echo "Verify fallocate punch: Range within the file range"
16307         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16308                 error "dd failed for bs 4096 and count 5"
16309
16310         # Call fallocate with punch range which is within the file range
16311         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16312                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16313         # client must see changes immediately after fallocate
16314         size=$(stat -c '%s' $DIR/$tfile)
16315         blocks=$(stat -c '%b' $DIR/$tfile)
16316
16317         # Verify punch worked.
16318         (( blocks == want_blocks_after )) ||
16319                 error "punch failed: blocks $blocks != $want_blocks_after"
16320
16321         (( size == want_size_before )) ||
16322                 error "punch failed: size $size != $want_size_before"
16323
16324         # Verify there is hole in file
16325         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16326         # precomputed md5sum
16327         local expect="4a9a834a2db02452929c0a348273b4aa"
16328
16329         cksum=($(md5sum $DIR/$tfile))
16330         [[ "${cksum[0]}" == "$expect" ]] ||
16331                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16332
16333         # Start second sub-case for fallocate punch.
16334         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16335         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16336                 error "dd failed for bs 4096 and count 5"
16337
16338         # Punch range less than block size will have no change in block count
16339         want_blocks_after=40  # 512 sized blocks
16340
16341         # Punch overlaps two blocks and less than blocksize
16342         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16343                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16344         size=$(stat -c '%s' $DIR/$tfile)
16345         blocks=$(stat -c '%b' $DIR/$tfile)
16346
16347         # Verify punch worked.
16348         (( blocks == want_blocks_after )) ||
16349                 error "punch failed: blocks $blocks != $want_blocks_after"
16350
16351         (( size == want_size_before )) ||
16352                 error "punch failed: size $size != $want_size_before"
16353
16354         # Verify if range is really zero'ed out. We expect Zeros.
16355         # precomputed md5sum
16356         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16357         cksum=($(md5sum $DIR/$tfile))
16358         [[ "${cksum[0]}" == "$expect" ]] ||
16359                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16360 }
16361 run_test 150f "Verify fallocate punch functionality"
16362
16363 test_150g() {
16364         local space
16365         local size
16366         local blocks
16367         local blocks_after
16368         local size_after
16369         local BS=4096 # Block size in bytes
16370
16371         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16372                 skip "need at least 2.14.0 for fallocate punch"
16373
16374         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16375                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16376         fi
16377
16378         check_set_fallocate_or_skip
16379         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16380
16381         if [[ "x$DOM" == "xyes" ]]; then
16382                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16383                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16384         else
16385                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16386                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16387         fi
16388
16389         # Get 100MB per OST of the available space to reduce run time
16390         # else 60% of the available space if we are running SLOW tests
16391         if [ $SLOW == "no" ]; then
16392                 space=$((1024 * 100 * OSTCOUNT))
16393         else
16394                 # Find OST with Minimum Size
16395                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16396                         sort -un | head -1)
16397                 echo "min size OST: $space"
16398                 space=$(((space * 60)/100 * OSTCOUNT))
16399         fi
16400         # space in 1k units, round to 4k blocks
16401         local blkcount=$((space * 1024 / $BS))
16402
16403         echo "Verify fallocate punch: Very large Range"
16404         fallocate -l${space}k $DIR/$tfile ||
16405                 error "fallocate ${space}k $DIR/$tfile failed"
16406         # write 1M at the end, start and in the middle
16407         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16408                 error "dd failed: bs $BS count 256"
16409         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16410                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16411         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16412                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16413
16414         # Gather stats.
16415         size=$(stat -c '%s' $DIR/$tfile)
16416
16417         # gather punch length.
16418         local punch_size=$((size - (BS * 2)))
16419
16420         echo "punch_size = $punch_size"
16421         echo "size - punch_size: $((size - punch_size))"
16422         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16423
16424         # Call fallocate to punch all except 2 blocks. We leave the
16425         # first and the last block
16426         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16427         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16428                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16429
16430         size_after=$(stat -c '%s' $DIR/$tfile)
16431         blocks_after=$(stat -c '%b' $DIR/$tfile)
16432
16433         # Verify punch worked.
16434         # Size should be kept
16435         (( size == size_after )) ||
16436                 error "punch failed: size $size != $size_after"
16437
16438         # two 4k data blocks to remain plus possible 1 extra extent block
16439         (( blocks_after <= ((BS / 512) * 3) )) ||
16440                 error "too many blocks remains: $blocks_after"
16441
16442         # Verify that file has hole between the first and the last blocks
16443         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16444         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16445
16446         echo "Hole at [$hole_start, $hole_end)"
16447         (( hole_start == BS )) ||
16448                 error "no hole at offset $BS after punch"
16449
16450         (( hole_end == BS + punch_size )) ||
16451                 error "data at offset $hole_end < $((BS + punch_size))"
16452 }
16453 run_test 150g "Verify fallocate punch on large range"
16454
16455 test_150h() {
16456         local file=$DIR/$tfile
16457         local size
16458
16459         check_set_fallocate_or_skip
16460         statx_supported || skip_env "Test must be statx() syscall supported"
16461
16462         # fallocate() does not update the size information on the MDT
16463         fallocate -l 16K $file || error "failed to fallocate $file"
16464         cancel_lru_locks $OSC
16465         # STATX with cached-always mode will not send glimpse RPCs to OST,
16466         # it uses the caching attrs on the client side as much as possible.
16467         size=$($STATX --cached=always -c %s $file)
16468         [ $size == 16384 ] ||
16469                 error "size after fallocate() is $size, expected 16384"
16470 }
16471 run_test 150h "Verify extend fallocate updates the file size"
16472
16473 #LU-2902 roc_hit was not able to read all values from lproc
16474 function roc_hit_init() {
16475         local list=$(comma_list $(osts_nodes))
16476         local dir=$DIR/$tdir-check
16477         local file=$dir/$tfile
16478         local BEFORE
16479         local AFTER
16480         local idx
16481
16482         test_mkdir $dir
16483         #use setstripe to do a write to every ost
16484         for i in $(seq 0 $((OSTCOUNT-1))); do
16485                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16486                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16487                 idx=$(printf %04x $i)
16488                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16489                         awk '$1 == "cache_access" {sum += $7}
16490                                 END { printf("%0.0f", sum) }')
16491
16492                 cancel_lru_locks osc
16493                 cat $file >/dev/null
16494
16495                 AFTER=$(get_osd_param $list *OST*$idx stats |
16496                         awk '$1 == "cache_access" {sum += $7}
16497                                 END { printf("%0.0f", sum) }')
16498
16499                 echo BEFORE:$BEFORE AFTER:$AFTER
16500                 if ! let "AFTER - BEFORE == 4"; then
16501                         rm -rf $dir
16502                         error "roc_hit is not safe to use"
16503                 fi
16504                 rm $file
16505         done
16506
16507         rm -rf $dir
16508 }
16509
16510 function roc_hit() {
16511         local list=$(comma_list $(osts_nodes))
16512         echo $(get_osd_param $list '' stats |
16513                 awk '$1 == "cache_hit" {sum += $7}
16514                         END { printf("%0.0f", sum) }')
16515 }
16516
16517 function set_cache() {
16518         local on=1
16519
16520         if [ "$2" == "off" ]; then
16521                 on=0;
16522         fi
16523         local list=$(comma_list $(osts_nodes))
16524         set_osd_param $list '' $1_cache_enable $on
16525
16526         cancel_lru_locks osc
16527 }
16528
16529 test_151() {
16530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16531         remote_ost_nodsh && skip "remote OST with nodsh"
16532         (( CLIENT_VERSION == OST1_VERSION )) ||
16533                 skip "LU-13081: no interop testing for OSS cache"
16534
16535         local CPAGES=3
16536         local list=$(comma_list $(osts_nodes))
16537
16538         # check whether obdfilter is cache capable at all
16539         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16540                 skip "not cache-capable obdfilter"
16541         fi
16542
16543         # check cache is enabled on all obdfilters
16544         if get_osd_param $list '' read_cache_enable | grep 0; then
16545                 skip "oss cache is disabled"
16546         fi
16547
16548         set_osd_param $list '' writethrough_cache_enable 1
16549
16550         # check write cache is enabled on all obdfilters
16551         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16552                 skip "oss write cache is NOT enabled"
16553         fi
16554
16555         roc_hit_init
16556
16557         #define OBD_FAIL_OBD_NO_LRU  0x609
16558         do_nodes $list $LCTL set_param fail_loc=0x609
16559
16560         # pages should be in the case right after write
16561         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16562                 error "dd failed"
16563
16564         local BEFORE=$(roc_hit)
16565         cancel_lru_locks osc
16566         cat $DIR/$tfile >/dev/null
16567         local AFTER=$(roc_hit)
16568
16569         do_nodes $list $LCTL set_param fail_loc=0
16570
16571         if ! let "AFTER - BEFORE == CPAGES"; then
16572                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16573         fi
16574
16575         cancel_lru_locks osc
16576         # invalidates OST cache
16577         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16578         set_osd_param $list '' read_cache_enable 0
16579         cat $DIR/$tfile >/dev/null
16580
16581         # now data shouldn't be found in the cache
16582         BEFORE=$(roc_hit)
16583         cancel_lru_locks osc
16584         cat $DIR/$tfile >/dev/null
16585         AFTER=$(roc_hit)
16586         if let "AFTER - BEFORE != 0"; then
16587                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16588         fi
16589
16590         set_osd_param $list '' read_cache_enable 1
16591         rm -f $DIR/$tfile
16592 }
16593 run_test 151 "test cache on oss and controls ==============================="
16594
16595 test_152() {
16596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16597
16598         local TF="$TMP/$tfile"
16599
16600         # simulate ENOMEM during write
16601 #define OBD_FAIL_OST_NOMEM      0x226
16602         lctl set_param fail_loc=0x80000226
16603         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16604         cp $TF $DIR/$tfile
16605         sync || error "sync failed"
16606         lctl set_param fail_loc=0
16607
16608         # discard client's cache
16609         cancel_lru_locks osc
16610
16611         # simulate ENOMEM during read
16612         lctl set_param fail_loc=0x80000226
16613         cmp $TF $DIR/$tfile || error "cmp failed"
16614         lctl set_param fail_loc=0
16615
16616         rm -f $TF
16617 }
16618 run_test 152 "test read/write with enomem ============================"
16619
16620 test_153() {
16621         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16622 }
16623 run_test 153 "test if fdatasync does not crash ======================="
16624
16625 dot_lustre_fid_permission_check() {
16626         local fid=$1
16627         local ffid=$MOUNT/.lustre/fid/$fid
16628         local test_dir=$2
16629
16630         echo "stat fid $fid"
16631         stat $ffid || error "stat $ffid failed."
16632         echo "touch fid $fid"
16633         touch $ffid || error "touch $ffid failed."
16634         echo "write to fid $fid"
16635         cat /etc/hosts > $ffid || error "write $ffid failed."
16636         echo "read fid $fid"
16637         diff /etc/hosts $ffid || error "read $ffid failed."
16638         echo "append write to fid $fid"
16639         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16640         echo "rename fid $fid"
16641         mv $ffid $test_dir/$tfile.1 &&
16642                 error "rename $ffid to $tfile.1 should fail."
16643         touch $test_dir/$tfile.1
16644         mv $test_dir/$tfile.1 $ffid &&
16645                 error "rename $tfile.1 to $ffid should fail."
16646         rm -f $test_dir/$tfile.1
16647         echo "truncate fid $fid"
16648         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16649         echo "link fid $fid"
16650         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16651         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16652                 id $USER0 || skip_env "missing user $USER0"
16653                 echo "setfacl fid $fid"
16654                 setfacl -R -m u:$USER0:rwx $ffid ||
16655                         error "setfacl $ffid failed"
16656                 echo "getfacl fid $fid"
16657                 getfacl $ffid || error "getfacl $ffid failed."
16658         fi
16659         echo "unlink fid $fid"
16660         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16661         echo "mknod fid $fid"
16662         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16663
16664         fid=[0xf00000400:0x1:0x0]
16665         ffid=$MOUNT/.lustre/fid/$fid
16666
16667         echo "stat non-exist fid $fid"
16668         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16669         echo "write to non-exist fid $fid"
16670         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16671         echo "link new fid $fid"
16672         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16673
16674         mkdir -p $test_dir/$tdir
16675         touch $test_dir/$tdir/$tfile
16676         fid=$($LFS path2fid $test_dir/$tdir)
16677         rc=$?
16678         [ $rc -ne 0 ] &&
16679                 error "error: could not get fid for $test_dir/$dir/$tfile."
16680
16681         ffid=$MOUNT/.lustre/fid/$fid
16682
16683         echo "ls $fid"
16684         ls $ffid || error "ls $ffid failed."
16685         echo "touch $fid/$tfile.1"
16686         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16687
16688         echo "touch $MOUNT/.lustre/fid/$tfile"
16689         touch $MOUNT/.lustre/fid/$tfile && \
16690                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16691
16692         echo "setxattr to $MOUNT/.lustre/fid"
16693         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16694
16695         echo "listxattr for $MOUNT/.lustre/fid"
16696         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16697
16698         echo "delxattr from $MOUNT/.lustre/fid"
16699         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16700
16701         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16702         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16703                 error "touch invalid fid should fail."
16704
16705         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16706         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16707                 error "touch non-normal fid should fail."
16708
16709         echo "rename $tdir to $MOUNT/.lustre/fid"
16710         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16711                 error "rename to $MOUNT/.lustre/fid should fail."
16712
16713         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16714         then            # LU-3547
16715                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16716                 local new_obf_mode=777
16717
16718                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16719                 chmod $new_obf_mode $DIR/.lustre/fid ||
16720                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16721
16722                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16723                 [ $obf_mode -eq $new_obf_mode ] ||
16724                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16725
16726                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16727                 chmod $old_obf_mode $DIR/.lustre/fid ||
16728                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16729         fi
16730
16731         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16732         fid=$($LFS path2fid $test_dir/$tfile-2)
16733
16734         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16735         then # LU-5424
16736                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16737                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16738                         error "create lov data thru .lustre failed"
16739         fi
16740         echo "cp /etc/passwd $test_dir/$tfile-2"
16741         cp /etc/passwd $test_dir/$tfile-2 ||
16742                 error "copy to $test_dir/$tfile-2 failed."
16743         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16744         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16745                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16746
16747         rm -rf $test_dir/tfile.lnk
16748         rm -rf $test_dir/$tfile-2
16749 }
16750
16751 test_154A() {
16752         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16753                 skip "Need MDS version at least 2.4.1"
16754
16755         local tf=$DIR/$tfile
16756         touch $tf
16757
16758         local fid=$($LFS path2fid $tf)
16759         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16760
16761         # check that we get the same pathname back
16762         local rootpath
16763         local found
16764         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16765                 echo "$rootpath $fid"
16766                 found=$($LFS fid2path $rootpath "$fid")
16767                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16768                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16769         done
16770
16771         # check wrong root path format
16772         rootpath=$MOUNT"_wrong"
16773         found=$($LFS fid2path $rootpath "$fid")
16774         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16775 }
16776 run_test 154A "lfs path2fid and fid2path basic checks"
16777
16778 test_154B() {
16779         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16780                 skip "Need MDS version at least 2.4.1"
16781
16782         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16783         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16784         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16785         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16786
16787         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16788         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16789
16790         # check that we get the same pathname
16791         echo "PFID: $PFID, name: $name"
16792         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16793         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16794         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16795                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16796
16797         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16798 }
16799 run_test 154B "verify the ll_decode_linkea tool"
16800
16801 test_154a() {
16802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16803         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16804         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16805                 skip "Need MDS version at least 2.2.51"
16806         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16807
16808         cp /etc/hosts $DIR/$tfile
16809
16810         fid=$($LFS path2fid $DIR/$tfile)
16811         rc=$?
16812         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16813
16814         dot_lustre_fid_permission_check "$fid" $DIR ||
16815                 error "dot lustre permission check $fid failed"
16816
16817         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16818
16819         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16820
16821         touch $MOUNT/.lustre/file &&
16822                 error "creation is not allowed under .lustre"
16823
16824         mkdir $MOUNT/.lustre/dir &&
16825                 error "mkdir is not allowed under .lustre"
16826
16827         rm -rf $DIR/$tfile
16828 }
16829 run_test 154a "Open-by-FID"
16830
16831 test_154b() {
16832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16833         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16835         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16836                 skip "Need MDS version at least 2.2.51"
16837
16838         local remote_dir=$DIR/$tdir/remote_dir
16839         local MDTIDX=1
16840         local rc=0
16841
16842         mkdir -p $DIR/$tdir
16843         $LFS mkdir -i $MDTIDX $remote_dir ||
16844                 error "create remote directory failed"
16845
16846         cp /etc/hosts $remote_dir/$tfile
16847
16848         fid=$($LFS path2fid $remote_dir/$tfile)
16849         rc=$?
16850         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16851
16852         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16853                 error "dot lustre permission check $fid failed"
16854         rm -rf $DIR/$tdir
16855 }
16856 run_test 154b "Open-by-FID for remote directory"
16857
16858 test_154c() {
16859         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16860                 skip "Need MDS version at least 2.4.1"
16861
16862         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16863         local FID1=$($LFS path2fid $DIR/$tfile.1)
16864         local FID2=$($LFS path2fid $DIR/$tfile.2)
16865         local FID3=$($LFS path2fid $DIR/$tfile.3)
16866
16867         local N=1
16868         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16869                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16870                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16871                 local want=FID$N
16872                 [ "$FID" = "${!want}" ] ||
16873                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16874                 N=$((N + 1))
16875         done
16876
16877         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16878         do
16879                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16880                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16881                 N=$((N + 1))
16882         done
16883 }
16884 run_test 154c "lfs path2fid and fid2path multiple arguments"
16885
16886 test_154d() {
16887         remote_mds_nodsh && skip "remote MDS with nodsh"
16888         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16889                 skip "Need MDS version at least 2.5.53"
16890
16891         if remote_mds; then
16892                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16893         else
16894                 nid="0@lo"
16895         fi
16896         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16897         local fd
16898         local cmd
16899
16900         rm -f $DIR/$tfile
16901         touch $DIR/$tfile
16902
16903         local fid=$($LFS path2fid $DIR/$tfile)
16904         # Open the file
16905         fd=$(free_fd)
16906         cmd="exec $fd<$DIR/$tfile"
16907         eval $cmd
16908         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16909         echo "$fid_list" | grep "$fid"
16910         rc=$?
16911
16912         cmd="exec $fd>/dev/null"
16913         eval $cmd
16914         if [ $rc -ne 0 ]; then
16915                 error "FID $fid not found in open files list $fid_list"
16916         fi
16917 }
16918 run_test 154d "Verify open file fid"
16919
16920 test_154e()
16921 {
16922         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16923                 skip "Need MDS version at least 2.6.50"
16924
16925         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16926                 error ".lustre returned by readdir"
16927         fi
16928 }
16929 run_test 154e ".lustre is not returned by readdir"
16930
16931 test_154f() {
16932         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16933
16934         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16935         mkdir_on_mdt0 $DIR/$tdir
16936         # test dirs inherit from its stripe
16937         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16938         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16939         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16940         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16941         touch $DIR/f
16942
16943         # get fid of parents
16944         local FID0=$($LFS path2fid $DIR/$tdir)
16945         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16946         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16947         local FID3=$($LFS path2fid $DIR)
16948
16949         # check that path2fid --parents returns expected <parent_fid>/name
16950         # 1) test for a directory (single parent)
16951         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16952         [ "$parent" == "$FID0/foo1" ] ||
16953                 error "expected parent: $FID0/foo1, got: $parent"
16954
16955         # 2) test for a file with nlink > 1 (multiple parents)
16956         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16957         echo "$parent" | grep -F "$FID1/$tfile" ||
16958                 error "$FID1/$tfile not returned in parent list"
16959         echo "$parent" | grep -F "$FID2/link" ||
16960                 error "$FID2/link not returned in parent list"
16961
16962         # 3) get parent by fid
16963         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16964         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16965         echo "$parent" | grep -F "$FID1/$tfile" ||
16966                 error "$FID1/$tfile not returned in parent list (by fid)"
16967         echo "$parent" | grep -F "$FID2/link" ||
16968                 error "$FID2/link not returned in parent list (by fid)"
16969
16970         # 4) test for entry in root directory
16971         parent=$($LFS path2fid --parents $DIR/f)
16972         echo "$parent" | grep -F "$FID3/f" ||
16973                 error "$FID3/f not returned in parent list"
16974
16975         # 5) test it on root directory
16976         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16977                 error "$MOUNT should not have parents"
16978
16979         # enable xattr caching and check that linkea is correctly updated
16980         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16981         save_lustre_params client "llite.*.xattr_cache" > $save
16982         lctl set_param llite.*.xattr_cache 1
16983
16984         # 6.1) linkea update on rename
16985         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16986
16987         # get parents by fid
16988         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16989         # foo1 should no longer be returned in parent list
16990         echo "$parent" | grep -F "$FID1" &&
16991                 error "$FID1 should no longer be in parent list"
16992         # the new path should appear
16993         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16994                 error "$FID2/$tfile.moved is not in parent list"
16995
16996         # 6.2) linkea update on unlink
16997         rm -f $DIR/$tdir/foo2/link
16998         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16999         # foo2/link should no longer be returned in parent list
17000         echo "$parent" | grep -F "$FID2/link" &&
17001                 error "$FID2/link should no longer be in parent list"
17002         true
17003
17004         rm -f $DIR/f
17005         restore_lustre_params < $save
17006         rm -f $save
17007 }
17008 run_test 154f "get parent fids by reading link ea"
17009
17010 test_154g()
17011 {
17012         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17013            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17014                 skip "Need MDS version at least 2.6.92"
17015
17016         mkdir_on_mdt0 $DIR/$tdir
17017         llapi_fid_test -d $DIR/$tdir
17018 }
17019 run_test 154g "various llapi FID tests"
17020
17021 test_154h()
17022 {
17023         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17024                 skip "Need client at least version 2.15.55.1"
17025
17026         # Create an empty file
17027         touch $DIR/$tfile
17028
17029         # Get FID (interactive mode) and save under $TMP/$tfile.log
17030         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17031                 path2fid $DIR/$tfile
17032         EOF
17033
17034         fid=$(cat $TMP/$tfile.log)
17035         # $fid should not be empty
17036         [[ ! -z $fid ]] || error "FID is empty"
17037         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17038 }
17039 run_test 154h "Verify interactive path2fid"
17040
17041 test_155_small_load() {
17042     local temp=$TMP/$tfile
17043     local file=$DIR/$tfile
17044
17045     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17046         error "dd of=$temp bs=6096 count=1 failed"
17047     cp $temp $file
17048     cancel_lru_locks $OSC
17049     cmp $temp $file || error "$temp $file differ"
17050
17051     $TRUNCATE $temp 6000
17052     $TRUNCATE $file 6000
17053     cmp $temp $file || error "$temp $file differ (truncate1)"
17054
17055     echo "12345" >>$temp
17056     echo "12345" >>$file
17057     cmp $temp $file || error "$temp $file differ (append1)"
17058
17059     echo "12345" >>$temp
17060     echo "12345" >>$file
17061     cmp $temp $file || error "$temp $file differ (append2)"
17062
17063     rm -f $temp $file
17064     true
17065 }
17066
17067 test_155_big_load() {
17068         remote_ost_nodsh && skip "remote OST with nodsh"
17069
17070         local temp=$TMP/$tfile
17071         local file=$DIR/$tfile
17072
17073         free_min_max
17074         local cache_size=$(do_facet ost$((MAXI+1)) \
17075                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17076
17077         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17078         # pre-set value
17079         if [ -z "$cache_size" ]; then
17080                 cache_size=256
17081         fi
17082         local large_file_size=$((cache_size * 2))
17083
17084         echo "OSS cache size: $cache_size KB"
17085         echo "Large file size: $large_file_size KB"
17086
17087         [ $MAXV -le $large_file_size ] &&
17088                 skip_env "max available OST size needs > $large_file_size KB"
17089
17090         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17091
17092         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17093                 error "dd of=$temp bs=$large_file_size count=1k failed"
17094         cp $temp $file
17095         ls -lh $temp $file
17096         cancel_lru_locks osc
17097         cmp $temp $file || error "$temp $file differ"
17098
17099         rm -f $temp $file
17100         true
17101 }
17102
17103 save_writethrough() {
17104         local facets=$(get_facets OST)
17105
17106         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17107 }
17108
17109 test_155a() {
17110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17111
17112         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17113
17114         save_writethrough $p
17115
17116         set_cache read on
17117         set_cache writethrough on
17118         test_155_small_load
17119         restore_lustre_params < $p
17120         rm -f $p
17121 }
17122 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17123
17124 test_155b() {
17125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17126
17127         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17128
17129         save_writethrough $p
17130
17131         set_cache read on
17132         set_cache writethrough off
17133         test_155_small_load
17134         restore_lustre_params < $p
17135         rm -f $p
17136 }
17137 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17138
17139 test_155c() {
17140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17141
17142         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17143
17144         save_writethrough $p
17145
17146         set_cache read off
17147         set_cache writethrough on
17148         test_155_small_load
17149         restore_lustre_params < $p
17150         rm -f $p
17151 }
17152 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17153
17154 test_155d() {
17155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17156
17157         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17158
17159         save_writethrough $p
17160
17161         set_cache read off
17162         set_cache writethrough off
17163         test_155_small_load
17164         restore_lustre_params < $p
17165         rm -f $p
17166 }
17167 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17168
17169 test_155e() {
17170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17171
17172         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17173
17174         save_writethrough $p
17175
17176         set_cache read on
17177         set_cache writethrough on
17178         test_155_big_load
17179         restore_lustre_params < $p
17180         rm -f $p
17181 }
17182 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17183
17184 test_155f() {
17185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17186
17187         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17188
17189         save_writethrough $p
17190
17191         set_cache read on
17192         set_cache writethrough off
17193         test_155_big_load
17194         restore_lustre_params < $p
17195         rm -f $p
17196 }
17197 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17198
17199 test_155g() {
17200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17201
17202         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17203
17204         save_writethrough $p
17205
17206         set_cache read off
17207         set_cache writethrough on
17208         test_155_big_load
17209         restore_lustre_params < $p
17210         rm -f $p
17211 }
17212 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17213
17214 test_155h() {
17215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17216
17217         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17218
17219         save_writethrough $p
17220
17221         set_cache read off
17222         set_cache writethrough off
17223         test_155_big_load
17224         restore_lustre_params < $p
17225         rm -f $p
17226 }
17227 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17228
17229 test_156() {
17230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17231         remote_ost_nodsh && skip "remote OST with nodsh"
17232         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17233                 skip "stats not implemented on old servers"
17234         [ "$ost1_FSTYPE" = "zfs" ] &&
17235                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17236         (( CLIENT_VERSION == OST1_VERSION )) ||
17237                 skip "LU-13081: no interop testing for OSS cache"
17238
17239         local CPAGES=3
17240         local BEFORE
17241         local AFTER
17242         local file="$DIR/$tfile"
17243         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17244
17245         save_writethrough $p
17246         roc_hit_init
17247
17248         log "Turn on read and write cache"
17249         set_cache read on
17250         set_cache writethrough on
17251
17252         log "Write data and read it back."
17253         log "Read should be satisfied from the cache."
17254         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17255         BEFORE=$(roc_hit)
17256         cancel_lru_locks osc
17257         cat $file >/dev/null
17258         AFTER=$(roc_hit)
17259         if ! let "AFTER - BEFORE == CPAGES"; then
17260                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17261         else
17262                 log "cache hits: before: $BEFORE, after: $AFTER"
17263         fi
17264
17265         log "Read again; it should be satisfied from the cache."
17266         BEFORE=$AFTER
17267         cancel_lru_locks osc
17268         cat $file >/dev/null
17269         AFTER=$(roc_hit)
17270         if ! let "AFTER - BEFORE == CPAGES"; then
17271                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17272         else
17273                 log "cache hits:: before: $BEFORE, after: $AFTER"
17274         fi
17275
17276         log "Turn off the read cache and turn on the write cache"
17277         set_cache read off
17278         set_cache writethrough on
17279
17280         log "Read again; it should be satisfied from the cache."
17281         BEFORE=$(roc_hit)
17282         cancel_lru_locks osc
17283         cat $file >/dev/null
17284         AFTER=$(roc_hit)
17285         if ! let "AFTER - BEFORE == CPAGES"; then
17286                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17287         else
17288                 log "cache hits:: before: $BEFORE, after: $AFTER"
17289         fi
17290
17291         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17292                 # > 2.12.56 uses pagecache if cached
17293                 log "Read again; it should not be satisfied from the cache."
17294                 BEFORE=$AFTER
17295                 cancel_lru_locks osc
17296                 cat $file >/dev/null
17297                 AFTER=$(roc_hit)
17298                 if ! let "AFTER - BEFORE == 0"; then
17299                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17300                 else
17301                         log "cache hits:: before: $BEFORE, after: $AFTER"
17302                 fi
17303         fi
17304
17305         log "Write data and read it back."
17306         log "Read should be satisfied from the cache."
17307         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17308         BEFORE=$(roc_hit)
17309         cancel_lru_locks osc
17310         cat $file >/dev/null
17311         AFTER=$(roc_hit)
17312         if ! let "AFTER - BEFORE == CPAGES"; then
17313                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17314         else
17315                 log "cache hits:: before: $BEFORE, after: $AFTER"
17316         fi
17317
17318         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17319                 # > 2.12.56 uses pagecache if cached
17320                 log "Read again; it should not be satisfied from the cache."
17321                 BEFORE=$AFTER
17322                 cancel_lru_locks osc
17323                 cat $file >/dev/null
17324                 AFTER=$(roc_hit)
17325                 if ! let "AFTER - BEFORE == 0"; then
17326                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17327                 else
17328                         log "cache hits:: before: $BEFORE, after: $AFTER"
17329                 fi
17330         fi
17331
17332         log "Turn off read and write cache"
17333         set_cache read off
17334         set_cache writethrough off
17335
17336         log "Write data and read it back"
17337         log "It should not be satisfied from the cache."
17338         rm -f $file
17339         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17340         cancel_lru_locks osc
17341         BEFORE=$(roc_hit)
17342         cat $file >/dev/null
17343         AFTER=$(roc_hit)
17344         if ! let "AFTER - BEFORE == 0"; then
17345                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17346         else
17347                 log "cache hits:: before: $BEFORE, after: $AFTER"
17348         fi
17349
17350         log "Turn on the read cache and turn off the write cache"
17351         set_cache read on
17352         set_cache writethrough off
17353
17354         log "Write data and read it back"
17355         log "It should not be satisfied from the cache."
17356         rm -f $file
17357         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17358         BEFORE=$(roc_hit)
17359         cancel_lru_locks osc
17360         cat $file >/dev/null
17361         AFTER=$(roc_hit)
17362         if ! let "AFTER - BEFORE == 0"; then
17363                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17364         else
17365                 log "cache hits:: before: $BEFORE, after: $AFTER"
17366         fi
17367
17368         log "Read again; it should be satisfied from the cache."
17369         BEFORE=$(roc_hit)
17370         cancel_lru_locks osc
17371         cat $file >/dev/null
17372         AFTER=$(roc_hit)
17373         if ! let "AFTER - BEFORE == CPAGES"; then
17374                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17375         else
17376                 log "cache hits:: before: $BEFORE, after: $AFTER"
17377         fi
17378
17379         restore_lustre_params < $p
17380         rm -f $p $file
17381 }
17382 run_test 156 "Verification of tunables"
17383
17384 test_160a() {
17385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17386         remote_mds_nodsh && skip "remote MDS with nodsh"
17387         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17388                 skip "Need MDS version at least 2.2.0"
17389
17390         changelog_register || error "changelog_register failed"
17391         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17392         changelog_users $SINGLEMDS | grep -q $cl_user ||
17393                 error "User $cl_user not found in changelog_users"
17394
17395         mkdir_on_mdt0 $DIR/$tdir
17396
17397         # change something
17398         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17399         changelog_clear 0 || error "changelog_clear failed"
17400         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17401         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17402         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17403         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17404         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17405         rm $DIR/$tdir/pics/desktop.jpg
17406
17407         echo "verifying changelog mask"
17408         changelog_chmask "-MKDIR"
17409         changelog_chmask "-CLOSE"
17410
17411         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17412         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17413
17414         changelog_chmask "+MKDIR"
17415         changelog_chmask "+CLOSE"
17416
17417         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17418         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17419
17420         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17421         CLOSES=$(changelog_dump | grep -c "CLOSE")
17422         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17423         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17424
17425         # verify contents
17426         echo "verifying target fid"
17427         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17428         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17429         [ "$fidc" == "$fidf" ] ||
17430                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17431         echo "verifying parent fid"
17432         # The FID returned from the Changelog may be the directory shard on
17433         # a different MDT, and not the FID returned by path2fid on the parent.
17434         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17435         # since this is what will matter when recreating this file in the tree.
17436         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17437         local pathp=$($LFS fid2path $MOUNT "$fidp")
17438         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17439                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17440
17441         echo "getting records for $cl_user"
17442         changelog_users $SINGLEMDS
17443         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17444         local nclr=3
17445         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17446                 error "changelog_clear failed"
17447         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17448         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17449         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17450                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17451
17452         local min0_rec=$(changelog_users $SINGLEMDS |
17453                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17454         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17455                           awk '{ print $1; exit; }')
17456
17457         changelog_dump | tail -n 5
17458         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17459         [ $first_rec == $((min0_rec + 1)) ] ||
17460                 error "first index should be $min0_rec + 1 not $first_rec"
17461
17462         # LU-3446 changelog index reset on MDT restart
17463         local cur_rec1=$(changelog_users $SINGLEMDS |
17464                          awk '/^current.index:/ { print $NF }')
17465         changelog_clear 0 ||
17466                 error "clear all changelog records for $cl_user failed"
17467         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17468         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17469                 error "Fail to start $SINGLEMDS"
17470         local cur_rec2=$(changelog_users $SINGLEMDS |
17471                          awk '/^current.index:/ { print $NF }')
17472         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17473         [ $cur_rec1 == $cur_rec2 ] ||
17474                 error "current index should be $cur_rec1 not $cur_rec2"
17475
17476         echo "verifying users from this test are deregistered"
17477         changelog_deregister || error "changelog_deregister failed"
17478         changelog_users $SINGLEMDS | grep -q $cl_user &&
17479                 error "User '$cl_user' still in changelog_users"
17480
17481         # lctl get_param -n mdd.*.changelog_users
17482         # current_index: 144
17483         # ID    index (idle seconds)
17484         # cl3   144   (2) mask=<list>
17485         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17486                 # this is the normal case where all users were deregistered
17487                 # make sure no new records are added when no users are present
17488                 local last_rec1=$(changelog_users $SINGLEMDS |
17489                                   awk '/^current.index:/ { print $NF }')
17490                 touch $DIR/$tdir/chloe
17491                 local last_rec2=$(changelog_users $SINGLEMDS |
17492                                   awk '/^current.index:/ { print $NF }')
17493                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17494                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17495         else
17496                 # any changelog users must be leftovers from a previous test
17497                 changelog_users $SINGLEMDS
17498                 echo "other changelog users; can't verify off"
17499         fi
17500 }
17501 run_test 160a "changelog sanity"
17502
17503 test_160b() { # LU-3587
17504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17505         remote_mds_nodsh && skip "remote MDS with nodsh"
17506         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17507                 skip "Need MDS version at least 2.2.0"
17508
17509         changelog_register || error "changelog_register failed"
17510         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17511         changelog_users $SINGLEMDS | grep -q $cl_user ||
17512                 error "User '$cl_user' not found in changelog_users"
17513
17514         local longname1=$(str_repeat a 255)
17515         local longname2=$(str_repeat b 255)
17516
17517         cd $DIR
17518         echo "creating very long named file"
17519         touch $longname1 || error "create of '$longname1' failed"
17520         echo "renaming very long named file"
17521         mv $longname1 $longname2
17522
17523         changelog_dump | grep RENME | tail -n 5
17524         rm -f $longname2
17525 }
17526 run_test 160b "Verify that very long rename doesn't crash in changelog"
17527
17528 test_160c() {
17529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17530         remote_mds_nodsh && skip "remote MDS with nodsh"
17531
17532         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17533                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17534                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17535                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17536
17537         local rc=0
17538
17539         # Registration step
17540         changelog_register || error "changelog_register failed"
17541
17542         rm -rf $DIR/$tdir
17543         mkdir -p $DIR/$tdir
17544         $MCREATE $DIR/$tdir/foo_160c
17545         changelog_chmask "-TRUNC"
17546         $TRUNCATE $DIR/$tdir/foo_160c 200
17547         changelog_chmask "+TRUNC"
17548         $TRUNCATE $DIR/$tdir/foo_160c 199
17549         changelog_dump | tail -n 5
17550         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17551         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17552 }
17553 run_test 160c "verify that changelog log catch the truncate event"
17554
17555 test_160d() {
17556         remote_mds_nodsh && skip "remote MDS with nodsh"
17557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17559         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17560                 skip "Need MDS version at least 2.7.60"
17561
17562         # Registration step
17563         changelog_register || error "changelog_register failed"
17564
17565         mkdir -p $DIR/$tdir/migrate_dir
17566         changelog_clear 0 || error "changelog_clear failed"
17567
17568         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17569         changelog_dump | tail -n 5
17570         local migrates=$(changelog_dump | grep -c "MIGRT")
17571         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17572 }
17573 run_test 160d "verify that changelog log catch the migrate event"
17574
17575 test_160e() {
17576         remote_mds_nodsh && skip "remote MDS with nodsh"
17577
17578         # Create a user
17579         changelog_register || error "changelog_register failed"
17580
17581         local MDT0=$(facet_svc $SINGLEMDS)
17582         local rc
17583
17584         # No user (expect fail)
17585         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17586         rc=$?
17587         if [ $rc -eq 0 ]; then
17588                 error "Should fail without user"
17589         elif [ $rc -ne 4 ]; then
17590                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17591         fi
17592
17593         # Delete a future user (expect fail)
17594         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17595         rc=$?
17596         if [ $rc -eq 0 ]; then
17597                 error "Deleted non-existant user cl77"
17598         elif [ $rc -ne 2 ]; then
17599                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17600         fi
17601
17602         # Clear to a bad index (1 billion should be safe)
17603         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17604         rc=$?
17605
17606         if [ $rc -eq 0 ]; then
17607                 error "Successfully cleared to invalid CL index"
17608         elif [ $rc -ne 22 ]; then
17609                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17610         fi
17611 }
17612 run_test 160e "changelog negative testing (should return errors)"
17613
17614 test_160f() {
17615         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17616         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17617                 skip "Need MDS version at least 2.10.56"
17618
17619         local mdts=$(comma_list $(mdts_nodes))
17620
17621         # Create a user
17622         changelog_register || error "first changelog_register failed"
17623         changelog_register || error "second changelog_register failed"
17624         local cl_users
17625         declare -A cl_user1
17626         declare -A cl_user2
17627         local user_rec1
17628         local user_rec2
17629         local i
17630
17631         # generate some changelog records to accumulate on each MDT
17632         # use all_char because created files should be evenly distributed
17633         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17634                 error "test_mkdir $tdir failed"
17635         log "$(date +%s): creating first files"
17636         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17637                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17638                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17639         done
17640
17641         # check changelogs have been generated
17642         local start=$SECONDS
17643         local idle_time=$((MDSCOUNT * 5 + 5))
17644         local nbcl=$(changelog_dump | wc -l)
17645         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17646
17647         for param in "changelog_max_idle_time=$idle_time" \
17648                      "changelog_gc=1" \
17649                      "changelog_min_gc_interval=2" \
17650                      "changelog_min_free_cat_entries=3"; do
17651                 local MDT0=$(facet_svc $SINGLEMDS)
17652                 local var="${param%=*}"
17653                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17654
17655                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17656                 do_nodes $mdts $LCTL set_param mdd.*.$param
17657         done
17658
17659         # force cl_user2 to be idle (1st part), but also cancel the
17660         # cl_user1 records so that it is not evicted later in the test.
17661         local sleep1=$((idle_time / 2))
17662         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17663         sleep $sleep1
17664
17665         # simulate changelog catalog almost full
17666         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17667         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17668
17669         for i in $(seq $MDSCOUNT); do
17670                 cl_users=(${CL_USERS[mds$i]})
17671                 cl_user1[mds$i]="${cl_users[0]}"
17672                 cl_user2[mds$i]="${cl_users[1]}"
17673
17674                 [ -n "${cl_user1[mds$i]}" ] ||
17675                         error "mds$i: no user registered"
17676                 [ -n "${cl_user2[mds$i]}" ] ||
17677                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17678
17679                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17680                 [ -n "$user_rec1" ] ||
17681                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17682                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17683                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17684                 [ -n "$user_rec2" ] ||
17685                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17686                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17687                      "$user_rec1 + 2 == $user_rec2"
17688                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17689                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17690                               "$user_rec1 + 2, but is $user_rec2"
17691                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17692                 [ -n "$user_rec2" ] ||
17693                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17694                 [ $user_rec1 == $user_rec2 ] ||
17695                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17696                               "$user_rec1, but is $user_rec2"
17697         done
17698
17699         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17700         local sleep2=$((idle_time - (SECONDS - start) + 1))
17701         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17702         sleep $sleep2
17703
17704         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17705         # cl_user1 should be OK because it recently processed records.
17706         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17707         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17708                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17709                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17710         done
17711
17712         # ensure gc thread is done
17713         for i in $(mdts_nodes); do
17714                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17715                         error "$i: GC-thread not done"
17716         done
17717
17718         local first_rec
17719         for (( i = 1; i <= MDSCOUNT; i++ )); do
17720                 # check cl_user1 still registered
17721                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17722                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17723                 # check cl_user2 unregistered
17724                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17725                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17726
17727                 # check changelogs are present and starting at $user_rec1 + 1
17728                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17729                 [ -n "$user_rec1" ] ||
17730                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17731                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17732                             awk '{ print $1; exit; }')
17733
17734                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17735                 [ $((user_rec1 + 1)) == $first_rec ] ||
17736                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17737         done
17738 }
17739 run_test 160f "changelog garbage collect (timestamped users)"
17740
17741 test_160g() {
17742         remote_mds_nodsh && skip "remote MDS with nodsh"
17743         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17744                 skip "Need MDS version at least 2.14.55"
17745
17746         local mdts=$(comma_list $(mdts_nodes))
17747
17748         # Create a user
17749         changelog_register || error "first changelog_register failed"
17750         changelog_register || error "second changelog_register failed"
17751         local cl_users
17752         declare -A cl_user1
17753         declare -A cl_user2
17754         local user_rec1
17755         local user_rec2
17756         local i
17757
17758         # generate some changelog records to accumulate on each MDT
17759         # use all_char because created files should be evenly distributed
17760         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17761                 error "test_mkdir $tdir failed"
17762         for ((i = 0; i < MDSCOUNT; i++)); do
17763                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17764                         error "create $DIR/$tdir/d$i.1 failed"
17765         done
17766
17767         # check changelogs have been generated
17768         local nbcl=$(changelog_dump | wc -l)
17769         (( $nbcl > 0 )) || error "no changelogs found"
17770
17771         # reduce the max_idle_indexes value to make sure we exceed it
17772         for param in "changelog_max_idle_indexes=2" \
17773                      "changelog_gc=1" \
17774                      "changelog_min_gc_interval=2"; do
17775                 local MDT0=$(facet_svc $SINGLEMDS)
17776                 local var="${param%=*}"
17777                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17778
17779                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17780                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17781                         error "unable to set mdd.*.$param"
17782         done
17783
17784         local start=$SECONDS
17785         for i in $(seq $MDSCOUNT); do
17786                 cl_users=(${CL_USERS[mds$i]})
17787                 cl_user1[mds$i]="${cl_users[0]}"
17788                 cl_user2[mds$i]="${cl_users[1]}"
17789
17790                 [ -n "${cl_user1[mds$i]}" ] ||
17791                         error "mds$i: user1 is not registered"
17792                 [ -n "${cl_user2[mds$i]}" ] ||
17793                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17794
17795                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17796                 [ -n "$user_rec1" ] ||
17797                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17798                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17799                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17800                 [ -n "$user_rec2" ] ||
17801                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17802                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17803                      "$user_rec1 + 2 == $user_rec2"
17804                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17805                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17806                               "expected $user_rec1 + 2, but is $user_rec2"
17807                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17808                 [ -n "$user_rec2" ] ||
17809                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17810                 [ $user_rec1 == $user_rec2 ] ||
17811                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17812                               "expected $user_rec1, but is $user_rec2"
17813         done
17814
17815         # ensure we are past the previous changelog_min_gc_interval set above
17816         local sleep2=$((start + 2 - SECONDS))
17817         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17818         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17819         # cl_user1 should be OK because it recently processed records.
17820         for ((i = 0; i < MDSCOUNT; i++)); do
17821                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17822                         error "create $DIR/$tdir/d$i.3 failed"
17823         done
17824
17825         # ensure gc thread is done
17826         for i in $(mdts_nodes); do
17827                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17828                         error "$i: GC-thread not done"
17829         done
17830
17831         local first_rec
17832         for (( i = 1; i <= MDSCOUNT; i++ )); do
17833                 # check cl_user1 still registered
17834                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17835                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17836                 # check cl_user2 unregistered
17837                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17838                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17839
17840                 # check changelogs are present and starting at $user_rec1 + 1
17841                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17842                 [ -n "$user_rec1" ] ||
17843                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17844                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17845                             awk '{ print $1; exit; }')
17846
17847                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17848                 [ $((user_rec1 + 1)) == $first_rec ] ||
17849                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17850         done
17851 }
17852 run_test 160g "changelog garbage collect on idle records"
17853
17854 test_160h() {
17855         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17856         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17857                 skip "Need MDS version at least 2.10.56"
17858
17859         local mdts=$(comma_list $(mdts_nodes))
17860
17861         # Create a user
17862         changelog_register || error "first changelog_register failed"
17863         changelog_register || error "second changelog_register failed"
17864         local cl_users
17865         declare -A cl_user1
17866         declare -A cl_user2
17867         local user_rec1
17868         local user_rec2
17869         local i
17870
17871         # generate some changelog records to accumulate on each MDT
17872         # use all_char because created files should be evenly distributed
17873         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17874                 error "test_mkdir $tdir failed"
17875         for ((i = 0; i < MDSCOUNT; i++)); do
17876                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17877                         error "create $DIR/$tdir/d$i.1 failed"
17878         done
17879
17880         # check changelogs have been generated
17881         local nbcl=$(changelog_dump | wc -l)
17882         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17883
17884         for param in "changelog_max_idle_time=10" \
17885                      "changelog_gc=1" \
17886                      "changelog_min_gc_interval=2"; do
17887                 local MDT0=$(facet_svc $SINGLEMDS)
17888                 local var="${param%=*}"
17889                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17890
17891                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17892                 do_nodes $mdts $LCTL set_param mdd.*.$param
17893         done
17894
17895         # force cl_user2 to be idle (1st part)
17896         sleep 9
17897
17898         for i in $(seq $MDSCOUNT); do
17899                 cl_users=(${CL_USERS[mds$i]})
17900                 cl_user1[mds$i]="${cl_users[0]}"
17901                 cl_user2[mds$i]="${cl_users[1]}"
17902
17903                 [ -n "${cl_user1[mds$i]}" ] ||
17904                         error "mds$i: no user registered"
17905                 [ -n "${cl_user2[mds$i]}" ] ||
17906                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17907
17908                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17909                 [ -n "$user_rec1" ] ||
17910                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17911                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17912                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17913                 [ -n "$user_rec2" ] ||
17914                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17915                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17916                      "$user_rec1 + 2 == $user_rec2"
17917                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17918                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17919                               "$user_rec1 + 2, but is $user_rec2"
17920                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17921                 [ -n "$user_rec2" ] ||
17922                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17923                 [ $user_rec1 == $user_rec2 ] ||
17924                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17925                               "$user_rec1, but is $user_rec2"
17926         done
17927
17928         # force cl_user2 to be idle (2nd part) and to reach
17929         # changelog_max_idle_time
17930         sleep 2
17931
17932         # force each GC-thread start and block then
17933         # one per MDT/MDD, set fail_val accordingly
17934         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17935         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17936
17937         # generate more changelogs to trigger fail_loc
17938         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17939                 error "create $DIR/$tdir/${tfile}bis failed"
17940
17941         # stop MDT to stop GC-thread, should be done in back-ground as it will
17942         # block waiting for the thread to be released and exit
17943         declare -A stop_pids
17944         for i in $(seq $MDSCOUNT); do
17945                 stop mds$i &
17946                 stop_pids[mds$i]=$!
17947         done
17948
17949         for i in $(mdts_nodes); do
17950                 local facet
17951                 local nb=0
17952                 local facets=$(facets_up_on_host $i)
17953
17954                 for facet in ${facets//,/ }; do
17955                         if [[ $facet == mds* ]]; then
17956                                 nb=$((nb + 1))
17957                         fi
17958                 done
17959                 # ensure each MDS's gc threads are still present and all in "R"
17960                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17961                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17962                         error "$i: expected $nb GC-thread"
17963                 wait_update $i \
17964                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17965                         "R" 20 ||
17966                         error "$i: GC-thread not found in R-state"
17967                 # check umounts of each MDT on MDS have reached kthread_stop()
17968                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17969                         error "$i: expected $nb umount"
17970                 wait_update $i \
17971                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17972                         error "$i: umount not found in D-state"
17973         done
17974
17975         # release all GC-threads
17976         do_nodes $mdts $LCTL set_param fail_loc=0
17977
17978         # wait for MDT stop to complete
17979         for i in $(seq $MDSCOUNT); do
17980                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17981         done
17982
17983         # XXX
17984         # may try to check if any orphan changelog records are present
17985         # via ldiskfs/zfs and llog_reader...
17986
17987         # re-start/mount MDTs
17988         for i in $(seq $MDSCOUNT); do
17989                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17990                         error "Fail to start mds$i"
17991         done
17992
17993         local first_rec
17994         for i in $(seq $MDSCOUNT); do
17995                 # check cl_user1 still registered
17996                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17997                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17998                 # check cl_user2 unregistered
17999                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18000                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18001
18002                 # check changelogs are present and starting at $user_rec1 + 1
18003                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18004                 [ -n "$user_rec1" ] ||
18005                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18006                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18007                             awk '{ print $1; exit; }')
18008
18009                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18010                 [ $((user_rec1 + 1)) == $first_rec ] ||
18011                         error "mds$i: first index should be $user_rec1 + 1, " \
18012                               "but is $first_rec"
18013         done
18014 }
18015 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18016               "during mount"
18017
18018 test_160i() {
18019
18020         local mdts=$(comma_list $(mdts_nodes))
18021
18022         changelog_register || error "first changelog_register failed"
18023
18024         # generate some changelog records to accumulate on each MDT
18025         # use all_char because created files should be evenly distributed
18026         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18027                 error "test_mkdir $tdir failed"
18028         for ((i = 0; i < MDSCOUNT; i++)); do
18029                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18030                         error "create $DIR/$tdir/d$i.1 failed"
18031         done
18032
18033         # check changelogs have been generated
18034         local nbcl=$(changelog_dump | wc -l)
18035         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18036
18037         # simulate race between register and unregister
18038         # XXX as fail_loc is set per-MDS, with DNE configs the race
18039         # simulation will only occur for one MDT per MDS and for the
18040         # others the normal race scenario will take place
18041         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18042         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18043         do_nodes $mdts $LCTL set_param fail_val=1
18044
18045         # unregister 1st user
18046         changelog_deregister &
18047         local pid1=$!
18048         # wait some time for deregister work to reach race rdv
18049         sleep 2
18050         # register 2nd user
18051         changelog_register || error "2nd user register failed"
18052
18053         wait $pid1 || error "1st user deregister failed"
18054
18055         local i
18056         local last_rec
18057         declare -A LAST_REC
18058         for i in $(seq $MDSCOUNT); do
18059                 if changelog_users mds$i | grep "^cl"; then
18060                         # make sure new records are added with one user present
18061                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18062                                           awk '/^current.index:/ { print $NF }')
18063                 else
18064                         error "mds$i has no user registered"
18065                 fi
18066         done
18067
18068         # generate more changelog records to accumulate on each MDT
18069         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18070                 error "create $DIR/$tdir/${tfile}bis failed"
18071
18072         for i in $(seq $MDSCOUNT); do
18073                 last_rec=$(changelog_users $SINGLEMDS |
18074                            awk '/^current.index:/ { print $NF }')
18075                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18076                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18077                         error "changelogs are off on mds$i"
18078         done
18079 }
18080 run_test 160i "changelog user register/unregister race"
18081
18082 test_160j() {
18083         remote_mds_nodsh && skip "remote MDS with nodsh"
18084         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18085                 skip "Need MDS version at least 2.12.56"
18086
18087         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18088         stack_trap "umount $MOUNT2" EXIT
18089
18090         changelog_register || error "first changelog_register failed"
18091         stack_trap "changelog_deregister" EXIT
18092
18093         # generate some changelog
18094         # use all_char because created files should be evenly distributed
18095         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18096                 error "mkdir $tdir failed"
18097         for ((i = 0; i < MDSCOUNT; i++)); do
18098                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18099                         error "create $DIR/$tdir/d$i.1 failed"
18100         done
18101
18102         # open the changelog device
18103         exec 3>/dev/changelog-$FSNAME-MDT0000
18104         stack_trap "exec 3>&-" EXIT
18105         exec 4</dev/changelog-$FSNAME-MDT0000
18106         stack_trap "exec 4<&-" EXIT
18107
18108         # umount the first lustre mount
18109         umount $MOUNT
18110         stack_trap "mount_client $MOUNT" EXIT
18111
18112         # read changelog, which may or may not fail, but should not crash
18113         cat <&4 >/dev/null
18114
18115         # clear changelog
18116         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18117         changelog_users $SINGLEMDS | grep -q $cl_user ||
18118                 error "User $cl_user not found in changelog_users"
18119
18120         printf 'clear:'$cl_user':0' >&3
18121 }
18122 run_test 160j "client can be umounted while its chanangelog is being used"
18123
18124 test_160k() {
18125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18126         remote_mds_nodsh && skip "remote MDS with nodsh"
18127
18128         mkdir -p $DIR/$tdir/1/1
18129
18130         changelog_register || error "changelog_register failed"
18131         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18132
18133         changelog_users $SINGLEMDS | grep -q $cl_user ||
18134                 error "User '$cl_user' not found in changelog_users"
18135 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18136         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18137         rmdir $DIR/$tdir/1/1 & sleep 1
18138         mkdir $DIR/$tdir/2
18139         touch $DIR/$tdir/2/2
18140         rm -rf $DIR/$tdir/2
18141
18142         wait
18143         sleep 4
18144
18145         changelog_dump | grep rmdir || error "rmdir not recorded"
18146 }
18147 run_test 160k "Verify that changelog records are not lost"
18148
18149 # Verifies that a file passed as a parameter has recently had an operation
18150 # performed on it that has generated an MTIME changelog which contains the
18151 # correct parent FID. As files might reside on a different MDT from the
18152 # parent directory in DNE configurations, the FIDs are translated to paths
18153 # before being compared, which should be identical
18154 compare_mtime_changelog() {
18155         local file="${1}"
18156         local mdtidx
18157         local mtime
18158         local cl_fid
18159         local pdir
18160         local dir
18161
18162         mdtidx=$($LFS getstripe --mdt-index $file)
18163         mdtidx=$(printf "%04x" $mdtidx)
18164
18165         # Obtain the parent FID from the MTIME changelog
18166         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18167         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18168
18169         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18170         [ -z "$cl_fid" ] && error "parent FID not present"
18171
18172         # Verify that the path for the parent FID is the same as the path for
18173         # the test directory
18174         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18175
18176         dir=$(dirname $1)
18177
18178         [[ "${pdir%/}" == "$dir" ]] ||
18179                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18180 }
18181
18182 test_160l() {
18183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18184
18185         remote_mds_nodsh && skip "remote MDS with nodsh"
18186         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18187                 skip "Need MDS version at least 2.13.55"
18188
18189         local cl_user
18190
18191         changelog_register || error "changelog_register failed"
18192         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18193
18194         changelog_users $SINGLEMDS | grep -q $cl_user ||
18195                 error "User '$cl_user' not found in changelog_users"
18196
18197         # Clear some types so that MTIME changelogs are generated
18198         changelog_chmask "-CREAT"
18199         changelog_chmask "-CLOSE"
18200
18201         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18202
18203         # Test CL_MTIME during setattr
18204         touch $DIR/$tdir/$tfile
18205         compare_mtime_changelog $DIR/$tdir/$tfile
18206
18207         # Test CL_MTIME during close
18208         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18209         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18210 }
18211 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18212
18213 test_160m() {
18214         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18215         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18216                 skip "Need MDS version at least 2.14.51"
18217         local cl_users
18218         local cl_user1
18219         local cl_user2
18220         local pid1
18221
18222         # Create a user
18223         changelog_register || error "first changelog_register failed"
18224         changelog_register || error "second changelog_register failed"
18225
18226         cl_users=(${CL_USERS[mds1]})
18227         cl_user1="${cl_users[0]}"
18228         cl_user2="${cl_users[1]}"
18229         # generate some changelog records to accumulate on MDT0
18230         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18231         createmany -m $DIR/$tdir/$tfile 50 ||
18232                 error "create $DIR/$tdir/$tfile failed"
18233         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18234         rm -f $DIR/$tdir
18235
18236         # check changelogs have been generated
18237         local nbcl=$(changelog_dump | wc -l)
18238         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18239
18240 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18241         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18242
18243         __changelog_clear mds1 $cl_user1 +10
18244         __changelog_clear mds1 $cl_user2 0 &
18245         pid1=$!
18246         sleep 2
18247         __changelog_clear mds1 $cl_user1 0 ||
18248                 error "fail to cancel record for $cl_user1"
18249         wait $pid1
18250         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18251 }
18252 run_test 160m "Changelog clear race"
18253
18254 test_160n() {
18255         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18256         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18257                 skip "Need MDS version at least 2.14.51"
18258         local cl_users
18259         local cl_user1
18260         local cl_user2
18261         local pid1
18262         local first_rec
18263         local last_rec=0
18264
18265         # Create a user
18266         changelog_register || error "first changelog_register failed"
18267
18268         cl_users=(${CL_USERS[mds1]})
18269         cl_user1="${cl_users[0]}"
18270
18271         # generate some changelog records to accumulate on MDT0
18272         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18273         first_rec=$(changelog_users $SINGLEMDS |
18274                         awk '/^current.index:/ { print $NF }')
18275         while (( last_rec < (( first_rec + 65000)) )); do
18276                 createmany -m $DIR/$tdir/$tfile 10000 ||
18277                         error "create $DIR/$tdir/$tfile failed"
18278
18279                 for i in $(seq 0 10000); do
18280                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18281                                 > /dev/null
18282                 done
18283
18284                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18285                         error "unlinkmany failed unlink"
18286                 last_rec=$(changelog_users $SINGLEMDS |
18287                         awk '/^current.index:/ { print $NF }')
18288                 echo last record $last_rec
18289                 (( last_rec == 0 )) && error "no changelog found"
18290         done
18291
18292 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18293         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18294
18295         __changelog_clear mds1 $cl_user1 0 &
18296         pid1=$!
18297         sleep 2
18298         __changelog_clear mds1 $cl_user1 0 ||
18299                 error "fail to cancel record for $cl_user1"
18300         wait $pid1
18301         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18302 }
18303 run_test 160n "Changelog destroy race"
18304
18305 test_160o() {
18306         local mdt="$(facet_svc $SINGLEMDS)"
18307
18308         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18309         remote_mds_nodsh && skip "remote MDS with nodsh"
18310         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18311                 skip "Need MDS version at least 2.14.52"
18312
18313         changelog_register --user test_160o -m unlnk+close+open ||
18314                 error "changelog_register failed"
18315
18316         do_facet $SINGLEMDS $LCTL --device $mdt \
18317                                 changelog_register -u "Tt3_-#" &&
18318                 error "bad symbols in name should fail"
18319
18320         do_facet $SINGLEMDS $LCTL --device $mdt \
18321                                 changelog_register -u test_160o &&
18322                 error "the same name registration should fail"
18323
18324         do_facet $SINGLEMDS $LCTL --device $mdt \
18325                         changelog_register -u test_160toolongname &&
18326                 error "too long name registration should fail"
18327
18328         changelog_chmask "MARK+HSM"
18329         lctl get_param mdd.*.changelog*mask
18330         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18331         changelog_users $SINGLEMDS | grep -q $cl_user ||
18332                 error "User $cl_user not found in changelog_users"
18333         #verify username
18334         echo $cl_user | grep -q test_160o ||
18335                 error "User $cl_user has no specific name 'test160o'"
18336
18337         # change something
18338         changelog_clear 0 || error "changelog_clear failed"
18339         # generate some changelog records to accumulate on MDT0
18340         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18341         touch $DIR/$tdir/$tfile                 # open 1
18342
18343         OPENS=$(changelog_dump | grep -c "OPEN")
18344         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18345
18346         # must be no MKDIR it wasn't set as user mask
18347         MKDIR=$(changelog_dump | grep -c "MKDIR")
18348         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18349
18350         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18351                                 mdd.$mdt.changelog_current_mask -n)
18352         # register maskless user
18353         changelog_register || error "changelog_register failed"
18354         # effective mask should be not changed because it is not minimal
18355         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18356                                 mdd.$mdt.changelog_current_mask -n)
18357         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18358         # set server mask to minimal value
18359         changelog_chmask "MARK"
18360         # check effective mask again, should be treated as DEFMASK now
18361         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18362                                 mdd.$mdt.changelog_current_mask -n)
18363         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18364
18365         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18366                 # set server mask back to some value
18367                 changelog_chmask "CLOSE,UNLNK"
18368                 # check effective mask again, should not remain as DEFMASK
18369                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18370                                 mdd.$mdt.changelog_current_mask -n)
18371                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18372         fi
18373
18374         do_facet $SINGLEMDS $LCTL --device $mdt \
18375                                 changelog_deregister -u test_160o ||
18376                 error "cannot deregister by name"
18377 }
18378 run_test 160o "changelog user name and mask"
18379
18380 test_160p() {
18381         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18382         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18383                 skip "Need MDS version at least 2.14.51"
18384         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18385         local cl_users
18386         local cl_user1
18387         local entry_count
18388
18389         # Create a user
18390         changelog_register || error "first changelog_register failed"
18391
18392         cl_users=(${CL_USERS[mds1]})
18393         cl_user1="${cl_users[0]}"
18394
18395         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18396         createmany -m $DIR/$tdir/$tfile 50 ||
18397                 error "create $DIR/$tdir/$tfile failed"
18398         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18399         rm -rf $DIR/$tdir
18400
18401         # check changelogs have been generated
18402         entry_count=$(changelog_dump | wc -l)
18403         ((entry_count != 0)) || error "no changelog entries found"
18404
18405         # remove changelog_users and check that orphan entries are removed
18406         stop mds1
18407         local dev=$(mdsdevname 1)
18408         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18409         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18410         entry_count=$(changelog_dump | wc -l)
18411         ((entry_count == 0)) ||
18412                 error "found $entry_count changelog entries, expected none"
18413 }
18414 run_test 160p "Changelog orphan cleanup with no users"
18415
18416 test_160q() {
18417         local mdt="$(facet_svc $SINGLEMDS)"
18418         local clu
18419
18420         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18421         remote_mds_nodsh && skip "remote MDS with nodsh"
18422         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18423                 skip "Need MDS version at least 2.14.54"
18424
18425         # set server mask to minimal value like server init does
18426         changelog_chmask "MARK"
18427         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18428                 error "changelog_register failed"
18429         # check effective mask again, should be treated as DEFMASK now
18430         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18431                                 mdd.$mdt.changelog_current_mask -n)
18432         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18433                 error "changelog_deregister failed"
18434         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18435 }
18436 run_test 160q "changelog effective mask is DEFMASK if not set"
18437
18438 test_160s() {
18439         remote_mds_nodsh && skip "remote MDS with nodsh"
18440         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18441                 skip "Need MDS version at least 2.14.55"
18442
18443         local mdts=$(comma_list $(mdts_nodes))
18444
18445         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18446         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18447                                        fail_val=$((24 * 3600 * 10))
18448
18449         # Create a user which is 10 days old
18450         changelog_register || error "first changelog_register failed"
18451         local cl_users
18452         declare -A cl_user1
18453         local i
18454
18455         # generate some changelog records to accumulate on each MDT
18456         # use all_char because created files should be evenly distributed
18457         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18458                 error "test_mkdir $tdir failed"
18459         for ((i = 0; i < MDSCOUNT; i++)); do
18460                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18461                         error "create $DIR/$tdir/d$i.1 failed"
18462         done
18463
18464         # check changelogs have been generated
18465         local nbcl=$(changelog_dump | wc -l)
18466         (( nbcl > 0 )) || error "no changelogs found"
18467
18468         # reduce the max_idle_indexes value to make sure we exceed it
18469         for param in "changelog_max_idle_indexes=2097446912" \
18470                      "changelog_max_idle_time=2592000" \
18471                      "changelog_gc=1" \
18472                      "changelog_min_gc_interval=2"; do
18473                 local MDT0=$(facet_svc $SINGLEMDS)
18474                 local var="${param%=*}"
18475                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18476
18477                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18478                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18479                         error "unable to set mdd.*.$param"
18480         done
18481
18482         local start=$SECONDS
18483         for i in $(seq $MDSCOUNT); do
18484                 cl_users=(${CL_USERS[mds$i]})
18485                 cl_user1[mds$i]="${cl_users[0]}"
18486
18487                 [[ -n "${cl_user1[mds$i]}" ]] ||
18488                         error "mds$i: no user registered"
18489         done
18490
18491         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18492         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18493
18494         # ensure we are past the previous changelog_min_gc_interval set above
18495         local sleep2=$((start + 2 - SECONDS))
18496         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18497
18498         # Generate one more changelog to trigger GC
18499         for ((i = 0; i < MDSCOUNT; i++)); do
18500                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18501                         error "create $DIR/$tdir/d$i.3 failed"
18502         done
18503
18504         # ensure gc thread is done
18505         for node in $(mdts_nodes); do
18506                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18507                         error "$node: GC-thread not done"
18508         done
18509
18510         do_nodes $mdts $LCTL set_param fail_loc=0
18511
18512         for (( i = 1; i <= MDSCOUNT; i++ )); do
18513                 # check cl_user1 is purged
18514                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18515                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18516         done
18517         return 0
18518 }
18519 run_test 160s "changelog garbage collect on idle records * time"
18520
18521 test_160t() {
18522         remote_mds_nodsh && skip "remote MDS with nodsh"
18523         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18524                 skip "Need MDS version at least 2.15.50"
18525
18526         local MDT0=$(facet_svc $SINGLEMDS)
18527         local cl_users
18528         local cl_user1
18529         local cl_user2
18530         local start
18531
18532         changelog_register --user user1 -m all ||
18533                 error "user1 failed to register"
18534
18535         mkdir_on_mdt0 $DIR/$tdir
18536         # create default overstripe to maximize changelog size
18537         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18538         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18539         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18540
18541         # user2 consumes less records so less space
18542         changelog_register --user user2 || error "user2 failed to register"
18543         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18544         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18545
18546         # check changelogs have been generated
18547         local nbcl=$(changelog_dump | wc -l)
18548         (( nbcl > 0 )) || error "no changelogs found"
18549
18550         # reduce the changelog_min_gc_interval to force check
18551         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18552                 local var="${param%=*}"
18553                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18554
18555                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18556                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18557                         error "unable to set mdd.*.$param"
18558         done
18559
18560         start=$SECONDS
18561         cl_users=(${CL_USERS[mds1]})
18562         cl_user1="${cl_users[0]}"
18563         cl_user2="${cl_users[1]}"
18564
18565         [[ -n $cl_user1 ]] ||
18566                 error "mds1: user #1 isn't registered"
18567         [[ -n $cl_user2 ]] ||
18568                 error "mds1: user #2 isn't registered"
18569
18570         # ensure we are past the previous changelog_min_gc_interval set above
18571         local sleep2=$((start + 2 - SECONDS))
18572         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18573
18574         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18575         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18576                         fail_val=$(((llog_size1 + llog_size2) / 2))
18577
18578         # Generate more changelog to trigger GC
18579         createmany -o $DIR/$tdir/u3_ 4 ||
18580                 error "create failed for more files"
18581
18582         # ensure gc thread is done
18583         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18584                 error "mds1: GC-thread not done"
18585
18586         do_facet mds1 $LCTL set_param fail_loc=0
18587
18588         # check cl_user1 is purged
18589         changelog_users mds1 | grep -q "$cl_user1" &&
18590                 error "User $cl_user1 is registered"
18591         # check cl_user2 is not purged
18592         changelog_users mds1 | grep -q "$cl_user2" ||
18593                 error "User $cl_user2 is not registered"
18594 }
18595 run_test 160t "changelog garbage collect on lack of space"
18596
18597 test_161a() {
18598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18599
18600         test_mkdir -c1 $DIR/$tdir
18601         cp /etc/hosts $DIR/$tdir/$tfile
18602         test_mkdir -c1 $DIR/$tdir/foo1
18603         test_mkdir -c1 $DIR/$tdir/foo2
18604         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18605         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18606         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18607         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18608         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18609         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18610                 $LFS fid2path $DIR $FID
18611                 error "bad link ea"
18612         fi
18613         # middle
18614         rm $DIR/$tdir/foo2/zachary
18615         # last
18616         rm $DIR/$tdir/foo2/thor
18617         # first
18618         rm $DIR/$tdir/$tfile
18619         # rename
18620         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18621         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18622                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18623         rm $DIR/$tdir/foo2/maggie
18624
18625         # overflow the EA
18626         local longname=$tfile.avg_len_is_thirty_two_
18627         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18628                 error_noexit 'failed to unlink many hardlinks'" EXIT
18629         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18630                 error "failed to hardlink many files"
18631         links=$($LFS fid2path $DIR $FID | wc -l)
18632         echo -n "${links}/1000 links in link EA"
18633         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18634 }
18635 run_test 161a "link ea sanity"
18636
18637 test_161b() {
18638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18639         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18640
18641         local MDTIDX=1
18642         local remote_dir=$DIR/$tdir/remote_dir
18643
18644         mkdir -p $DIR/$tdir
18645         $LFS mkdir -i $MDTIDX $remote_dir ||
18646                 error "create remote directory failed"
18647
18648         cp /etc/hosts $remote_dir/$tfile
18649         mkdir -p $remote_dir/foo1
18650         mkdir -p $remote_dir/foo2
18651         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18652         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18653         ln $remote_dir/$tfile $remote_dir/foo1/luna
18654         ln $remote_dir/$tfile $remote_dir/foo2/thor
18655
18656         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18657                      tr -d ']')
18658         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18659                 $LFS fid2path $DIR $FID
18660                 error "bad link ea"
18661         fi
18662         # middle
18663         rm $remote_dir/foo2/zachary
18664         # last
18665         rm $remote_dir/foo2/thor
18666         # first
18667         rm $remote_dir/$tfile
18668         # rename
18669         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18670         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18671         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18672                 $LFS fid2path $DIR $FID
18673                 error "bad link rename"
18674         fi
18675         rm $remote_dir/foo2/maggie
18676
18677         # overflow the EA
18678         local longname=filename_avg_len_is_thirty_two_
18679         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18680                 error "failed to hardlink many files"
18681         links=$($LFS fid2path $DIR $FID | wc -l)
18682         echo -n "${links}/1000 links in link EA"
18683         [[ ${links} -gt 60 ]] ||
18684                 error "expected at least 60 links in link EA"
18685         unlinkmany $remote_dir/foo2/$longname 1000 ||
18686         error "failed to unlink many hardlinks"
18687 }
18688 run_test 161b "link ea sanity under remote directory"
18689
18690 test_161c() {
18691         remote_mds_nodsh && skip "remote MDS with nodsh"
18692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18693         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18694                 skip "Need MDS version at least 2.1.5"
18695
18696         # define CLF_RENAME_LAST 0x0001
18697         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18698         changelog_register || error "changelog_register failed"
18699
18700         rm -rf $DIR/$tdir
18701         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18702         touch $DIR/$tdir/foo_161c
18703         touch $DIR/$tdir/bar_161c
18704         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18705         changelog_dump | grep RENME | tail -n 5
18706         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18707         changelog_clear 0 || error "changelog_clear failed"
18708         if [ x$flags != "x0x1" ]; then
18709                 error "flag $flags is not 0x1"
18710         fi
18711
18712         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18713         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18714         touch $DIR/$tdir/foo_161c
18715         touch $DIR/$tdir/bar_161c
18716         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18717         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18718         changelog_dump | grep RENME | tail -n 5
18719         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18720         changelog_clear 0 || error "changelog_clear failed"
18721         if [ x$flags != "x0x0" ]; then
18722                 error "flag $flags is not 0x0"
18723         fi
18724         echo "rename overwrite a target having nlink > 1," \
18725                 "changelog record has flags of $flags"
18726
18727         # rename doesn't overwrite a target (changelog flag 0x0)
18728         touch $DIR/$tdir/foo_161c
18729         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18730         changelog_dump | grep RENME | tail -n 5
18731         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18732         changelog_clear 0 || error "changelog_clear failed"
18733         if [ x$flags != "x0x0" ]; then
18734                 error "flag $flags is not 0x0"
18735         fi
18736         echo "rename doesn't overwrite a target," \
18737                 "changelog record has flags of $flags"
18738
18739         # define CLF_UNLINK_LAST 0x0001
18740         # unlink a file having nlink = 1 (changelog flag 0x1)
18741         rm -f $DIR/$tdir/foo2_161c
18742         changelog_dump | grep UNLNK | tail -n 5
18743         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18744         changelog_clear 0 || error "changelog_clear failed"
18745         if [ x$flags != "x0x1" ]; then
18746                 error "flag $flags is not 0x1"
18747         fi
18748         echo "unlink a file having nlink = 1," \
18749                 "changelog record has flags of $flags"
18750
18751         # unlink a file having nlink > 1 (changelog flag 0x0)
18752         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18753         rm -f $DIR/$tdir/foobar_161c
18754         changelog_dump | grep UNLNK | tail -n 5
18755         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18756         changelog_clear 0 || error "changelog_clear failed"
18757         if [ x$flags != "x0x0" ]; then
18758                 error "flag $flags is not 0x0"
18759         fi
18760         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18761 }
18762 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18763
18764 test_161d() {
18765         remote_mds_nodsh && skip "remote MDS with nodsh"
18766         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18767
18768         local pid
18769         local fid
18770
18771         changelog_register || error "changelog_register failed"
18772
18773         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18774         # interfer with $MOUNT/.lustre/fid/ access
18775         mkdir $DIR/$tdir
18776         [[ $? -eq 0 ]] || error "mkdir failed"
18777
18778         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
18779         $LCTL set_param fail_loc=0x8000140c
18780         # 5s pause
18781         $LCTL set_param fail_val=5
18782
18783         # create file
18784         echo foofoo > $DIR/$tdir/$tfile &
18785         pid=$!
18786
18787         # wait for create to be delayed
18788         sleep 2
18789
18790         ps -p $pid
18791         [[ $? -eq 0 ]] || error "create should be blocked"
18792
18793         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18794         stack_trap "rm -f $tempfile"
18795         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18796         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18797         # some delay may occur during ChangeLog publishing and file read just
18798         # above, that could allow file write to happen finally
18799         [[ -s $tempfile ]] && echo "file should be empty"
18800
18801         $LCTL set_param fail_loc=0
18802
18803         wait $pid
18804         [[ $? -eq 0 ]] || error "create failed"
18805 }
18806 run_test 161d "create with concurrent .lustre/fid access"
18807
18808 check_path() {
18809         local expected="$1"
18810         shift
18811         local fid="$2"
18812
18813         local path
18814         path=$($LFS fid2path "$@")
18815         local rc=$?
18816
18817         if [ $rc -ne 0 ]; then
18818                 error "path looked up of '$expected' failed: rc=$rc"
18819         elif [ "$path" != "$expected" ]; then
18820                 error "path looked up '$path' instead of '$expected'"
18821         else
18822                 echo "FID '$fid' resolves to path '$path' as expected"
18823         fi
18824 }
18825
18826 test_162a() { # was test_162
18827         test_mkdir -p -c1 $DIR/$tdir/d2
18828         touch $DIR/$tdir/d2/$tfile
18829         touch $DIR/$tdir/d2/x1
18830         touch $DIR/$tdir/d2/x2
18831         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18832         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18833         # regular file
18834         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18835         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18836
18837         # softlink
18838         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18839         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18840         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18841
18842         # softlink to wrong file
18843         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18844         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18845         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18846
18847         # hardlink
18848         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18849         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18850         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18851         # fid2path dir/fsname should both work
18852         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18853         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18854
18855         # hardlink count: check that there are 2 links
18856         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18857         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18858
18859         # hardlink indexing: remove the first link
18860         rm $DIR/$tdir/d2/p/q/r/hlink
18861         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18862 }
18863 run_test 162a "path lookup sanity"
18864
18865 test_162b() {
18866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18868
18869         mkdir $DIR/$tdir
18870         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18871                                 error "create striped dir failed"
18872
18873         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18874                                         tail -n 1 | awk '{print $2}')
18875         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18876
18877         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18878         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18879
18880         # regular file
18881         for ((i=0;i<5;i++)); do
18882                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18883                         error "get fid for f$i failed"
18884                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18885
18886                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18887                         error "get fid for d$i failed"
18888                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18889         done
18890
18891         return 0
18892 }
18893 run_test 162b "striped directory path lookup sanity"
18894
18895 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18896 test_162c() {
18897         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18898                 skip "Need MDS version at least 2.7.51"
18899
18900         local lpath=$tdir.local
18901         local rpath=$tdir.remote
18902
18903         test_mkdir $DIR/$lpath
18904         test_mkdir $DIR/$rpath
18905
18906         for ((i = 0; i <= 101; i++)); do
18907                 lpath="$lpath/$i"
18908                 mkdir $DIR/$lpath
18909                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18910                         error "get fid for local directory $DIR/$lpath failed"
18911                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18912
18913                 rpath="$rpath/$i"
18914                 test_mkdir $DIR/$rpath
18915                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18916                         error "get fid for remote directory $DIR/$rpath failed"
18917                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18918         done
18919
18920         return 0
18921 }
18922 run_test 162c "fid2path works with paths 100 or more directories deep"
18923
18924 oalr_event_count() {
18925         local event="${1}"
18926         local trace="${2}"
18927
18928         awk -v name="${FSNAME}-OST0000" \
18929             -v event="${event}" \
18930             '$1 == "TRACE" && $2 == event && $3 == name' \
18931             "${trace}" |
18932         wc -l
18933 }
18934
18935 oalr_expect_event_count() {
18936         local event="${1}"
18937         local trace="${2}"
18938         local expect="${3}"
18939         local count
18940
18941         count=$(oalr_event_count "${event}" "${trace}")
18942         if ((count == expect)); then
18943                 return 0
18944         fi
18945
18946         error_noexit "${event} event count was '${count}', expected ${expect}"
18947         cat "${trace}" >&2
18948         exit 1
18949 }
18950
18951 cleanup_165() {
18952         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18953         stop ost1
18954         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18955 }
18956
18957 setup_165() {
18958         sync # Flush previous IOs so we can count log entries.
18959         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18960         stack_trap cleanup_165 EXIT
18961 }
18962
18963 test_165a() {
18964         local trace="/tmp/${tfile}.trace"
18965         local rc
18966         local count
18967
18968         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18969                 skip "OFD access log unsupported"
18970
18971         setup_165
18972         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18973         sleep 5
18974
18975         do_facet ost1 ofd_access_log_reader --list
18976         stop ost1
18977
18978         do_facet ost1 killall -TERM ofd_access_log_reader
18979         wait
18980         rc=$?
18981
18982         if ((rc != 0)); then
18983                 error "ofd_access_log_reader exited with rc = '${rc}'"
18984         fi
18985
18986         # Parse trace file for discovery events:
18987         oalr_expect_event_count alr_log_add "${trace}" 1
18988         oalr_expect_event_count alr_log_eof "${trace}" 1
18989         oalr_expect_event_count alr_log_free "${trace}" 1
18990 }
18991 run_test 165a "ofd access log discovery"
18992
18993 test_165b() {
18994         local trace="/tmp/${tfile}.trace"
18995         local file="${DIR}/${tfile}"
18996         local pfid1
18997         local pfid2
18998         local -a entry
18999         local rc
19000         local count
19001         local size
19002         local flags
19003
19004         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19005                 skip "OFD access log unsupported"
19006
19007         setup_165
19008         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19009         sleep 5
19010
19011         do_facet ost1 ofd_access_log_reader --list
19012
19013         lfs setstripe -c 1 -i 0 "${file}"
19014         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19015                 error "cannot create '${file}'"
19016
19017         sleep 5
19018         do_facet ost1 killall -TERM ofd_access_log_reader
19019         wait
19020         rc=$?
19021
19022         if ((rc != 0)); then
19023                 error "ofd_access_log_reader exited with rc = '${rc}'"
19024         fi
19025
19026         oalr_expect_event_count alr_log_entry "${trace}" 1
19027
19028         pfid1=$($LFS path2fid "${file}")
19029
19030         # 1     2             3   4    5     6   7    8    9     10
19031         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19032         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19033
19034         echo "entry = '${entry[*]}'" >&2
19035
19036         pfid2=${entry[4]}
19037         if [[ "${pfid1}" != "${pfid2}" ]]; then
19038                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19039         fi
19040
19041         size=${entry[8]}
19042         if ((size != 1048576)); then
19043                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19044         fi
19045
19046         flags=${entry[10]}
19047         if [[ "${flags}" != "w" ]]; then
19048                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19049         fi
19050
19051         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19052         sleep 5
19053
19054         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19055                 error "cannot read '${file}'"
19056         sleep 5
19057
19058         do_facet ost1 killall -TERM ofd_access_log_reader
19059         wait
19060         rc=$?
19061
19062         if ((rc != 0)); then
19063                 error "ofd_access_log_reader exited with rc = '${rc}'"
19064         fi
19065
19066         oalr_expect_event_count alr_log_entry "${trace}" 1
19067
19068         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19069         echo "entry = '${entry[*]}'" >&2
19070
19071         pfid2=${entry[4]}
19072         if [[ "${pfid1}" != "${pfid2}" ]]; then
19073                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19074         fi
19075
19076         size=${entry[8]}
19077         if ((size != 524288)); then
19078                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19079         fi
19080
19081         flags=${entry[10]}
19082         if [[ "${flags}" != "r" ]]; then
19083                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19084         fi
19085 }
19086 run_test 165b "ofd access log entries are produced and consumed"
19087
19088 test_165c() {
19089         local trace="/tmp/${tfile}.trace"
19090         local file="${DIR}/${tdir}/${tfile}"
19091
19092         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19093                 skip "OFD access log unsupported"
19094
19095         test_mkdir "${DIR}/${tdir}"
19096
19097         setup_165
19098         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19099         sleep 5
19100
19101         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19102
19103         # 4096 / 64 = 64. Create twice as many entries.
19104         for ((i = 0; i < 128; i++)); do
19105                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19106                         error "cannot create file"
19107         done
19108
19109         sync
19110
19111         do_facet ost1 killall -TERM ofd_access_log_reader
19112         wait
19113         rc=$?
19114         if ((rc != 0)); then
19115                 error "ofd_access_log_reader exited with rc = '${rc}'"
19116         fi
19117
19118         unlinkmany  "${file}-%d" 128
19119 }
19120 run_test 165c "full ofd access logs do not block IOs"
19121
19122 oal_get_read_count() {
19123         local stats="$1"
19124
19125         # STATS lustre-OST0001 alr_read_count 1
19126
19127         do_facet ost1 cat "${stats}" |
19128         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19129              END { print count; }'
19130 }
19131
19132 oal_expect_read_count() {
19133         local stats="$1"
19134         local count
19135         local expect="$2"
19136
19137         # Ask ofd_access_log_reader to write stats.
19138         do_facet ost1 killall -USR1 ofd_access_log_reader
19139
19140         # Allow some time for things to happen.
19141         sleep 1
19142
19143         count=$(oal_get_read_count "${stats}")
19144         if ((count == expect)); then
19145                 return 0
19146         fi
19147
19148         error_noexit "bad read count, got ${count}, expected ${expect}"
19149         do_facet ost1 cat "${stats}" >&2
19150         exit 1
19151 }
19152
19153 test_165d() {
19154         local stats="/tmp/${tfile}.stats"
19155         local file="${DIR}/${tdir}/${tfile}"
19156         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19157
19158         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19159                 skip "OFD access log unsupported"
19160
19161         test_mkdir "${DIR}/${tdir}"
19162
19163         setup_165
19164         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19165         sleep 5
19166
19167         lfs setstripe -c 1 -i 0 "${file}"
19168
19169         do_facet ost1 lctl set_param "${param}=rw"
19170         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19171                 error "cannot create '${file}'"
19172         oal_expect_read_count "${stats}" 1
19173
19174         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19175                 error "cannot read '${file}'"
19176         oal_expect_read_count "${stats}" 2
19177
19178         do_facet ost1 lctl set_param "${param}=r"
19179         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19180                 error "cannot create '${file}'"
19181         oal_expect_read_count "${stats}" 2
19182
19183         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19184                 error "cannot read '${file}'"
19185         oal_expect_read_count "${stats}" 3
19186
19187         do_facet ost1 lctl set_param "${param}=w"
19188         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19189                 error "cannot create '${file}'"
19190         oal_expect_read_count "${stats}" 4
19191
19192         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19193                 error "cannot read '${file}'"
19194         oal_expect_read_count "${stats}" 4
19195
19196         do_facet ost1 lctl set_param "${param}=0"
19197         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19198                 error "cannot create '${file}'"
19199         oal_expect_read_count "${stats}" 4
19200
19201         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19202                 error "cannot read '${file}'"
19203         oal_expect_read_count "${stats}" 4
19204
19205         do_facet ost1 killall -TERM ofd_access_log_reader
19206         wait
19207         rc=$?
19208         if ((rc != 0)); then
19209                 error "ofd_access_log_reader exited with rc = '${rc}'"
19210         fi
19211 }
19212 run_test 165d "ofd_access_log mask works"
19213
19214 test_165e() {
19215         local stats="/tmp/${tfile}.stats"
19216         local file0="${DIR}/${tdir}-0/${tfile}"
19217         local file1="${DIR}/${tdir}-1/${tfile}"
19218
19219         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19220                 skip "OFD access log unsupported"
19221
19222         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19223
19224         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19225         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19226
19227         lfs setstripe -c 1 -i 0 "${file0}"
19228         lfs setstripe -c 1 -i 0 "${file1}"
19229
19230         setup_165
19231         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19232         sleep 5
19233
19234         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19235                 error "cannot create '${file0}'"
19236         sync
19237         oal_expect_read_count "${stats}" 0
19238
19239         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19240                 error "cannot create '${file1}'"
19241         sync
19242         oal_expect_read_count "${stats}" 1
19243
19244         do_facet ost1 killall -TERM ofd_access_log_reader
19245         wait
19246         rc=$?
19247         if ((rc != 0)); then
19248                 error "ofd_access_log_reader exited with rc = '${rc}'"
19249         fi
19250 }
19251 run_test 165e "ofd_access_log MDT index filter works"
19252
19253 test_165f() {
19254         local trace="/tmp/${tfile}.trace"
19255         local rc
19256         local count
19257
19258         setup_165
19259         do_facet ost1 timeout 60 ofd_access_log_reader \
19260                 --exit-on-close --debug=- --trace=- > "${trace}" &
19261         sleep 5
19262         stop ost1
19263
19264         wait
19265         rc=$?
19266
19267         if ((rc != 0)); then
19268                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19269                 cat "${trace}"
19270                 exit 1
19271         fi
19272 }
19273 run_test 165f "ofd_access_log_reader --exit-on-close works"
19274
19275 test_169() {
19276         # do directio so as not to populate the page cache
19277         log "creating a 10 Mb file"
19278         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19279                 error "multiop failed while creating a file"
19280         log "starting reads"
19281         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19282         log "truncating the file"
19283         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19284                 error "multiop failed while truncating the file"
19285         log "killing dd"
19286         kill %+ || true # reads might have finished
19287         echo "wait until dd is finished"
19288         wait
19289         log "removing the temporary file"
19290         rm -rf $DIR/$tfile || error "tmp file removal failed"
19291 }
19292 run_test 169 "parallel read and truncate should not deadlock"
19293
19294 test_170() {
19295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19296
19297         $LCTL clear     # bug 18514
19298         $LCTL debug_daemon start $TMP/${tfile}_log_good
19299         touch $DIR/$tfile
19300         $LCTL debug_daemon stop
19301         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19302                 error "sed failed to read log_good"
19303
19304         $LCTL debug_daemon start $TMP/${tfile}_log_good
19305         rm -rf $DIR/$tfile
19306         $LCTL debug_daemon stop
19307
19308         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19309                error "lctl df log_bad failed"
19310
19311         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19312         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19313
19314         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19315         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19316
19317         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19318                 error "bad_line good_line1 good_line2 are empty"
19319
19320         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19321         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19322         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19323
19324         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19325         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19326         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19327
19328         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19329                 error "bad_line_new good_line_new are empty"
19330
19331         local expected_good=$((good_line1 + good_line2*2))
19332
19333         rm -f $TMP/${tfile}*
19334         # LU-231, short malformed line may not be counted into bad lines
19335         if [ $bad_line -ne $bad_line_new ] &&
19336                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19337                 error "expected $bad_line bad lines, but got $bad_line_new"
19338                 return 1
19339         fi
19340
19341         if [ $expected_good -ne $good_line_new ]; then
19342                 error "expected $expected_good good lines, but got $good_line_new"
19343                 return 2
19344         fi
19345         true
19346 }
19347 run_test 170 "test lctl df to handle corrupted log ====================="
19348
19349 test_171() { # bug20592
19350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19351
19352         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19353         $LCTL set_param fail_loc=0x50e
19354         $LCTL set_param fail_val=3000
19355         multiop_bg_pause $DIR/$tfile O_s || true
19356         local MULTIPID=$!
19357         kill -USR1 $MULTIPID
19358         # cause log dump
19359         sleep 3
19360         wait $MULTIPID
19361         if dmesg | grep "recursive fault"; then
19362                 error "caught a recursive fault"
19363         fi
19364         $LCTL set_param fail_loc=0
19365         true
19366 }
19367 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19368
19369 test_172() {
19370
19371         #define OBD_FAIL_OBD_CLEANUP  0x60e
19372         $LCTL set_param fail_loc=0x60e
19373         umount $MOUNT || error "umount $MOUNT failed"
19374         stack_trap "mount_client $MOUNT"
19375
19376         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19377                 error "no client OBDs are remained"
19378
19379         $LCTL dl | while read devno state type name foo; do
19380                 case $type in
19381                 lov|osc|lmv|mdc)
19382                         $LCTL --device $name cleanup
19383                         $LCTL --device $name detach
19384                         ;;
19385                 *)
19386                         # skip server devices
19387                         ;;
19388                 esac
19389         done
19390
19391         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19392                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19393                 error "some client OBDs are still remained"
19394         fi
19395
19396 }
19397 run_test 172 "manual device removal with lctl cleanup/detach ======"
19398
19399 # it would be good to share it with obdfilter-survey/iokit-libecho code
19400 setup_obdecho_osc () {
19401         local rc=0
19402         local ost_nid=$1
19403         local obdfilter_name=$2
19404         echo "Creating new osc for $obdfilter_name on $ost_nid"
19405         # make sure we can find loopback nid
19406         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19407
19408         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19409                            ${obdfilter_name}_osc_UUID || rc=2; }
19410         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19411                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19412         return $rc
19413 }
19414
19415 cleanup_obdecho_osc () {
19416         local obdfilter_name=$1
19417         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19418         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19419         return 0
19420 }
19421
19422 obdecho_test() {
19423         local OBD=$1
19424         local node=$2
19425         local pages=${3:-64}
19426         local rc=0
19427         local id
19428
19429         local count=10
19430         local obd_size=$(get_obd_size $node $OBD)
19431         local page_size=$(get_page_size $node)
19432         if [[ -n "$obd_size" ]]; then
19433                 local new_count=$((obd_size / (pages * page_size / 1024)))
19434                 [[ $new_count -ge $count ]] || count=$new_count
19435         fi
19436
19437         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19438         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19439                            rc=2; }
19440         if [ $rc -eq 0 ]; then
19441             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19442             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19443         fi
19444         echo "New object id is $id"
19445         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19446                            rc=4; }
19447         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19448                            "test_brw $count w v $pages $id" || rc=4; }
19449         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19450                            rc=4; }
19451         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19452                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19453         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19454                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19455         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19456         return $rc
19457 }
19458
19459 test_180a() {
19460         skip "obdecho on osc is no longer supported"
19461 }
19462 run_test 180a "test obdecho on osc"
19463
19464 test_180b() {
19465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19466         remote_ost_nodsh && skip "remote OST with nodsh"
19467
19468         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19469                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19470                 error "failed to load module obdecho"
19471
19472         local target=$(do_facet ost1 $LCTL dl |
19473                        awk '/obdfilter/ { print $4; exit; }')
19474
19475         if [ -n "$target" ]; then
19476                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19477         else
19478                 do_facet ost1 $LCTL dl
19479                 error "there is no obdfilter target on ost1"
19480         fi
19481 }
19482 run_test 180b "test obdecho directly on obdfilter"
19483
19484 test_180c() { # LU-2598
19485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19486         remote_ost_nodsh && skip "remote OST with nodsh"
19487         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19488                 skip "Need MDS version at least 2.4.0"
19489
19490         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19491                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19492                 error "failed to load module obdecho"
19493
19494         local target=$(do_facet ost1 $LCTL dl |
19495                        awk '/obdfilter/ { print $4; exit; }')
19496
19497         if [ -n "$target" ]; then
19498                 local pages=16384 # 64MB bulk I/O RPC size
19499
19500                 obdecho_test "$target" ost1 "$pages" ||
19501                         error "obdecho_test with pages=$pages failed with $?"
19502         else
19503                 do_facet ost1 $LCTL dl
19504                 error "there is no obdfilter target on ost1"
19505         fi
19506 }
19507 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19508
19509 test_181() { # bug 22177
19510         test_mkdir $DIR/$tdir
19511         # create enough files to index the directory
19512         createmany -o $DIR/$tdir/foobar 4000
19513         # print attributes for debug purpose
19514         lsattr -d .
19515         # open dir
19516         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19517         MULTIPID=$!
19518         # remove the files & current working dir
19519         unlinkmany $DIR/$tdir/foobar 4000
19520         rmdir $DIR/$tdir
19521         kill -USR1 $MULTIPID
19522         wait $MULTIPID
19523         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19524         return 0
19525 }
19526 run_test 181 "Test open-unlinked dir ========================"
19527
19528 test_182a() {
19529         local fcount=1000
19530         local tcount=10
19531
19532         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19533
19534         $LCTL set_param mdc.*.rpc_stats=clear
19535
19536         for (( i = 0; i < $tcount; i++ )) ; do
19537                 mkdir $DIR/$tdir/$i
19538         done
19539
19540         for (( i = 0; i < $tcount; i++ )) ; do
19541                 createmany -o $DIR/$tdir/$i/f- $fcount &
19542         done
19543         wait
19544
19545         for (( i = 0; i < $tcount; i++ )) ; do
19546                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19547         done
19548         wait
19549
19550         $LCTL get_param mdc.*.rpc_stats
19551
19552         rm -rf $DIR/$tdir
19553 }
19554 run_test 182a "Test parallel modify metadata operations from mdc"
19555
19556 test_182b() {
19557         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19558         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19559         local dcount=1000
19560         local tcount=10
19561         local stime
19562         local etime
19563         local delta
19564
19565         do_facet mds1 $LCTL list_param \
19566                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19567                 skip "MDS lacks parallel RPC handling"
19568
19569         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19570
19571         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19572                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19573
19574         stime=$(date +%s)
19575         createmany -i 0 -d $DIR/$tdir/t- $tcount
19576
19577         for (( i = 0; i < $tcount; i++ )) ; do
19578                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19579         done
19580         wait
19581         etime=$(date +%s)
19582         delta=$((etime - stime))
19583         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19584
19585         stime=$(date +%s)
19586         for (( i = 0; i < $tcount; i++ )) ; do
19587                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19588         done
19589         wait
19590         etime=$(date +%s)
19591         delta=$((etime - stime))
19592         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19593
19594         rm -rf $DIR/$tdir
19595
19596         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19597
19598         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19599
19600         stime=$(date +%s)
19601         createmany -i 0 -d $DIR/$tdir/t- $tcount
19602
19603         for (( i = 0; i < $tcount; i++ )) ; do
19604                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19605         done
19606         wait
19607         etime=$(date +%s)
19608         delta=$((etime - stime))
19609         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19610
19611         stime=$(date +%s)
19612         for (( i = 0; i < $tcount; i++ )) ; do
19613                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19614         done
19615         wait
19616         etime=$(date +%s)
19617         delta=$((etime - stime))
19618         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19619
19620         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19621 }
19622 run_test 182b "Test parallel modify metadata operations from osp"
19623
19624 test_183() { # LU-2275
19625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19626         remote_mds_nodsh && skip "remote MDS with nodsh"
19627         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19628                 skip "Need MDS version at least 2.3.56"
19629
19630         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19631         echo aaa > $DIR/$tdir/$tfile
19632
19633 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19634         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19635
19636         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19637         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19638
19639         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19640
19641         # Flush negative dentry cache
19642         touch $DIR/$tdir/$tfile
19643
19644         # We are not checking for any leaked references here, they'll
19645         # become evident next time we do cleanup with module unload.
19646         rm -rf $DIR/$tdir
19647 }
19648 run_test 183 "No crash or request leak in case of strange dispositions ========"
19649
19650 # test suite 184 is for LU-2016, LU-2017
19651 test_184a() {
19652         check_swap_layouts_support
19653
19654         dir0=$DIR/$tdir/$testnum
19655         test_mkdir -p -c1 $dir0
19656         ref1=/etc/passwd
19657         ref2=/etc/group
19658         file1=$dir0/f1
19659         file2=$dir0/f2
19660         $LFS setstripe -c1 $file1
19661         cp $ref1 $file1
19662         $LFS setstripe -c2 $file2
19663         cp $ref2 $file2
19664         gen1=$($LFS getstripe -g $file1)
19665         gen2=$($LFS getstripe -g $file2)
19666
19667         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19668         gen=$($LFS getstripe -g $file1)
19669         [[ $gen1 != $gen ]] ||
19670                 error "Layout generation on $file1 does not change"
19671         gen=$($LFS getstripe -g $file2)
19672         [[ $gen2 != $gen ]] ||
19673                 error "Layout generation on $file2 does not change"
19674
19675         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19676         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19677
19678         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19679 }
19680 run_test 184a "Basic layout swap"
19681
19682 test_184b() {
19683         check_swap_layouts_support
19684
19685         dir0=$DIR/$tdir/$testnum
19686         mkdir -p $dir0 || error "creating dir $dir0"
19687         file1=$dir0/f1
19688         file2=$dir0/f2
19689         file3=$dir0/f3
19690         dir1=$dir0/d1
19691         dir2=$dir0/d2
19692         mkdir $dir1 $dir2
19693         $LFS setstripe -c1 $file1
19694         $LFS setstripe -c2 $file2
19695         $LFS setstripe -c1 $file3
19696         chown $RUNAS_ID $file3
19697         gen1=$($LFS getstripe -g $file1)
19698         gen2=$($LFS getstripe -g $file2)
19699
19700         $LFS swap_layouts $dir1 $dir2 &&
19701                 error "swap of directories layouts should fail"
19702         $LFS swap_layouts $dir1 $file1 &&
19703                 error "swap of directory and file layouts should fail"
19704         $RUNAS $LFS swap_layouts $file1 $file2 &&
19705                 error "swap of file we cannot write should fail"
19706         $LFS swap_layouts $file1 $file3 &&
19707                 error "swap of file with different owner should fail"
19708         /bin/true # to clear error code
19709 }
19710 run_test 184b "Forbidden layout swap (will generate errors)"
19711
19712 test_184c() {
19713         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19714         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19715         check_swap_layouts_support
19716         check_swap_layout_no_dom $DIR
19717
19718         local dir0=$DIR/$tdir/$testnum
19719         mkdir -p $dir0 || error "creating dir $dir0"
19720
19721         local ref1=$dir0/ref1
19722         local ref2=$dir0/ref2
19723         local file1=$dir0/file1
19724         local file2=$dir0/file2
19725         # create a file large enough for the concurrent test
19726         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19727         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19728         echo "ref file size: ref1($(stat -c %s $ref1))," \
19729              "ref2($(stat -c %s $ref2))"
19730
19731         cp $ref2 $file2
19732         dd if=$ref1 of=$file1 bs=16k &
19733         local DD_PID=$!
19734
19735         # Make sure dd starts to copy file, but wait at most 5 seconds
19736         local loops=0
19737         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19738
19739         $LFS swap_layouts $file1 $file2
19740         local rc=$?
19741         wait $DD_PID
19742         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19743         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19744
19745         # how many bytes copied before swapping layout
19746         local copied=$(stat -c %s $file2)
19747         local remaining=$(stat -c %s $ref1)
19748         remaining=$((remaining - copied))
19749         echo "Copied $copied bytes before swapping layout..."
19750
19751         cmp -n $copied $file1 $ref2 | grep differ &&
19752                 error "Content mismatch [0, $copied) of ref2 and file1"
19753         cmp -n $copied $file2 $ref1 ||
19754                 error "Content mismatch [0, $copied) of ref1 and file2"
19755         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19756                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19757
19758         # clean up
19759         rm -f $ref1 $ref2 $file1 $file2
19760 }
19761 run_test 184c "Concurrent write and layout swap"
19762
19763 test_184d() {
19764         check_swap_layouts_support
19765         check_swap_layout_no_dom $DIR
19766         [ -z "$(which getfattr 2>/dev/null)" ] &&
19767                 skip_env "no getfattr command"
19768
19769         local file1=$DIR/$tdir/$tfile-1
19770         local file2=$DIR/$tdir/$tfile-2
19771         local file3=$DIR/$tdir/$tfile-3
19772         local lovea1
19773         local lovea2
19774
19775         mkdir -p $DIR/$tdir
19776         touch $file1 || error "create $file1 failed"
19777         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19778                 error "create $file2 failed"
19779         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19780                 error "create $file3 failed"
19781         lovea1=$(get_layout_param $file1)
19782
19783         $LFS swap_layouts $file2 $file3 ||
19784                 error "swap $file2 $file3 layouts failed"
19785         $LFS swap_layouts $file1 $file2 ||
19786                 error "swap $file1 $file2 layouts failed"
19787
19788         lovea2=$(get_layout_param $file2)
19789         echo "$lovea1"
19790         echo "$lovea2"
19791         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19792
19793         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19794         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19795 }
19796 run_test 184d "allow stripeless layouts swap"
19797
19798 test_184e() {
19799         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19800                 skip "Need MDS version at least 2.6.94"
19801         check_swap_layouts_support
19802         check_swap_layout_no_dom $DIR
19803         [ -z "$(which getfattr 2>/dev/null)" ] &&
19804                 skip_env "no getfattr command"
19805
19806         local file1=$DIR/$tdir/$tfile-1
19807         local file2=$DIR/$tdir/$tfile-2
19808         local file3=$DIR/$tdir/$tfile-3
19809         local lovea
19810
19811         mkdir -p $DIR/$tdir
19812         touch $file1 || error "create $file1 failed"
19813         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19814                 error "create $file2 failed"
19815         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19816                 error "create $file3 failed"
19817
19818         $LFS swap_layouts $file1 $file2 ||
19819                 error "swap $file1 $file2 layouts failed"
19820
19821         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19822         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19823
19824         echo 123 > $file1 || error "Should be able to write into $file1"
19825
19826         $LFS swap_layouts $file1 $file3 ||
19827                 error "swap $file1 $file3 layouts failed"
19828
19829         echo 123 > $file1 || error "Should be able to write into $file1"
19830
19831         rm -rf $file1 $file2 $file3
19832 }
19833 run_test 184e "Recreate layout after stripeless layout swaps"
19834
19835 test_184f() {
19836         # Create a file with name longer than sizeof(struct stat) ==
19837         # 144 to see if we can get chars from the file name to appear
19838         # in the returned striping. Note that 'f' == 0x66.
19839         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19840
19841         mkdir -p $DIR/$tdir
19842         mcreate $DIR/$tdir/$file
19843         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19844                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19845         fi
19846 }
19847 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19848
19849 test_185() { # LU-2441
19850         # LU-3553 - no volatile file support in old servers
19851         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19852                 skip "Need MDS version at least 2.3.60"
19853
19854         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19855         touch $DIR/$tdir/spoo
19856         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19857         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19858                 error "cannot create/write a volatile file"
19859         [ "$FILESET" == "" ] &&
19860         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19861                 error "FID is still valid after close"
19862
19863         multiop_bg_pause $DIR/$tdir Vw4096_c
19864         local multi_pid=$!
19865
19866         local OLD_IFS=$IFS
19867         IFS=":"
19868         local fidv=($fid)
19869         IFS=$OLD_IFS
19870         # assume that the next FID for this client is sequential, since stdout
19871         # is unfortunately eaten by multiop_bg_pause
19872         local n=$((${fidv[1]} + 1))
19873         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19874         if [ "$FILESET" == "" ]; then
19875                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19876                         error "FID is missing before close"
19877         fi
19878         kill -USR1 $multi_pid
19879         # 1 second delay, so if mtime change we will see it
19880         sleep 1
19881         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19882         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19883 }
19884 run_test 185 "Volatile file support"
19885
19886 function create_check_volatile() {
19887         local idx=$1
19888         local tgt
19889
19890         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19891         local PID=$!
19892         sleep 1
19893         local FID=$(cat /tmp/${tfile}.fid)
19894         [ "$FID" == "" ] && error "can't get FID for volatile"
19895         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19896         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19897         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19898         kill -USR1 $PID
19899         wait
19900         sleep 1
19901         cancel_lru_locks mdc # flush opencache
19902         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19903         return 0
19904 }
19905
19906 test_185a(){
19907         # LU-12516 - volatile creation via .lustre
19908         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19909                 skip "Need MDS version at least 2.3.55"
19910
19911         create_check_volatile 0
19912         [ $MDSCOUNT -lt 2 ] && return 0
19913
19914         # DNE case
19915         create_check_volatile 1
19916
19917         return 0
19918 }
19919 run_test 185a "Volatile file creation in .lustre/fid/"
19920
19921 test_187a() {
19922         remote_mds_nodsh && skip "remote MDS with nodsh"
19923         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19924                 skip "Need MDS version at least 2.3.0"
19925
19926         local dir0=$DIR/$tdir/$testnum
19927         mkdir -p $dir0 || error "creating dir $dir0"
19928
19929         local file=$dir0/file1
19930         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19931         stack_trap "rm -f $file"
19932         local dv1=$($LFS data_version $file)
19933         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19934         local dv2=$($LFS data_version $file)
19935         [[ $dv1 != $dv2 ]] ||
19936                 error "data version did not change on write $dv1 == $dv2"
19937 }
19938 run_test 187a "Test data version change"
19939
19940 test_187b() {
19941         remote_mds_nodsh && skip "remote MDS with nodsh"
19942         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19943                 skip "Need MDS version at least 2.3.0"
19944
19945         local dir0=$DIR/$tdir/$testnum
19946         mkdir -p $dir0 || error "creating dir $dir0"
19947
19948         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19949         [[ ${DV[0]} != ${DV[1]} ]] ||
19950                 error "data version did not change on write"\
19951                       " ${DV[0]} == ${DV[1]}"
19952
19953         # clean up
19954         rm -f $file1
19955 }
19956 run_test 187b "Test data version change on volatile file"
19957
19958 test_200() {
19959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19960         remote_mgs_nodsh && skip "remote MGS with nodsh"
19961         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19962
19963         local POOL=${POOL:-cea1}
19964         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19965         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19966         # Pool OST targets
19967         local first_ost=0
19968         local last_ost=$(($OSTCOUNT - 1))
19969         local ost_step=2
19970         local ost_list=$(seq $first_ost $ost_step $last_ost)
19971         local ost_range="$first_ost $last_ost $ost_step"
19972         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19973         local file_dir=$POOL_ROOT/file_tst
19974         local subdir=$test_path/subdir
19975         local rc=0
19976
19977         while : ; do
19978                 # former test_200a test_200b
19979                 pool_add $POOL                          || { rc=$? ; break; }
19980                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19981                 # former test_200c test_200d
19982                 mkdir -p $test_path
19983                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19984                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19985                 mkdir -p $subdir
19986                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19987                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19988                                                         || { rc=$? ; break; }
19989                 # former test_200e test_200f
19990                 local files=$((OSTCOUNT*3))
19991                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19992                                                         || { rc=$? ; break; }
19993                 pool_create_files $POOL $file_dir $files "$ost_list" \
19994                                                         || { rc=$? ; break; }
19995                 # former test_200g test_200h
19996                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19997                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19998
19999                 # former test_201a test_201b test_201c
20000                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20001
20002                 local f=$test_path/$tfile
20003                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20004                 pool_remove $POOL $f                    || { rc=$? ; break; }
20005                 break
20006         done
20007
20008         destroy_test_pools
20009
20010         return $rc
20011 }
20012 run_test 200 "OST pools"
20013
20014 # usage: default_attr <count | size | offset>
20015 default_attr() {
20016         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20017 }
20018
20019 # usage: check_default_stripe_attr
20020 check_default_stripe_attr() {
20021         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20022         case $1 in
20023         --stripe-count|-c)
20024                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20025         --stripe-size|-S)
20026                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20027         --stripe-index|-i)
20028                 EXPECTED=-1;;
20029         *)
20030                 error "unknown getstripe attr '$1'"
20031         esac
20032
20033         [ $ACTUAL == $EXPECTED ] ||
20034                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20035 }
20036
20037 test_204a() {
20038         test_mkdir $DIR/$tdir
20039         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20040
20041         check_default_stripe_attr --stripe-count
20042         check_default_stripe_attr --stripe-size
20043         check_default_stripe_attr --stripe-index
20044 }
20045 run_test 204a "Print default stripe attributes"
20046
20047 test_204b() {
20048         test_mkdir $DIR/$tdir
20049         $LFS setstripe --stripe-count 1 $DIR/$tdir
20050
20051         check_default_stripe_attr --stripe-size
20052         check_default_stripe_attr --stripe-index
20053 }
20054 run_test 204b "Print default stripe size and offset"
20055
20056 test_204c() {
20057         test_mkdir $DIR/$tdir
20058         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20059
20060         check_default_stripe_attr --stripe-count
20061         check_default_stripe_attr --stripe-index
20062 }
20063 run_test 204c "Print default stripe count and offset"
20064
20065 test_204d() {
20066         test_mkdir $DIR/$tdir
20067         $LFS setstripe --stripe-index 0 $DIR/$tdir
20068
20069         check_default_stripe_attr --stripe-count
20070         check_default_stripe_attr --stripe-size
20071 }
20072 run_test 204d "Print default stripe count and size"
20073
20074 test_204e() {
20075         test_mkdir $DIR/$tdir
20076         $LFS setstripe -d $DIR/$tdir
20077
20078         # LU-16904 check if root is set as PFL layout
20079         local numcomp=$($LFS getstripe --component-count $MOUNT)
20080
20081         if [[ $numcomp -gt 0 ]]; then
20082                 check_default_stripe_attr --stripe-count
20083         else
20084                 check_default_stripe_attr --stripe-count --raw
20085         fi
20086         check_default_stripe_attr --stripe-size --raw
20087         check_default_stripe_attr --stripe-index --raw
20088 }
20089 run_test 204e "Print raw stripe attributes"
20090
20091 test_204f() {
20092         test_mkdir $DIR/$tdir
20093         $LFS setstripe --stripe-count 1 $DIR/$tdir
20094
20095         check_default_stripe_attr --stripe-size --raw
20096         check_default_stripe_attr --stripe-index --raw
20097 }
20098 run_test 204f "Print raw stripe size and offset"
20099
20100 test_204g() {
20101         test_mkdir $DIR/$tdir
20102         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20103
20104         check_default_stripe_attr --stripe-count --raw
20105         check_default_stripe_attr --stripe-index --raw
20106 }
20107 run_test 204g "Print raw stripe count and offset"
20108
20109 test_204h() {
20110         test_mkdir $DIR/$tdir
20111         $LFS setstripe --stripe-index 0 $DIR/$tdir
20112
20113         check_default_stripe_attr --stripe-count --raw
20114         check_default_stripe_attr --stripe-size --raw
20115 }
20116 run_test 204h "Print raw stripe count and size"
20117
20118 # Figure out which job scheduler is being used, if any,
20119 # or use a fake one
20120 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20121         JOBENV=SLURM_JOB_ID
20122 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20123         JOBENV=LSB_JOBID
20124 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20125         JOBENV=PBS_JOBID
20126 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20127         JOBENV=LOADL_STEP_ID
20128 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20129         JOBENV=JOB_ID
20130 else
20131         $LCTL list_param jobid_name > /dev/null 2>&1
20132         if [ $? -eq 0 ]; then
20133                 JOBENV=nodelocal
20134         else
20135                 JOBENV=FAKE_JOBID
20136         fi
20137 fi
20138 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20139
20140 verify_jobstats() {
20141         local cmd=($1)
20142         shift
20143         local facets="$@"
20144
20145 # we don't really need to clear the stats for this test to work, since each
20146 # command has a unique jobid, but it makes debugging easier if needed.
20147 #       for facet in $facets; do
20148 #               local dev=$(convert_facet2label $facet)
20149 #               # clear old jobstats
20150 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20151 #       done
20152
20153         # use a new JobID for each test, or we might see an old one
20154         [ "$JOBENV" = "FAKE_JOBID" ] &&
20155                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20156
20157         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20158
20159         [ "$JOBENV" = "nodelocal" ] && {
20160                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20161                 $LCTL set_param jobid_name=$FAKE_JOBID
20162                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20163         }
20164
20165         log "Test: ${cmd[*]}"
20166         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20167
20168         if [ $JOBENV = "FAKE_JOBID" ]; then
20169                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20170         else
20171                 ${cmd[*]}
20172         fi
20173
20174         # all files are created on OST0000
20175         for facet in $facets; do
20176                 local stats="*.$(convert_facet2label $facet).job_stats"
20177
20178                 # strip out libtool wrappers for in-tree executables
20179                 if (( $(do_facet $facet lctl get_param $stats |
20180                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20181                         do_facet $facet lctl get_param $stats
20182                         error "No jobstats for $JOBVAL found on $facet::$stats"
20183                 fi
20184         done
20185 }
20186
20187 jobstats_set() {
20188         local new_jobenv=$1
20189
20190         set_persistent_param_and_check client "jobid_var" \
20191                 "$FSNAME.sys.jobid_var" $new_jobenv
20192 }
20193
20194 test_205a() { # Job stats
20195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20196         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20197                 skip "Need MDS version with at least 2.7.1"
20198         remote_mgs_nodsh && skip "remote MGS with nodsh"
20199         remote_mds_nodsh && skip "remote MDS with nodsh"
20200         remote_ost_nodsh && skip "remote OST with nodsh"
20201         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20202                 skip "Server doesn't support jobstats"
20203         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20204
20205         local old_jobenv=$($LCTL get_param -n jobid_var)
20206         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20207         stack_trap "jobstats_set $old_jobenv" EXIT
20208
20209         changelog_register
20210
20211         local old_jobid_name=$($LCTL get_param jobid_name)
20212         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20213
20214         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20215                                 mdt.*.job_cleanup_interval | head -n 1)
20216         local new_interval=5
20217         do_facet $SINGLEMDS \
20218                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20219         stack_trap "do_facet $SINGLEMDS \
20220                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20221         local start=$SECONDS
20222
20223         local cmd
20224         # mkdir
20225         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20226         verify_jobstats "$cmd" "$SINGLEMDS"
20227         # rmdir
20228         cmd="rmdir $DIR/$tdir"
20229         verify_jobstats "$cmd" "$SINGLEMDS"
20230         # mkdir on secondary MDT
20231         if [ $MDSCOUNT -gt 1 ]; then
20232                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20233                 verify_jobstats "$cmd" "mds2"
20234         fi
20235         # mknod
20236         cmd="mknod $DIR/$tfile c 1 3"
20237         verify_jobstats "$cmd" "$SINGLEMDS"
20238         # unlink
20239         cmd="rm -f $DIR/$tfile"
20240         verify_jobstats "$cmd" "$SINGLEMDS"
20241         # create all files on OST0000 so verify_jobstats can find OST stats
20242         # open & close
20243         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20244         verify_jobstats "$cmd" "$SINGLEMDS"
20245         # setattr
20246         cmd="touch $DIR/$tfile"
20247         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20248         # write
20249         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20250         verify_jobstats "$cmd" "ost1"
20251         # read
20252         cancel_lru_locks osc
20253         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20254         verify_jobstats "$cmd" "ost1"
20255         # truncate
20256         cmd="$TRUNCATE $DIR/$tfile 0"
20257         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20258         # rename
20259         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20260         verify_jobstats "$cmd" "$SINGLEMDS"
20261         # jobstats expiry - sleep until old stats should be expired
20262         local left=$((new_interval + 5 - (SECONDS - start)))
20263         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20264                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20265                         "0" $left
20266         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20267         verify_jobstats "$cmd" "$SINGLEMDS"
20268         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20269             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20270
20271         # Ensure that jobid are present in changelog (if supported by MDS)
20272         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20273                 changelog_dump | tail -10
20274                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20275                 [ $jobids -eq 9 ] ||
20276                         error "Wrong changelog jobid count $jobids != 9"
20277
20278                 # LU-5862
20279                 JOBENV="disable"
20280                 jobstats_set $JOBENV
20281                 touch $DIR/$tfile
20282                 changelog_dump | grep $tfile
20283                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20284                 [ $jobids -eq 0 ] ||
20285                         error "Unexpected jobids when jobid_var=$JOBENV"
20286         fi
20287
20288         # test '%j' access to environment variable - if supported
20289         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20290                 JOBENV="JOBCOMPLEX"
20291                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20292
20293                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20294         fi
20295
20296         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20297                 JOBENV="JOBCOMPLEX"
20298                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20299
20300                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20301         fi
20302
20303         # test '%j' access to per-session jobid - if supported
20304         if lctl list_param jobid_this_session > /dev/null 2>&1
20305         then
20306                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20307                 lctl set_param jobid_this_session=$USER
20308
20309                 JOBENV="JOBCOMPLEX"
20310                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20311
20312                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20313         fi
20314 }
20315 run_test 205a "Verify job stats"
20316
20317 # LU-13117, LU-13597, LU-16599
20318 test_205b() {
20319         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20320                 skip "Need MDS version at least 2.13.54.91"
20321
20322         local job_stats="mdt.*.job_stats"
20323         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20324
20325         do_facet mds1 $LCTL set_param $job_stats=clear
20326
20327         # Setting jobid_var to USER might not be supported
20328         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20329         $LCTL set_param jobid_var=USER || true
20330         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20331         $LCTL set_param jobid_name="%j.%e.%u"
20332
20333         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20334         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20335                 { do_facet mds1 $LCTL get_param $job_stats;
20336                   error "Unexpected jobid found"; }
20337         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20338                 { do_facet mds1 $LCTL get_param $job_stats;
20339                   error "wrong job_stats format found"; }
20340
20341         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20342                 echo "MDS does not yet escape jobid" && return 0
20343
20344         mkdir_on_mdt0 $DIR/$tdir
20345         $LCTL set_param jobid_var=TEST205b
20346         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20347         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20348                       awk '/has\\x20sp/ {print $3}')
20349         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20350                   error "jobid not escaped"; }
20351
20352         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20353                 # need to run such a command on mds1:
20354                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20355                 #
20356                 # there might be multiple MDTs on single mds server, so need to
20357                 # specifiy MDT0000. Or the command will fail due to other MDTs
20358                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20359                         error "cannot clear escaped jobid in job_stats";
20360         else
20361                 echo "MDS does not support clearing escaped jobid"
20362         fi
20363 }
20364 run_test 205b "Verify job stats jobid and output format"
20365
20366 # LU-13733
20367 test_205c() {
20368         $LCTL set_param llite.*.stats=0
20369         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20370         $LCTL get_param llite.*.stats
20371         $LCTL get_param llite.*.stats | grep \
20372                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20373                         error "wrong client stats format found"
20374 }
20375 run_test 205c "Verify client stats format"
20376
20377 test_205d() {
20378         local file=$DIR/$tdir/$tfile
20379
20380         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20381                 skip "need lustre >= 2.15.53 for lljobstat"
20382         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20383                 skip "need lustre >= 2.15.53 for lljobstat"
20384         verify_yaml_available || skip_env "YAML verification not installed"
20385
20386         test_mkdir -i 0 $DIR/$tdir
20387         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20388         stack_trap "rm -rf $DIR/$tdir"
20389
20390         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20391                 error "failed to write data to $file"
20392         mv $file $file.2
20393
20394         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20395         echo -n 'verify rename_stats...'
20396         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20397                 verify_yaml || error "rename_stats is not valid YAML"
20398         echo " OK"
20399
20400         echo -n 'verify mdt job_stats...'
20401         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20402                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20403         echo " OK"
20404
20405         echo -n 'verify ost job_stats...'
20406         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20407                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20408         echo " OK"
20409 }
20410 run_test 205d "verify the format of some stats files"
20411
20412 test_205e() {
20413         local ops_comma
20414         local file=$DIR/$tdir/$tfile
20415         local -a cli_params
20416
20417         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20418                 skip "need lustre >= 2.15.53 for lljobstat"
20419         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20420                 skip "need lustre >= 2.15.53 for lljobstat"
20421         verify_yaml_available || skip_env "YAML verification not installed"
20422
20423         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20424         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20425         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20426
20427         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20428         stack_trap "rm -rf $DIR/$tdir"
20429
20430         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20431                 error "failed to create $file on ost1"
20432         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20433                 error "failed to write data to $file"
20434
20435         do_facet mds1 "$LCTL get_param *.*.job_stats"
20436         do_facet ost1 "$LCTL get_param *.*.job_stats"
20437
20438         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20439         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20440                 error "The output of lljobstat is not an valid YAML"
20441
20442         # verify that job dd.0 does exist and has some ops on ost1
20443         # typically this line is like:
20444         # - 205e.dd.0:            {ops: 20, ...}
20445         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20446                     awk '$2=="205e.dd.0:" {print $4}')
20447
20448         (( ${ops_comma%,} >= 10 )) ||
20449                 error "cannot find job 205e.dd.0 with ops >= 10"
20450 }
20451 run_test 205e "verify the output of lljobstat"
20452
20453 test_205f() {
20454         verify_yaml_available || skip_env "YAML verification not installed"
20455
20456         # check both qos_ost_weights and qos_mdt_weights
20457         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20458         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20459                 error "qos_ost_weights is not valid YAML"
20460 }
20461 run_test 205f "verify qos_ost_weights YAML format "
20462
20463 __test_205_jobstats_dump() {
20464         local -a pids
20465         local nbr_instance=$1
20466
20467         while true; do
20468                 if (( ${#pids[@]} >= nbr_instance )); then
20469                         wait ${pids[@]}
20470                         pids=()
20471                 fi
20472
20473                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20474                 pids+=( $! )
20475         done
20476 }
20477
20478 __test_205_cleanup() {
20479         kill $@
20480         # Clear all job entries
20481         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20482 }
20483
20484 test_205g() {
20485         local -a mds1_params
20486         local -a cli_params
20487         local pids
20488         local interval=5
20489
20490         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20491         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20492         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20493
20494         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20495         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20496         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20497
20498         # start jobs loop
20499         export TEST205G_ID=205g
20500         stack_trap "unset TEST205G_ID" EXIT
20501         while true; do
20502                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20503         done & pids="$! "
20504
20505         __test_205_jobstats_dump 4 & pids+="$! "
20506         stack_trap "__test_205_cleanup $pids" EXIT INT
20507
20508         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20509 }
20510 run_test 205g "stress test for job_stats procfile"
20511
20512 test_205h() {
20513         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20514                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20515         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20516
20517         local dir=$DIR/$tdir
20518         local f=$dir/$tfile
20519         local f2=$dir/$tfile-2
20520         local f3=$dir/$tfile-3
20521         local subdir=$DIR/dir
20522         local val
20523
20524         local mdts=$(comma_list $(mdts_nodes))
20525         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20526         local client_saved=$($LCTL get_param -n jobid_var)
20527
20528         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20529         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20530
20531         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20532                 error "failed to set job_xattr parameter to user.job"
20533         $LCTL set_param jobid_var=procname.uid ||
20534                 error "failed to set jobid_var parameter"
20535
20536         test_mkdir $dir
20537
20538         touch $f
20539         val=$(getfattr -n user.job $f | grep user.job)
20540         [[ $val = user.job=\"touch.0\" ]] ||
20541                 error "expected user.job=\"touch.0\", got '$val'"
20542
20543         mkdir $subdir
20544         val=$(getfattr -n user.job $subdir | grep user.job)
20545         [[ $val = user.job=\"mkdir.0\" ]] ||
20546                 error "expected user.job=\"mkdir.0\", got '$val'"
20547
20548         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20549                 error "failed to set job_xattr parameter to NONE"
20550
20551         touch $f2
20552         val=$(getfattr -d $f2)
20553         [[ -z $val ]] ||
20554                 error "expected no user xattr, got '$val'"
20555
20556         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20557                 error "failed to set job_xattr parameter to trusted.job"
20558
20559         touch $f3
20560         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20561         [[ $val = trusted.job=\"touch.0\" ]] ||
20562                 error "expected trusted.job=\"touch.0\", got '$val'"
20563 }
20564 run_test 205h "check jobid xattr is stored correctly"
20565
20566 test_205i() {
20567         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20568                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20569
20570         local mdts=$(comma_list $(mdts_nodes))
20571         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20572
20573         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20574
20575         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20576                 error "failed to set mdt.*.job_xattr to user.1234567"
20577
20578         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20579                 error "failed to reject too long job_xattr name"
20580
20581         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20582                 error "failed to reject job_xattr name in bad format"
20583
20584         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20585                 error "failed to reject job_xattr name with invalid character"
20586
20587         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20588                         xargs $LCTL set_param" &&
20589                 error "failed to reject job_xattr name with non-ascii character"
20590
20591         return 0
20592 }
20593 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20594
20595 # LU-1480, LU-1773 and LU-1657
20596 test_206() {
20597         mkdir -p $DIR/$tdir
20598         $LFS setstripe -c -1 $DIR/$tdir
20599 #define OBD_FAIL_LOV_INIT 0x1403
20600         $LCTL set_param fail_loc=0xa0001403
20601         $LCTL set_param fail_val=1
20602         touch $DIR/$tdir/$tfile || true
20603 }
20604 run_test 206 "fail lov_init_raid0() doesn't lbug"
20605
20606 test_207a() {
20607         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20608         local fsz=`stat -c %s $DIR/$tfile`
20609         cancel_lru_locks mdc
20610
20611         # do not return layout in getattr intent
20612 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20613         $LCTL set_param fail_loc=0x170
20614         local sz=`stat -c %s $DIR/$tfile`
20615
20616         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20617
20618         rm -rf $DIR/$tfile
20619 }
20620 run_test 207a "can refresh layout at glimpse"
20621
20622 test_207b() {
20623         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20624         local cksum=`md5sum $DIR/$tfile`
20625         local fsz=`stat -c %s $DIR/$tfile`
20626         cancel_lru_locks mdc
20627         cancel_lru_locks osc
20628
20629         # do not return layout in getattr intent
20630 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20631         $LCTL set_param fail_loc=0x171
20632
20633         # it will refresh layout after the file is opened but before read issues
20634         echo checksum is "$cksum"
20635         echo "$cksum" |md5sum -c --quiet || error "file differs"
20636
20637         rm -rf $DIR/$tfile
20638 }
20639 run_test 207b "can refresh layout at open"
20640
20641 test_208() {
20642         # FIXME: in this test suite, only RD lease is used. This is okay
20643         # for now as only exclusive open is supported. After generic lease
20644         # is done, this test suite should be revised. - Jinshan
20645
20646         remote_mds_nodsh && skip "remote MDS with nodsh"
20647         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20648                 skip "Need MDS version at least 2.4.52"
20649
20650         echo "==== test 1: verify get lease work"
20651         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20652
20653         echo "==== test 2: verify lease can be broken by upcoming open"
20654         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20655         local PID=$!
20656         sleep 2
20657
20658         $MULTIOP $DIR/$tfile oO_RDWR:c
20659         kill -USR1 $PID && wait $PID || error "break lease error"
20660
20661         echo "==== test 3: verify lease can't be granted if an open already exists"
20662         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20663         local PID=$!
20664         sleep 2
20665
20666         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20667         kill -USR1 $PID && wait $PID || error "open file error"
20668
20669         echo "==== test 4: lease can sustain over recovery"
20670         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20671         PID=$!
20672         sleep 2
20673
20674         fail mds1
20675
20676         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20677
20678         echo "==== test 5: lease broken can't be regained by replay"
20679         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20680         PID=$!
20681         sleep 2
20682
20683         # open file to break lease and then recovery
20684         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20685         fail mds1
20686
20687         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20688
20689         rm -f $DIR/$tfile
20690 }
20691 run_test 208 "Exclusive open"
20692
20693 test_209() {
20694         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20695                 skip_env "must have disp_stripe"
20696
20697         touch $DIR/$tfile
20698         sync; sleep 5; sync;
20699
20700         echo 3 > /proc/sys/vm/drop_caches
20701         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20702                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20703         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20704
20705         # open/close 500 times
20706         for i in $(seq 500); do
20707                 cat $DIR/$tfile
20708         done
20709
20710         echo 3 > /proc/sys/vm/drop_caches
20711         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20712                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20713         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20714
20715         echo "before: $req_before, after: $req_after"
20716         [ $((req_after - req_before)) -ge 300 ] &&
20717                 error "open/close requests are not freed"
20718         return 0
20719 }
20720 run_test 209 "read-only open/close requests should be freed promptly"
20721
20722 test_210() {
20723         local pid
20724
20725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20726         pid=$!
20727         sleep 1
20728
20729         $LFS getstripe $DIR/$tfile
20730         kill -USR1 $pid
20731         wait $pid || error "multiop failed"
20732
20733         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20734         pid=$!
20735         sleep 1
20736
20737         $LFS getstripe $DIR/$tfile
20738         kill -USR1 $pid
20739         wait $pid || error "multiop failed"
20740 }
20741 run_test 210 "lfs getstripe does not break leases"
20742
20743 function test_211() {
20744         local PID
20745         local id
20746         local rc
20747
20748         stack_trap "rm -f $DIR/$tfile" EXIT
20749         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20750                 error "can't create file"
20751         $LFS mirror extend -N $DIR/$tfile ||
20752                 error "can't create a replica"
20753         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20754         $LFS getstripe $DIR/$tfile
20755         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20756         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20757
20758         $MULTIOP $DIR/$tfile OeW_E+eUc &
20759         PID=$!
20760         sleep 0.3
20761
20762         id=$($LFS getstripe $DIR/$tfile |
20763                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20764         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20765                 error "removed last in-sync replica?"
20766
20767         kill -USR1 $PID
20768         wait $PID
20769         (( $? == 0 )) || error "failed split broke the lease"
20770 }
20771 run_test 211 "failed mirror split doesn't break write lease"
20772
20773 test_212() {
20774         size=`date +%s`
20775         size=$((size % 8192 + 1))
20776         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
20777         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
20778         rm -f $DIR/f212 $DIR/f212.xyz
20779 }
20780 run_test 212 "Sendfile test ============================================"
20781
20782 test_213() {
20783         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
20784         cancel_lru_locks osc
20785         lctl set_param fail_loc=0x8000040f
20786         # generate a read lock
20787         cat $DIR/$tfile > /dev/null
20788         # write to the file, it will try to cancel the above read lock.
20789         cat /etc/hosts >> $DIR/$tfile
20790 }
20791 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
20792
20793 test_214() { # for bug 20133
20794         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20795         for (( i=0; i < 340; i++ )) ; do
20796                 touch $DIR/$tdir/d214c/a$i
20797         done
20798
20799         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20800         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20801         ls $DIR/d214c || error "ls $DIR/d214c failed"
20802         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20803         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20804 }
20805 run_test 214 "hash-indexed directory test - bug 20133"
20806
20807 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20808 create_lnet_proc_files() {
20809         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20810 }
20811
20812 # counterpart of create_lnet_proc_files
20813 remove_lnet_proc_files() {
20814         rm -f $TMP/lnet_$1.sys
20815 }
20816
20817 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20818 # 3rd arg as regexp for body
20819 check_lnet_proc_stats() {
20820         local l=$(cat "$TMP/lnet_$1" |wc -l)
20821         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20822
20823         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20824 }
20825
20826 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20827 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20828 # optional and can be regexp for 2nd line (lnet.routes case)
20829 check_lnet_proc_entry() {
20830         local blp=2          # blp stands for 'position of 1st line of body'
20831         [ -z "$5" ] || blp=3 # lnet.routes case
20832
20833         local l=$(cat "$TMP/lnet_$1" |wc -l)
20834         # subtracting one from $blp because the body can be empty
20835         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20836
20837         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20838                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20839
20840         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20841                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20842
20843         # bail out if any unexpected line happened
20844         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20845         [ "$?" != 0 ] || error "$2 misformatted"
20846 }
20847
20848 test_215() { # for bugs 18102, 21079, 21517
20849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20850
20851         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20852         local P='[1-9][0-9]*'           # positive numeric
20853         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20854         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20855         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20856         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20857
20858         local L1 # regexp for 1st line
20859         local L2 # regexp for 2nd line (optional)
20860         local BR # regexp for the rest (body)
20861
20862         # lnet.stats should look as 11 space-separated non-negative numerics
20863         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20864         create_lnet_proc_files "stats"
20865         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20866         remove_lnet_proc_files "stats"
20867
20868         # lnet.routes should look like this:
20869         # Routing disabled/enabled
20870         # net hops priority state router
20871         # where net is a string like tcp0, hops > 0, priority >= 0,
20872         # state is up/down,
20873         # router is a string like 192.168.1.1@tcp2
20874         L1="^Routing (disabled|enabled)$"
20875         L2="^net +hops +priority +state +router$"
20876         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20877         create_lnet_proc_files "routes"
20878         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20879         remove_lnet_proc_files "routes"
20880
20881         # lnet.routers should look like this:
20882         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20883         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20884         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20885         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20886         L1="^ref +rtr_ref +alive +router$"
20887         BR="^$P +$P +(up|down) +$NID$"
20888         create_lnet_proc_files "routers"
20889         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20890         remove_lnet_proc_files "routers"
20891
20892         # lnet.peers should look like this:
20893         # nid refs state last max rtr min tx min queue
20894         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20895         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20896         # numeric (0 or >0 or <0), queue >= 0.
20897         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20898         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20899         create_lnet_proc_files "peers"
20900         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20901         remove_lnet_proc_files "peers"
20902
20903         # lnet.buffers  should look like this:
20904         # pages count credits min
20905         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20906         L1="^pages +count +credits +min$"
20907         BR="^ +$N +$N +$I +$I$"
20908         create_lnet_proc_files "buffers"
20909         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20910         remove_lnet_proc_files "buffers"
20911
20912         # lnet.nis should look like this:
20913         # nid status alive refs peer rtr max tx min
20914         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20915         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20916         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20917         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20918         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20919         create_lnet_proc_files "nis"
20920         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20921         remove_lnet_proc_files "nis"
20922
20923         # can we successfully write to lnet.stats?
20924         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20925 }
20926 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20927
20928 test_216() { # bug 20317
20929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20930         remote_ost_nodsh && skip "remote OST with nodsh"
20931
20932         local node
20933         local facets=$(get_facets OST)
20934         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20935
20936         save_lustre_params client "osc.*.contention_seconds" > $p
20937         save_lustre_params $facets \
20938                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20939         save_lustre_params $facets \
20940                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20941         save_lustre_params $facets \
20942                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20943         clear_stats osc.*.osc_stats
20944
20945         # agressive lockless i/o settings
20946         do_nodes $(comma_list $(osts_nodes)) \
20947                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20948                         ldlm.namespaces.filter-*.contended_locks=0 \
20949                         ldlm.namespaces.filter-*.contention_seconds=60"
20950         lctl set_param -n osc.*.contention_seconds=60
20951
20952         $DIRECTIO write $DIR/$tfile 0 10 4096
20953         $CHECKSTAT -s 40960 $DIR/$tfile
20954
20955         # disable lockless i/o
20956         do_nodes $(comma_list $(osts_nodes)) \
20957                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20958                         ldlm.namespaces.filter-*.contended_locks=32 \
20959                         ldlm.namespaces.filter-*.contention_seconds=0"
20960         lctl set_param -n osc.*.contention_seconds=0
20961         clear_stats osc.*.osc_stats
20962
20963         dd if=/dev/zero of=$DIR/$tfile count=0
20964         $CHECKSTAT -s 0 $DIR/$tfile
20965
20966         restore_lustre_params <$p
20967         rm -f $p
20968         rm $DIR/$tfile
20969 }
20970 run_test 216 "check lockless direct write updates file size and kms correctly"
20971
20972 test_217() { # bug 22430
20973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20974
20975         local node
20976
20977         for node in $(nodes_list); do
20978                 local nid=$(host_nids_address $node $NETTYPE)
20979                 local node_ip=$(do_node $node getent ahostsv4 $node |
20980                                 awk '{ print $1; exit; }')
20981
20982                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20983                 # if hostname matches any NID, use hostname for better testing
20984                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20985                         echo "lctl ping node $node@$NETTYPE"
20986                         lctl ping $node@$NETTYPE
20987                 else # otherwise, at least test 'lctl ping' is working
20988                         echo "lctl ping nid $(h2nettype $nid)"
20989                         lctl ping $(h2nettype $nid)
20990                         echo "skipping $node (no hyphen detected)"
20991                 fi
20992         done
20993 }
20994 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20995
20996 test_218() {
20997         # do directio so as not to populate the page cache
20998         log "creating a 10 Mb file"
20999         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21000                 error "multiop failed while creating a file"
21001         log "starting reads"
21002         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21003         log "truncating the file"
21004         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21005                 error "multiop failed while truncating the file"
21006         log "killing dd"
21007         kill %+ || true # reads might have finished
21008         echo "wait until dd is finished"
21009         wait
21010         log "removing the temporary file"
21011         rm -rf $DIR/$tfile || error "tmp file removal failed"
21012 }
21013 run_test 218 "parallel read and truncate should not deadlock"
21014
21015 test_219() {
21016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21017
21018         # write one partial page
21019         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21020         # set no grant so vvp_io_commit_write will do sync write
21021         $LCTL set_param fail_loc=0x411
21022         # write a full page at the end of file
21023         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21024
21025         $LCTL set_param fail_loc=0
21026         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21027         $LCTL set_param fail_loc=0x411
21028         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21029
21030         # LU-4201
21031         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21032         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21033 }
21034 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21035
21036 test_220() { #LU-325
21037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21038         remote_ost_nodsh && skip "remote OST with nodsh"
21039         remote_mds_nodsh && skip "remote MDS with nodsh"
21040         remote_mgs_nodsh && skip "remote MGS with nodsh"
21041
21042         local OSTIDX=0
21043
21044         # create on MDT0000 so the last_id and next_id are correct
21045         mkdir_on_mdt0 $DIR/$tdir
21046         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21047         OST=${OST%_UUID}
21048
21049         # on the mdt's osc
21050         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21051         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21052                         osp.$mdtosc_proc1.prealloc_last_id)
21053         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21054                         osp.$mdtosc_proc1.prealloc_next_id)
21055
21056         $LFS df -i
21057
21058         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21059         #define OBD_FAIL_OST_ENOINO              0x229
21060         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21061         create_pool $FSNAME.$TESTNAME || return 1
21062         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21063
21064         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21065
21066         MDSOBJS=$((last_id - next_id))
21067         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21068
21069         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21070         echo "OST still has $count kbytes free"
21071
21072         echo "create $MDSOBJS files @next_id..."
21073         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21074
21075         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21076                         osp.$mdtosc_proc1.prealloc_last_id)
21077         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21078                         osp.$mdtosc_proc1.prealloc_next_id)
21079
21080         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21081         $LFS df -i
21082
21083         echo "cleanup..."
21084
21085         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21086         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21087
21088         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21089                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21090         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21091                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21092         echo "unlink $MDSOBJS files @$next_id..."
21093         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21094 }
21095 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21096
21097 test_221() {
21098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21099
21100         dd if=`which date` of=$MOUNT/date oflag=sync
21101         chmod +x $MOUNT/date
21102
21103         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21104         $LCTL set_param fail_loc=0x80001401
21105
21106         $MOUNT/date > /dev/null
21107         rm -f $MOUNT/date
21108 }
21109 run_test 221 "make sure fault and truncate race to not cause OOM"
21110
21111 test_222a () {
21112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21113
21114         rm -rf $DIR/$tdir
21115         test_mkdir $DIR/$tdir
21116         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21117         createmany -o $DIR/$tdir/$tfile 10
21118         cancel_lru_locks mdc
21119         cancel_lru_locks osc
21120         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21121         $LCTL set_param fail_loc=0x31a
21122         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21123         $LCTL set_param fail_loc=0
21124         rm -r $DIR/$tdir
21125 }
21126 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21127
21128 test_222b () {
21129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21130
21131         rm -rf $DIR/$tdir
21132         test_mkdir $DIR/$tdir
21133         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21134         createmany -o $DIR/$tdir/$tfile 10
21135         cancel_lru_locks mdc
21136         cancel_lru_locks osc
21137         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21138         $LCTL set_param fail_loc=0x31a
21139         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21140         $LCTL set_param fail_loc=0
21141 }
21142 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21143
21144 test_223 () {
21145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21146
21147         rm -rf $DIR/$tdir
21148         test_mkdir $DIR/$tdir
21149         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21150         createmany -o $DIR/$tdir/$tfile 10
21151         cancel_lru_locks mdc
21152         cancel_lru_locks osc
21153         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21154         $LCTL set_param fail_loc=0x31b
21155         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21156         $LCTL set_param fail_loc=0
21157         rm -r $DIR/$tdir
21158 }
21159 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21160
21161 test_224a() { # LU-1039, MRP-303
21162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21163         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21164         $LCTL set_param fail_loc=0x508
21165         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21166         $LCTL set_param fail_loc=0
21167         df $DIR
21168 }
21169 run_test 224a "Don't panic on bulk IO failure"
21170
21171 test_224bd_sub() { # LU-1039, MRP-303
21172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21173         local timeout=$1
21174
21175         shift
21176         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21177
21178         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21179
21180         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21181         cancel_lru_locks osc
21182         set_checksums 0
21183         stack_trap "set_checksums $ORIG_CSUM" EXIT
21184         local at_max_saved=0
21185
21186         # adaptive timeouts may prevent seeing the issue
21187         if at_is_enabled; then
21188                 at_max_saved=$(at_max_get mds)
21189                 at_max_set 0 mds client
21190                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21191         fi
21192
21193         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21194         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21195         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21196
21197         do_facet ost1 $LCTL set_param fail_loc=0
21198         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21199         df $DIR
21200 }
21201
21202 test_224b() {
21203         test_224bd_sub 3 error "dd failed"
21204 }
21205 run_test 224b "Don't panic on bulk IO failure"
21206
21207 test_224c() { # LU-6441
21208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21209         remote_mds_nodsh && skip "remote MDS with nodsh"
21210
21211         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21212         save_writethrough $p
21213         set_cache writethrough on
21214
21215         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21216         local at_max=$($LCTL get_param -n at_max)
21217         local timeout=$($LCTL get_param -n timeout)
21218         local test_at="at_max"
21219         local param_at="$FSNAME.sys.at_max"
21220         local test_timeout="timeout"
21221         local param_timeout="$FSNAME.sys.timeout"
21222
21223         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21224
21225         set_persistent_param_and_check client "$test_at" "$param_at" 0
21226         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21227
21228         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21229         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21230         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21231         stack_trap "rm -f $DIR/$tfile"
21232         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21233         sync
21234         do_facet ost1 "$LCTL set_param fail_loc=0"
21235
21236         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21237         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21238                 $timeout
21239
21240         $LCTL set_param -n $pages_per_rpc
21241         restore_lustre_params < $p
21242         rm -f $p
21243 }
21244 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21245
21246 test_224d() { # LU-11169
21247         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21248 }
21249 run_test 224d "Don't corrupt data on bulk IO timeout"
21250
21251 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21252 test_225a () {
21253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21254         if [ -z ${MDSSURVEY} ]; then
21255                 skip_env "mds-survey not found"
21256         fi
21257         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21258                 skip "Need MDS version at least 2.2.51"
21259
21260         local mds=$(facet_host $SINGLEMDS)
21261         local target=$(do_nodes $mds 'lctl dl' |
21262                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21263
21264         local cmd1="file_count=1000 thrhi=4"
21265         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21266         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21267         local cmd="$cmd1 $cmd2 $cmd3"
21268
21269         rm -f ${TMP}/mds_survey*
21270         echo + $cmd
21271         eval $cmd || error "mds-survey with zero-stripe failed"
21272         cat ${TMP}/mds_survey*
21273         rm -f ${TMP}/mds_survey*
21274 }
21275 run_test 225a "Metadata survey sanity with zero-stripe"
21276
21277 test_225b () {
21278         if [ -z ${MDSSURVEY} ]; then
21279                 skip_env "mds-survey not found"
21280         fi
21281         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21282                 skip "Need MDS version at least 2.2.51"
21283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21284         remote_mds_nodsh && skip "remote MDS with nodsh"
21285         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21286                 skip_env "Need to mount OST to test"
21287         fi
21288
21289         local mds=$(facet_host $SINGLEMDS)
21290         local target=$(do_nodes $mds 'lctl dl' |
21291                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21292
21293         local cmd1="file_count=1000 thrhi=4"
21294         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21295         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21296         local cmd="$cmd1 $cmd2 $cmd3"
21297
21298         rm -f ${TMP}/mds_survey*
21299         echo + $cmd
21300         eval $cmd || error "mds-survey with stripe_count failed"
21301         cat ${TMP}/mds_survey*
21302         rm -f ${TMP}/mds_survey*
21303 }
21304 run_test 225b "Metadata survey sanity with stripe_count = 1"
21305
21306 mcreate_path2fid () {
21307         local mode=$1
21308         local major=$2
21309         local minor=$3
21310         local name=$4
21311         local desc=$5
21312         local path=$DIR/$tdir/$name
21313         local fid
21314         local rc
21315         local fid_path
21316
21317         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21318                 error "cannot create $desc"
21319
21320         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21321         rc=$?
21322         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21323
21324         fid_path=$($LFS fid2path $MOUNT $fid)
21325         rc=$?
21326         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21327
21328         [ "$path" == "$fid_path" ] ||
21329                 error "fid2path returned $fid_path, expected $path"
21330
21331         echo "pass with $path and $fid"
21332 }
21333
21334 test_226a () {
21335         rm -rf $DIR/$tdir
21336         mkdir -p $DIR/$tdir
21337
21338         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21339         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21340         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21341         mcreate_path2fid 0040666 0 0 dir "directory"
21342         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21343         mcreate_path2fid 0100666 0 0 file "regular file"
21344         mcreate_path2fid 0120666 0 0 link "symbolic link"
21345         mcreate_path2fid 0140666 0 0 sock "socket"
21346 }
21347 run_test 226a "call path2fid and fid2path on files of all type"
21348
21349 test_226b () {
21350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21351
21352         local MDTIDX=1
21353
21354         rm -rf $DIR/$tdir
21355         mkdir -p $DIR/$tdir
21356         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21357                 error "create remote directory failed"
21358         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21359         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21360                                 "character special file (null)"
21361         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21362                                 "character special file (no device)"
21363         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21364         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21365                                 "block special file (loop)"
21366         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21367         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21368         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21369 }
21370 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21371
21372 test_226c () {
21373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21374         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21375                 skip "Need MDS version at least 2.13.55"
21376
21377         local submnt=/mnt/submnt
21378         local srcfile=/etc/passwd
21379         local dstfile=$submnt/passwd
21380         local path
21381         local fid
21382
21383         rm -rf $DIR/$tdir
21384         rm -rf $submnt
21385         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21386                 error "create remote directory failed"
21387         mkdir -p $submnt || error "create $submnt failed"
21388         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21389                 error "mount $submnt failed"
21390         stack_trap "umount $submnt" EXIT
21391
21392         cp $srcfile $dstfile
21393         fid=$($LFS path2fid $dstfile)
21394         path=$($LFS fid2path $submnt "$fid")
21395         [ "$path" = "$dstfile" ] ||
21396                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21397 }
21398 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21399
21400 test_226d () {
21401         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21402                 skip "Need client at least version 2.15.57"
21403
21404         # Define First test dataset
21405         local testdirs_01=$DIR/$tdir
21406         local testdata_01=$testdirs_01/${tdir}_01
21407         local testresult_01=${tdir}_01
21408         # Define Second test dataset
21409         local testdirs_02=$DIR/$tdir/$tdir
21410         local testdata_02=$testdirs_02/${tdir}_02
21411         local testresult_02=${tdir}_02
21412         # Define third test dataset (top level)
21413         local testdata_03=$DIR/${tdir}_03
21414         local testresult_03=${tdir}_03
21415
21416         # Create first test dataset
21417         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21418         touch $testdata_01 || error "cannot create file $testdata_01"
21419
21420         # Create second test dataset
21421         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21422         touch $testdata_02 || error "cannot create file $testdata_02"
21423
21424         # Create third test dataset
21425         touch $testdata_03 || error "cannot create file $testdata_03"
21426
21427         local fid01=$($LFS getstripe -F "$testdata_01") ||
21428                 error "getstripe failed on $testdata_01"
21429         local fid02=$($LFS getstripe -F "$testdata_02") ||
21430                 error "getstripe failed on $testdata_01"
21431         local fid03=$($LFS getstripe -F "$testdata_03") ||
21432                 error "getstripe failed on $testdata_03"
21433
21434         # Verify only -n option
21435         local out1=$($LFS fid2path -n $DIR $fid01) ||
21436                 error "fid2path failed on $fid01"
21437         local out2=$($LFS fid2path -n $DIR $fid02) ||
21438                 error "fid2path failed on $fid02"
21439         local out3=$($LFS fid2path -n $DIR $fid03) ||
21440                 error "fid2path failed on $fid03"
21441
21442         [[ "$out1" == "$testresult_01" ]] ||
21443                 error "fid2path failed: Expected $testresult_01 got $out1"
21444         [[ "$out2" == "$testresult_02" ]] ||
21445                 error "fid2path failed: Expected $testresult_02 got $out2"
21446         [[ "$out3" == "$testresult_03" ]] ||
21447                 error "fid2path failed: Expected $testresult_03 got $out3"
21448
21449         # Verify with option -fn together
21450         out1=$($LFS fid2path -fn $DIR $fid01) ||
21451                 error "fid2path -fn failed on $fid01"
21452         out2=$($LFS fid2path -fn $DIR $fid02) ||
21453                 error "fid2path -fn failed on $fid02"
21454         out3=$($LFS fid2path -fn $DIR $fid03) ||
21455                 error "fid2path -fn failed on $fid03"
21456
21457         local tmpout=$(echo $out1 | cut -d" " -f2)
21458         [[ "$tmpout" == "$testresult_01" ]] ||
21459                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21460
21461         tmpout=$(echo $out2 | cut -d" " -f2)
21462         [[ "$tmpout" == "$testresult_02" ]] ||
21463                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21464
21465         tmpout=$(echo $out3 | cut -d" " -f2)
21466         [[ "$tmpout" == "$testresult_03" ]] ||
21467                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21468 }
21469 run_test 226d "verify fid2path with -n and -fn option"
21470
21471 test_226e () {
21472         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21473                 skip "Need client at least version 2.15.56"
21474
21475         # Define filename with 'newline' and a space
21476         local testfile="Test"$'\n'"file 01"
21477         # Define link name with multiple 'newline' and a space
21478         local linkfile="Link"$'\n'"file "$'\n'"01"
21479         # Remove prior hard link
21480         rm -f $DIR/"$linkfile"
21481
21482         # Create file
21483         touch $DIR/"$testfile"
21484         # Create link
21485         ln $DIR/"$testfile" $DIR/"$linkfile"
21486
21487         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21488                 error "getstripe failed on $DIR/$testfile"
21489
21490         # Call with -0 option
21491         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21492                 echo "FILE:" | grep -c "FILE:")
21493
21494         # With -0 option the output should be exactly 2 lines.
21495         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21496 }
21497 run_test 226e "Verify path2fid -0 option with newline and space"
21498
21499 # LU-1299 Executing or running ldd on a truncated executable does not
21500 # cause an out-of-memory condition.
21501 test_227() {
21502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21503         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21504
21505         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21506         chmod +x $MOUNT/date
21507
21508         $MOUNT/date > /dev/null
21509         ldd $MOUNT/date > /dev/null
21510         rm -f $MOUNT/date
21511 }
21512 run_test 227 "running truncated executable does not cause OOM"
21513
21514 # LU-1512 try to reuse idle OI blocks
21515 test_228a() {
21516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21517         remote_mds_nodsh && skip "remote MDS with nodsh"
21518         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21519
21520         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21521         local myDIR=$DIR/$tdir
21522
21523         mkdir -p $myDIR
21524         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21525         $LCTL set_param fail_loc=0x80001002
21526         createmany -o $myDIR/t- 10000
21527         $LCTL set_param fail_loc=0
21528         # The guard is current the largest FID holder
21529         touch $myDIR/guard
21530         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21531                     tr -d '[')
21532         local IDX=$(($SEQ % 64))
21533
21534         do_facet $SINGLEMDS sync
21535         # Make sure journal flushed.
21536         sleep 6
21537         local blk1=$(do_facet $SINGLEMDS \
21538                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21539                      grep Blockcount | awk '{print $4}')
21540
21541         # Remove old files, some OI blocks will become idle.
21542         unlinkmany $myDIR/t- 10000
21543         # Create new files, idle OI blocks should be reused.
21544         createmany -o $myDIR/t- 2000
21545         do_facet $SINGLEMDS sync
21546         # Make sure journal flushed.
21547         sleep 6
21548         local blk2=$(do_facet $SINGLEMDS \
21549                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21550                      grep Blockcount | awk '{print $4}')
21551
21552         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21553 }
21554 run_test 228a "try to reuse idle OI blocks"
21555
21556 test_228b() {
21557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21558         remote_mds_nodsh && skip "remote MDS with nodsh"
21559         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21560
21561         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21562         local myDIR=$DIR/$tdir
21563
21564         mkdir -p $myDIR
21565         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21566         $LCTL set_param fail_loc=0x80001002
21567         createmany -o $myDIR/t- 10000
21568         $LCTL set_param fail_loc=0
21569         # The guard is current the largest FID holder
21570         touch $myDIR/guard
21571         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21572                     tr -d '[')
21573         local IDX=$(($SEQ % 64))
21574
21575         do_facet $SINGLEMDS sync
21576         # Make sure journal flushed.
21577         sleep 6
21578         local blk1=$(do_facet $SINGLEMDS \
21579                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21580                      grep Blockcount | awk '{print $4}')
21581
21582         # Remove old files, some OI blocks will become idle.
21583         unlinkmany $myDIR/t- 10000
21584
21585         # stop the MDT
21586         stop $SINGLEMDS || error "Fail to stop MDT."
21587         # remount the MDT
21588         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21589                 error "Fail to start MDT."
21590
21591         client_up || error "Fail to df."
21592         # Create new files, idle OI blocks should be reused.
21593         createmany -o $myDIR/t- 2000
21594         do_facet $SINGLEMDS sync
21595         # Make sure journal flushed.
21596         sleep 6
21597         local blk2=$(do_facet $SINGLEMDS \
21598                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21599                      grep Blockcount | awk '{print $4}')
21600
21601         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21602 }
21603 run_test 228b "idle OI blocks can be reused after MDT restart"
21604
21605 #LU-1881
21606 test_228c() {
21607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21608         remote_mds_nodsh && skip "remote MDS with nodsh"
21609         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21610
21611         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21612         local myDIR=$DIR/$tdir
21613
21614         mkdir -p $myDIR
21615         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21616         $LCTL set_param fail_loc=0x80001002
21617         # 20000 files can guarantee there are index nodes in the OI file
21618         createmany -o $myDIR/t- 20000
21619         $LCTL set_param fail_loc=0
21620         # The guard is current the largest FID holder
21621         touch $myDIR/guard
21622         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21623                     tr -d '[')
21624         local IDX=$(($SEQ % 64))
21625
21626         do_facet $SINGLEMDS sync
21627         # Make sure journal flushed.
21628         sleep 6
21629         local blk1=$(do_facet $SINGLEMDS \
21630                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21631                      grep Blockcount | awk '{print $4}')
21632
21633         # Remove old files, some OI blocks will become idle.
21634         unlinkmany $myDIR/t- 20000
21635         rm -f $myDIR/guard
21636         # The OI file should become empty now
21637
21638         # Create new files, idle OI blocks should be reused.
21639         createmany -o $myDIR/t- 2000
21640         do_facet $SINGLEMDS sync
21641         # Make sure journal flushed.
21642         sleep 6
21643         local blk2=$(do_facet $SINGLEMDS \
21644                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21645                      grep Blockcount | awk '{print $4}')
21646
21647         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21648 }
21649 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21650
21651 test_229() { # LU-2482, LU-3448
21652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21653         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21654         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21655                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21656
21657         rm -f $DIR/$tfile
21658
21659         # Create a file with a released layout and stripe count 2.
21660         $MULTIOP $DIR/$tfile H2c ||
21661                 error "failed to create file with released layout"
21662
21663         $LFS getstripe -v $DIR/$tfile
21664
21665         local pattern=$($LFS getstripe -L $DIR/$tfile)
21666         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21667
21668         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21669                 error "getstripe"
21670         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21671         stat $DIR/$tfile || error "failed to stat released file"
21672
21673         chown $RUNAS_ID $DIR/$tfile ||
21674                 error "chown $RUNAS_ID $DIR/$tfile failed"
21675
21676         chgrp $RUNAS_ID $DIR/$tfile ||
21677                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21678
21679         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21680         rm $DIR/$tfile || error "failed to remove released file"
21681 }
21682 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21683
21684 test_230a() {
21685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21686         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21687         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21688                 skip "Need MDS version at least 2.11.52"
21689
21690         local MDTIDX=1
21691
21692         test_mkdir $DIR/$tdir
21693         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21694         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21695         [ $mdt_idx -ne 0 ] &&
21696                 error "create local directory on wrong MDT $mdt_idx"
21697
21698         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21699                         error "create remote directory failed"
21700         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21701         [ $mdt_idx -ne $MDTIDX ] &&
21702                 error "create remote directory on wrong MDT $mdt_idx"
21703
21704         createmany -o $DIR/$tdir/test_230/t- 10 ||
21705                 error "create files on remote directory failed"
21706         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21707         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21708         rm -r $DIR/$tdir || error "unlink remote directory failed"
21709 }
21710 run_test 230a "Create remote directory and files under the remote directory"
21711
21712 test_230b() {
21713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21715         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21716                 skip "Need MDS version at least 2.11.52"
21717
21718         local MDTIDX=1
21719         local mdt_index
21720         local i
21721         local file
21722         local pid
21723         local stripe_count
21724         local migrate_dir=$DIR/$tdir/migrate_dir
21725         local other_dir=$DIR/$tdir/other_dir
21726
21727         test_mkdir $DIR/$tdir
21728         test_mkdir -i0 -c1 $migrate_dir
21729         test_mkdir -i0 -c1 $other_dir
21730         for ((i=0; i<10; i++)); do
21731                 mkdir -p $migrate_dir/dir_${i}
21732                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21733                         error "create files under remote dir failed $i"
21734         done
21735
21736         cp /etc/passwd $migrate_dir/$tfile
21737         cp /etc/passwd $other_dir/$tfile
21738         chattr +SAD $migrate_dir
21739         chattr +SAD $migrate_dir/$tfile
21740
21741         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21742         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21743         local old_dir_mode=$(stat -c%f $migrate_dir)
21744         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21745
21746         mkdir -p $migrate_dir/dir_default_stripe2
21747         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21748         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21749
21750         mkdir -p $other_dir
21751         ln $migrate_dir/$tfile $other_dir/luna
21752         ln $migrate_dir/$tfile $migrate_dir/sofia
21753         ln $other_dir/$tfile $migrate_dir/david
21754         ln -s $migrate_dir/$tfile $other_dir/zachary
21755         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21756         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21757
21758         local len
21759         local lnktgt
21760
21761         # inline symlink
21762         for len in 58 59 60; do
21763                 lnktgt=$(str_repeat 'l' $len)
21764                 touch $migrate_dir/$lnktgt
21765                 ln -s $lnktgt $migrate_dir/${len}char_ln
21766         done
21767
21768         # PATH_MAX
21769         for len in 4094 4095; do
21770                 lnktgt=$(str_repeat 'l' $len)
21771                 ln -s $lnktgt $migrate_dir/${len}char_ln
21772         done
21773
21774         # NAME_MAX
21775         for len in 254 255; do
21776                 touch $migrate_dir/$(str_repeat 'l' $len)
21777         done
21778
21779         $LFS migrate -m $MDTIDX $migrate_dir ||
21780                 error "fails on migrating remote dir to MDT1"
21781
21782         echo "migratate to MDT1, then checking.."
21783         for ((i = 0; i < 10; i++)); do
21784                 for file in $(find $migrate_dir/dir_${i}); do
21785                         mdt_index=$($LFS getstripe -m $file)
21786                         # broken symlink getstripe will fail
21787                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21788                                 error "$file is not on MDT${MDTIDX}"
21789                 done
21790         done
21791
21792         # the multiple link file should still in MDT0
21793         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
21794         [ $mdt_index == 0 ] ||
21795                 error "$file is not on MDT${MDTIDX}"
21796
21797         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21798         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21799                 error " expect $old_dir_flag get $new_dir_flag"
21800
21801         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21802         [ "$old_file_flag" = "$new_file_flag" ] ||
21803                 error " expect $old_file_flag get $new_file_flag"
21804
21805         local new_dir_mode=$(stat -c%f $migrate_dir)
21806         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21807                 error "expect mode $old_dir_mode get $new_dir_mode"
21808
21809         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21810         [ "$old_file_mode" = "$new_file_mode" ] ||
21811                 error "expect mode $old_file_mode get $new_file_mode"
21812
21813         diff /etc/passwd $migrate_dir/$tfile ||
21814                 error "$tfile different after migration"
21815
21816         diff /etc/passwd $other_dir/luna ||
21817                 error "luna different after migration"
21818
21819         diff /etc/passwd $migrate_dir/sofia ||
21820                 error "sofia different after migration"
21821
21822         diff /etc/passwd $migrate_dir/david ||
21823                 error "david different after migration"
21824
21825         diff /etc/passwd $other_dir/zachary ||
21826                 error "zachary different after migration"
21827
21828         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21829                 error "${tfile}_ln different after migration"
21830
21831         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21832                 error "${tfile}_ln_other different after migration"
21833
21834         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
21835         [ $stripe_count = 2 ] ||
21836                 error "dir strpe_count $d != 2 after migration."
21837
21838         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
21839         [ $stripe_count = 2 ] ||
21840                 error "file strpe_count $d != 2 after migration."
21841
21842         #migrate back to MDT0
21843         MDTIDX=0
21844
21845         $LFS migrate -m $MDTIDX $migrate_dir ||
21846                 error "fails on migrating remote dir to MDT0"
21847
21848         echo "migrate back to MDT0, checking.."
21849         for file in $(find $migrate_dir); do
21850                 mdt_index=$($LFS getstripe -m $file)
21851                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
21852                         error "$file is not on MDT${MDTIDX}"
21853         done
21854
21855         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21856         [ "$old_dir_flag" = "$new_dir_flag" ] ||
21857                 error " expect $old_dir_flag get $new_dir_flag"
21858
21859         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21860         [ "$old_file_flag" = "$new_file_flag" ] ||
21861                 error " expect $old_file_flag get $new_file_flag"
21862
21863         local new_dir_mode=$(stat -c%f $migrate_dir)
21864         [ "$old_dir_mode" = "$new_dir_mode" ] ||
21865                 error "expect mode $old_dir_mode get $new_dir_mode"
21866
21867         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
21868         [ "$old_file_mode" = "$new_file_mode" ] ||
21869                 error "expect mode $old_file_mode get $new_file_mode"
21870
21871         diff /etc/passwd ${migrate_dir}/$tfile ||
21872                 error "$tfile different after migration"
21873
21874         diff /etc/passwd ${other_dir}/luna ||
21875                 error "luna different after migration"
21876
21877         diff /etc/passwd ${migrate_dir}/sofia ||
21878                 error "sofia different after migration"
21879
21880         diff /etc/passwd ${other_dir}/zachary ||
21881                 error "zachary different after migration"
21882
21883         diff /etc/passwd $migrate_dir/${tfile}_ln ||
21884                 error "${tfile}_ln different after migration"
21885
21886         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
21887                 error "${tfile}_ln_other different after migration"
21888
21889         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
21890         [ $stripe_count = 2 ] ||
21891                 error "dir strpe_count $d != 2 after migration."
21892
21893         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21894         [ $stripe_count = 2 ] ||
21895                 error "file strpe_count $d != 2 after migration."
21896
21897         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21898 }
21899 run_test 230b "migrate directory"
21900
21901 test_230c() {
21902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21903         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21904         remote_mds_nodsh && skip "remote MDS with nodsh"
21905         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21906                 skip "Need MDS version at least 2.11.52"
21907
21908         local MDTIDX=1
21909         local total=3
21910         local mdt_index
21911         local file
21912         local migrate_dir=$DIR/$tdir/migrate_dir
21913
21914         #If migrating directory fails in the middle, all entries of
21915         #the directory is still accessiable.
21916         test_mkdir $DIR/$tdir
21917         test_mkdir -i0 -c1 $migrate_dir
21918         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21919         stat $migrate_dir
21920         createmany -o $migrate_dir/f $total ||
21921                 error "create files under ${migrate_dir} failed"
21922
21923         # fail after migrating top dir, and this will fail only once, so the
21924         # first sub file migration will fail (currently f3), others succeed.
21925         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21926         do_facet mds1 lctl set_param fail_loc=0x1801
21927         local t=$(ls $migrate_dir | wc -l)
21928         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21929                 error "migrate should fail"
21930         local u=$(ls $migrate_dir | wc -l)
21931         [ "$u" == "$t" ] || error "$u != $t during migration"
21932
21933         # add new dir/file should succeed
21934         mkdir $migrate_dir/dir ||
21935                 error "mkdir failed under migrating directory"
21936         touch $migrate_dir/file ||
21937                 error "create file failed under migrating directory"
21938
21939         # add file with existing name should fail
21940         for file in $migrate_dir/f*; do
21941                 stat $file > /dev/null || error "stat $file failed"
21942                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21943                         error "open(O_CREAT|O_EXCL) $file should fail"
21944                 $MULTIOP $file m && error "create $file should fail"
21945                 touch $DIR/$tdir/remote_dir/$tfile ||
21946                         error "touch $tfile failed"
21947                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21948                         error "link $file should fail"
21949                 mdt_index=$($LFS getstripe -m $file)
21950                 if [ $mdt_index == 0 ]; then
21951                         # file failed to migrate is not allowed to rename to
21952                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21953                                 error "rename to $file should fail"
21954                 else
21955                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21956                                 error "rename to $file failed"
21957                 fi
21958                 echo hello >> $file || error "write $file failed"
21959         done
21960
21961         # resume migration with different options should fail
21962         $LFS migrate -m 0 $migrate_dir &&
21963                 error "migrate -m 0 $migrate_dir should fail"
21964
21965         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21966                 error "migrate -c 2 $migrate_dir should fail"
21967
21968         # resume migration should succeed
21969         $LFS migrate -m $MDTIDX $migrate_dir ||
21970                 error "migrate $migrate_dir failed"
21971
21972         echo "Finish migration, then checking.."
21973         for file in $(find $migrate_dir); do
21974                 mdt_index=$($LFS getstripe -m $file)
21975                 [ $mdt_index == $MDTIDX ] ||
21976                         error "$file is not on MDT${MDTIDX}"
21977         done
21978
21979         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21980 }
21981 run_test 230c "check directory accessiblity if migration failed"
21982
21983 test_230d() {
21984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21985         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21986         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21987                 skip "Need MDS version at least 2.11.52"
21988         # LU-11235
21989         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21990
21991         local migrate_dir=$DIR/$tdir/migrate_dir
21992         local old_index
21993         local new_index
21994         local old_count
21995         local new_count
21996         local new_hash
21997         local mdt_index
21998         local i
21999         local j
22000
22001         old_index=$((RANDOM % MDSCOUNT))
22002         old_count=$((MDSCOUNT - old_index))
22003         new_index=$((RANDOM % MDSCOUNT))
22004         new_count=$((MDSCOUNT - new_index))
22005         new_hash=1 # for all_char
22006
22007         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22008         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22009
22010         test_mkdir $DIR/$tdir
22011         test_mkdir -i $old_index -c $old_count $migrate_dir
22012
22013         for ((i=0; i<100; i++)); do
22014                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22015                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22016                         error "create files under remote dir failed $i"
22017         done
22018
22019         echo -n "Migrate from MDT$old_index "
22020         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22021         echo -n "to MDT$new_index"
22022         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22023         echo
22024
22025         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22026         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22027                 error "migrate remote dir error"
22028
22029         echo "Finish migration, then checking.."
22030         for file in $(find $migrate_dir -maxdepth 1); do
22031                 mdt_index=$($LFS getstripe -m $file)
22032                 if [ $mdt_index -lt $new_index ] ||
22033                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22034                         error "$file is on MDT$mdt_index"
22035                 fi
22036         done
22037
22038         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22039 }
22040 run_test 230d "check migrate big directory"
22041
22042 test_230e() {
22043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22044         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22045         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22046                 skip "Need MDS version at least 2.11.52"
22047
22048         local i
22049         local j
22050         local a_fid
22051         local b_fid
22052
22053         mkdir_on_mdt0 $DIR/$tdir
22054         mkdir $DIR/$tdir/migrate_dir
22055         mkdir $DIR/$tdir/other_dir
22056         touch $DIR/$tdir/migrate_dir/a
22057         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22058         ls $DIR/$tdir/other_dir
22059
22060         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22061                 error "migrate dir fails"
22062
22063         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22064         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22065
22066         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22067         [ $mdt_index == 0 ] || error "a is not on MDT0"
22068
22069         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22070                 error "migrate dir fails"
22071
22072         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22073         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22074
22075         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22076         [ $mdt_index == 1 ] || error "a is not on MDT1"
22077
22078         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22079         [ $mdt_index == 1 ] || error "b is not on MDT1"
22080
22081         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22082         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22083
22084         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22085
22086         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22087 }
22088 run_test 230e "migrate mulitple local link files"
22089
22090 test_230f() {
22091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22093         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22094                 skip "Need MDS version at least 2.11.52"
22095
22096         local a_fid
22097         local ln_fid
22098
22099         mkdir -p $DIR/$tdir
22100         mkdir $DIR/$tdir/migrate_dir
22101         $LFS mkdir -i1 $DIR/$tdir/other_dir
22102         touch $DIR/$tdir/migrate_dir/a
22103         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22104         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22105         ls $DIR/$tdir/other_dir
22106
22107         # a should be migrated to MDT1, since no other links on MDT0
22108         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22109                 error "#1 migrate dir fails"
22110         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22111         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22112         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22113         [ $mdt_index == 1 ] || error "a is not on MDT1"
22114
22115         # a should stay on MDT1, because it is a mulitple link file
22116         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22117                 error "#2 migrate dir fails"
22118         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22119         [ $mdt_index == 1 ] || error "a is not on MDT1"
22120
22121         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22122                 error "#3 migrate dir fails"
22123
22124         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22125         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22126         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22127
22128         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22129         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22130
22131         # a should be migrated to MDT0, since no other links on MDT1
22132         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22133                 error "#4 migrate dir fails"
22134         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22135         [ $mdt_index == 0 ] || error "a is not on MDT0"
22136
22137         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22138 }
22139 run_test 230f "migrate mulitple remote link files"
22140
22141 test_230g() {
22142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22144         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22145                 skip "Need MDS version at least 2.11.52"
22146
22147         mkdir -p $DIR/$tdir/migrate_dir
22148
22149         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22150                 error "migrating dir to non-exist MDT succeeds"
22151         true
22152 }
22153 run_test 230g "migrate dir to non-exist MDT"
22154
22155 test_230h() {
22156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22159                 skip "Need MDS version at least 2.11.52"
22160
22161         local mdt_index
22162
22163         mkdir -p $DIR/$tdir/migrate_dir
22164
22165         $LFS migrate -m1 $DIR &&
22166                 error "migrating mountpoint1 should fail"
22167
22168         $LFS migrate -m1 $DIR/$tdir/.. &&
22169                 error "migrating mountpoint2 should fail"
22170
22171         # same as mv
22172         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22173                 error "migrating $tdir/migrate_dir/.. should fail"
22174
22175         true
22176 }
22177 run_test 230h "migrate .. and root"
22178
22179 test_230i() {
22180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22181         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22182         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22183                 skip "Need MDS version at least 2.11.52"
22184
22185         mkdir -p $DIR/$tdir/migrate_dir
22186
22187         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22188                 error "migration fails with a tailing slash"
22189
22190         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22191                 error "migration fails with two tailing slashes"
22192 }
22193 run_test 230i "lfs migrate -m tolerates trailing slashes"
22194
22195 test_230j() {
22196         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22197         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22198                 skip "Need MDS version at least 2.11.52"
22199
22200         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22201         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22202                 error "create $tfile failed"
22203         cat /etc/passwd > $DIR/$tdir/$tfile
22204
22205         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22206
22207         cmp /etc/passwd $DIR/$tdir/$tfile ||
22208                 error "DoM file mismatch after migration"
22209 }
22210 run_test 230j "DoM file data not changed after dir migration"
22211
22212 test_230k() {
22213         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22214         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22215                 skip "Need MDS version at least 2.11.56"
22216
22217         local total=20
22218         local files_on_starting_mdt=0
22219
22220         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22221         $LFS getdirstripe $DIR/$tdir
22222         for i in $(seq $total); do
22223                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22224                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22225                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22226         done
22227
22228         echo "$files_on_starting_mdt files on MDT0"
22229
22230         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22231         $LFS getdirstripe $DIR/$tdir
22232
22233         files_on_starting_mdt=0
22234         for i in $(seq $total); do
22235                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22236                         error "file $tfile.$i mismatch after migration"
22237                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22238                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22239         done
22240
22241         echo "$files_on_starting_mdt files on MDT1 after migration"
22242         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22243
22244         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22245         $LFS getdirstripe $DIR/$tdir
22246
22247         files_on_starting_mdt=0
22248         for i in $(seq $total); do
22249                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22250                         error "file $tfile.$i mismatch after 2nd migration"
22251                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22252                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22253         done
22254
22255         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22256         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22257
22258         true
22259 }
22260 run_test 230k "file data not changed after dir migration"
22261
22262 test_230l() {
22263         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22264         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22265                 skip "Need MDS version at least 2.11.56"
22266
22267         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22268         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22269                 error "create files under remote dir failed $i"
22270         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22271 }
22272 run_test 230l "readdir between MDTs won't crash"
22273
22274 test_230m() {
22275         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22276         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22277                 skip "Need MDS version at least 2.11.56"
22278
22279         local MDTIDX=1
22280         local mig_dir=$DIR/$tdir/migrate_dir
22281         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22282         local shortstr="b"
22283         local val
22284
22285         echo "Creating files and dirs with xattrs"
22286         test_mkdir $DIR/$tdir
22287         test_mkdir -i0 -c1 $mig_dir
22288         mkdir $mig_dir/dir
22289         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22290                 error "cannot set xattr attr1 on dir"
22291         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22292                 error "cannot set xattr attr2 on dir"
22293         touch $mig_dir/dir/f0
22294         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22295                 error "cannot set xattr attr1 on file"
22296         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22297                 error "cannot set xattr attr2 on file"
22298         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22299         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22300         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22301         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22302         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22303         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22304         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22305         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22306         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22307
22308         echo "Migrating to MDT1"
22309         $LFS migrate -m $MDTIDX $mig_dir ||
22310                 error "fails on migrating dir to MDT1"
22311
22312         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22313         echo "Checking xattrs"
22314         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22315         [ "$val" = $longstr ] ||
22316                 error "expecting xattr1 $longstr on dir, found $val"
22317         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22318         [ "$val" = $shortstr ] ||
22319                 error "expecting xattr2 $shortstr on dir, found $val"
22320         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22321         [ "$val" = $longstr ] ||
22322                 error "expecting xattr1 $longstr on file, found $val"
22323         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22324         [ "$val" = $shortstr ] ||
22325                 error "expecting xattr2 $shortstr on file, found $val"
22326 }
22327 run_test 230m "xattrs not changed after dir migration"
22328
22329 test_230n() {
22330         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22331         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22332                 skip "Need MDS version at least 2.13.53"
22333
22334         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22335         cat /etc/hosts > $DIR/$tdir/$tfile
22336         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22337         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22338
22339         cmp /etc/hosts $DIR/$tdir/$tfile ||
22340                 error "File data mismatch after migration"
22341 }
22342 run_test 230n "Dir migration with mirrored file"
22343
22344 test_230o() {
22345         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22346         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22347                 skip "Need MDS version at least 2.13.52"
22348
22349         local mdts=$(comma_list $(mdts_nodes))
22350         local timeout=100
22351         local restripe_status
22352         local delta
22353         local i
22354
22355         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22356
22357         # in case "crush" hash type is not set
22358         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22359
22360         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22361                            mdt.*MDT0000.enable_dir_restripe)
22362         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22363         stack_trap "do_nodes $mdts $LCTL set_param \
22364                     mdt.*.enable_dir_restripe=$restripe_status"
22365
22366         mkdir $DIR/$tdir
22367         createmany -m $DIR/$tdir/f 100 ||
22368                 error "create files under remote dir failed $i"
22369         createmany -d $DIR/$tdir/d 100 ||
22370                 error "create dirs under remote dir failed $i"
22371
22372         for i in $(seq 2 $MDSCOUNT); do
22373                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22374                 $LFS setdirstripe -c $i $DIR/$tdir ||
22375                         error "split -c $i $tdir failed"
22376                 wait_update $HOSTNAME \
22377                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22378                         error "dir split not finished"
22379                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22380                         awk '/migrate/ {sum += $2} END { print sum }')
22381                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22382                 # delta is around total_files/stripe_count
22383                 (( $delta < 200 / (i - 1) + 4 )) ||
22384                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22385         done
22386 }
22387 run_test 230o "dir split"
22388
22389 test_230p() {
22390         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22391         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22392                 skip "Need MDS version at least 2.13.52"
22393
22394         local mdts=$(comma_list $(mdts_nodes))
22395         local timeout=100
22396         local restripe_status
22397         local delta
22398         local c
22399
22400         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22401
22402         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22403
22404         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22405                            mdt.*MDT0000.enable_dir_restripe)
22406         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22407         stack_trap "do_nodes $mdts $LCTL set_param \
22408                     mdt.*.enable_dir_restripe=$restripe_status"
22409
22410         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22411         createmany -m $DIR/$tdir/f 100 ||
22412                 error "create files under remote dir failed"
22413         createmany -d $DIR/$tdir/d 100 ||
22414                 error "create dirs under remote dir failed"
22415
22416         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22417                 local mdt_hash="crush"
22418
22419                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22420                 $LFS setdirstripe -c $c $DIR/$tdir ||
22421                         error "split -c $c $tdir failed"
22422                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22423                         mdt_hash="$mdt_hash,fixed"
22424                 elif [ $c -eq 1 ]; then
22425                         mdt_hash="none"
22426                 fi
22427                 wait_update $HOSTNAME \
22428                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22429                         error "dir merge not finished"
22430                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22431                         awk '/migrate/ {sum += $2} END { print sum }')
22432                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22433                 # delta is around total_files/stripe_count
22434                 (( delta < 200 / c + 4 )) ||
22435                         error "$delta files migrated >= $((200 / c + 4))"
22436         done
22437 }
22438 run_test 230p "dir merge"
22439
22440 test_230q() {
22441         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22442         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22443                 skip "Need MDS version at least 2.13.52"
22444
22445         local mdts=$(comma_list $(mdts_nodes))
22446         local saved_threshold=$(do_facet mds1 \
22447                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22448         local saved_delta=$(do_facet mds1 \
22449                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22450         local threshold=100
22451         local delta=2
22452         local total=0
22453         local stripe_count=0
22454         local stripe_index
22455         local nr_files
22456         local create
22457
22458         # test with fewer files on ZFS
22459         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22460
22461         stack_trap "do_nodes $mdts $LCTL set_param \
22462                     mdt.*.dir_split_count=$saved_threshold"
22463         stack_trap "do_nodes $mdts $LCTL set_param \
22464                     mdt.*.dir_split_delta=$saved_delta"
22465         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22466         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22467         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22468         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22469         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22470         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22471
22472         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22473         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22474
22475         create=$((threshold * 3 / 2))
22476         while [ $stripe_count -lt $MDSCOUNT ]; do
22477                 createmany -m $DIR/$tdir/f $total $create ||
22478                         error "create sub files failed"
22479                 stat $DIR/$tdir > /dev/null
22480                 total=$((total + create))
22481                 stripe_count=$((stripe_count + delta))
22482                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22483
22484                 wait_update $HOSTNAME \
22485                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22486                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22487
22488                 wait_update $HOSTNAME \
22489                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22490                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22491
22492                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22493                 echo "$nr_files/$total files on MDT$stripe_index after split"
22494                 # allow 10% margin of imbalance with crush hash
22495                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22496                         error "$nr_files files on MDT$stripe_index after split"
22497
22498                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22499                 [ $nr_files -eq $total ] ||
22500                         error "total sub files $nr_files != $total"
22501         done
22502
22503         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22504
22505         echo "fixed layout directory won't auto split"
22506         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22507         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22508                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22509         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22510                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22511 }
22512 run_test 230q "dir auto split"
22513
22514 test_230r() {
22515         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22516         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22517         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22518                 skip "Need MDS version at least 2.13.54"
22519
22520         # maximum amount of local locks:
22521         # parent striped dir - 2 locks
22522         # new stripe in parent to migrate to - 1 lock
22523         # source and target - 2 locks
22524         # Total 5 locks for regular file
22525         mkdir -p $DIR/$tdir
22526         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22527         touch $DIR/$tdir/dir1/eee
22528
22529         # create 4 hardlink for 4 more locks
22530         # Total: 9 locks > RS_MAX_LOCKS (8)
22531         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22532         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22533         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22534         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22535         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22536         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22537         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22538         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22539
22540         cancel_lru_locks mdc
22541
22542         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22543                 error "migrate dir fails"
22544
22545         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22546 }
22547 run_test 230r "migrate with too many local locks"
22548
22549 test_230s() {
22550         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22551                 skip "Need MDS version at least 2.14.52"
22552
22553         local mdts=$(comma_list $(mdts_nodes))
22554         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22555                                 mdt.*MDT0000.enable_dir_restripe)
22556
22557         stack_trap "do_nodes $mdts $LCTL set_param \
22558                     mdt.*.enable_dir_restripe=$restripe_status"
22559
22560         local st
22561         for st in 0 1; do
22562                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22563                 test_mkdir $DIR/$tdir
22564                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22565                         error "$LFS mkdir should return EEXIST if target exists"
22566                 rmdir $DIR/$tdir
22567         done
22568 }
22569 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22570
22571 test_230t()
22572 {
22573         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22574         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
22575                 skip "Need MDS version at least 2.14.50"
22576
22577         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22578         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22579         $LFS project -p 1 -s $DIR/$tdir ||
22580                 error "set $tdir project id failed"
22581         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22582                 error "set subdir project id failed"
22583         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22584 }
22585 run_test 230t "migrate directory with project ID set"
22586
22587 test_230u()
22588 {
22589         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22590         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22591                 skip "Need MDS version at least 2.14.53"
22592
22593         local count
22594
22595         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22596         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22597         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22598         for i in $(seq 0 $((MDSCOUNT - 1))); do
22599                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22600                 echo "$count dirs migrated to MDT$i"
22601         done
22602         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22603         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22604 }
22605 run_test 230u "migrate directory by QOS"
22606
22607 test_230v()
22608 {
22609         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22610         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22611                 skip "Need MDS version at least 2.14.53"
22612
22613         local count
22614
22615         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22616         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22617         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22618         for i in $(seq 0 $((MDSCOUNT - 1))); do
22619                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22620                 echo "$count subdirs migrated to MDT$i"
22621                 (( i == 3 )) && (( count > 0 )) &&
22622                         error "subdir shouldn't be migrated to MDT3"
22623         done
22624         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22625         (( count == 3 )) || error "dirs migrated to $count MDTs"
22626 }
22627 run_test 230v "subdir migrated to the MDT where its parent is located"
22628
22629 test_230w() {
22630         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22631         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22632                 skip "Need MDS version at least 2.15.0"
22633
22634         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22635         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22636         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22637
22638         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22639                 error "migrate failed"
22640
22641         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22642                 error "$tdir stripe count mismatch"
22643
22644         for i in $(seq 0 9); do
22645                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22646                         error "d$i is striped"
22647         done
22648 }
22649 run_test 230w "non-recursive mode dir migration"
22650
22651 test_230x() {
22652         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22653         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22654                 skip "Need MDS version at least 2.15.0"
22655
22656         mkdir -p $DIR/$tdir || error "mkdir failed"
22657         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22658
22659         local mdt_name=$(mdtname_from_index 0)
22660         local low=$(do_facet mds2 $LCTL get_param -n \
22661                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22662         local high=$(do_facet mds2 $LCTL get_param -n \
22663                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22664         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22665         local maxage=$(do_facet mds2 $LCTL get_param -n \
22666                 osp.*$mdt_name-osp-MDT0001.maxage)
22667
22668         stack_trap "do_facet mds2 $LCTL set_param -n \
22669                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22670                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22671         stack_trap "do_facet mds2 $LCTL set_param -n \
22672                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22673
22674         do_facet mds2 $LCTL set_param -n \
22675                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22676         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22677         sleep 4
22678         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22679                 error "migrate $tdir should fail"
22680
22681         do_facet mds2 $LCTL set_param -n \
22682                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22683         do_facet mds2 $LCTL set_param -n \
22684                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22685         sleep 4
22686         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22687                 error "migrate failed"
22688         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22689                 error "$tdir stripe count mismatch"
22690 }
22691 run_test 230x "dir migration check space"
22692
22693 test_230y() {
22694         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22695         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22696                 skip "Need MDS version at least 2.15.55.45"
22697
22698         local pid
22699
22700         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22701         $LFS getdirstripe $DIR/$tdir
22702         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22703         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22704         pid=$!
22705         sleep 1
22706
22707         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22708         do_facet mds2 lctl set_param fail_loc=0x1802
22709
22710         wait $pid
22711         do_facet mds2 lctl set_param fail_loc=0
22712         $LFS getdirstripe $DIR/$tdir
22713         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22714         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22715 }
22716 run_test 230y "unlink dir with bad hash type"
22717
22718 test_230z() {
22719         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22720         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22721                 skip "Need MDS version at least 2.15.55.45"
22722
22723         local pid
22724
22725         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22726         $LFS getdirstripe $DIR/$tdir
22727         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22728         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22729         pid=$!
22730         sleep 1
22731
22732         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22733         do_facet mds2 lctl set_param fail_loc=0x1802
22734
22735         wait $pid
22736         do_facet mds2 lctl set_param fail_loc=0
22737         $LFS getdirstripe $DIR/$tdir
22738
22739         # resume migration
22740         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22741                 error "resume migration failed"
22742         $LFS getdirstripe $DIR/$tdir
22743         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22744                 error "migration is not finished"
22745 }
22746 run_test 230z "resume dir migration with bad hash type"
22747
22748 test_231a()
22749 {
22750         # For simplicity this test assumes that max_pages_per_rpc
22751         # is the same across all OSCs
22752         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
22753         local bulk_size=$((max_pages * PAGE_SIZE))
22754         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
22755                                        head -n 1)
22756
22757         mkdir -p $DIR/$tdir
22758         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
22759                 error "failed to set stripe with -S ${brw_size}M option"
22760         stack_trap "rm -rf $DIR/$tdir"
22761
22762         # clear the OSC stats
22763         $LCTL set_param osc.*.stats=0 &>/dev/null
22764         stop_writeback
22765
22766         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
22767         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
22768                 oflag=direct &>/dev/null || error "dd failed"
22769
22770         sync; sleep 1; sync # just to be safe
22771         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
22772         if [ x$nrpcs != "x1" ]; then
22773                 $LCTL get_param osc.*.stats
22774                 error "found $nrpcs ost_write RPCs, not 1 as expected"
22775         fi
22776
22777         start_writeback
22778         # Drop the OSC cache, otherwise we will read from it
22779         cancel_lru_locks osc
22780
22781         # clear the OSC stats
22782         $LCTL set_param osc.*.stats=0 &>/dev/null
22783
22784         # Client reads $bulk_size.
22785         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
22786                 iflag=direct &>/dev/null || error "dd failed"
22787
22788         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
22789         if [ x$nrpcs != "x1" ]; then
22790                 $LCTL get_param osc.*.stats
22791                 error "found $nrpcs ost_read RPCs, not 1 as expected"
22792         fi
22793 }
22794 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
22795
22796 test_231b() {
22797         mkdir -p $DIR/$tdir
22798         stack_trap "rm -rf $DIR/$tdir"
22799         local i
22800         for i in {0..1023}; do
22801                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
22802                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
22803                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
22804         done
22805         sync
22806 }
22807 run_test 231b "must not assert on fully utilized OST request buffer"
22808
22809 test_232a() {
22810         mkdir -p $DIR/$tdir
22811         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22812
22813         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22814         do_facet ost1 $LCTL set_param fail_loc=0x31c
22815
22816         # ignore dd failure
22817         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
22818         stack_trap "rm -f $DIR/$tdir/$tfile"
22819
22820         do_facet ost1 $LCTL set_param fail_loc=0
22821         umount_client $MOUNT || error "umount failed"
22822         mount_client $MOUNT || error "mount failed"
22823         stop ost1 || error "cannot stop ost1"
22824         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22825 }
22826 run_test 232a "failed lock should not block umount"
22827
22828 test_232b() {
22829         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
22830                 skip "Need MDS version at least 2.10.58"
22831
22832         mkdir -p $DIR/$tdir
22833         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
22834         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
22835         stack_trap "rm -f $DIR/$tdir/$tfile"
22836         sync
22837         cancel_lru_locks osc
22838
22839         #define OBD_FAIL_LDLM_OST_LVB            0x31c
22840         do_facet ost1 $LCTL set_param fail_loc=0x31c
22841
22842         # ignore failure
22843         $LFS data_version $DIR/$tdir/$tfile || true
22844
22845         do_facet ost1 $LCTL set_param fail_loc=0
22846         umount_client $MOUNT || error "umount failed"
22847         mount_client $MOUNT || error "mount failed"
22848         stop ost1 || error "cannot stop ost1"
22849         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22850 }
22851 run_test 232b "failed data version lock should not block umount"
22852
22853 test_233a() {
22854         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
22855                 skip "Need MDS version at least 2.3.64"
22856         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22857
22858         local fid=$($LFS path2fid $MOUNT)
22859
22860         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22861                 error "cannot access $MOUNT using its FID '$fid'"
22862 }
22863 run_test 233a "checking that OBF of the FS root succeeds"
22864
22865 test_233b() {
22866         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
22867                 skip "Need MDS version at least 2.5.90"
22868         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
22869
22870         local fid=$($LFS path2fid $MOUNT/.lustre)
22871
22872         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22873                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
22874
22875         fid=$($LFS path2fid $MOUNT/.lustre/fid)
22876         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
22877                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
22878 }
22879 run_test 233b "checking that OBF of the FS .lustre succeeds"
22880
22881 test_234() {
22882         local p="$TMP/sanityN-$TESTNAME.parameters"
22883         save_lustre_params client "llite.*.xattr_cache" > $p
22884         lctl set_param llite.*.xattr_cache 1 ||
22885                 skip_env "xattr cache is not supported"
22886
22887         mkdir -p $DIR/$tdir || error "mkdir failed"
22888         touch $DIR/$tdir/$tfile || error "touch failed"
22889         # OBD_FAIL_LLITE_XATTR_ENOMEM
22890         $LCTL set_param fail_loc=0x1405
22891         getfattr -n user.attr $DIR/$tdir/$tfile &&
22892                 error "getfattr should have failed with ENOMEM"
22893         $LCTL set_param fail_loc=0x0
22894         rm -rf $DIR/$tdir
22895
22896         restore_lustre_params < $p
22897         rm -f $p
22898 }
22899 run_test 234 "xattr cache should not crash on ENOMEM"
22900
22901 test_235() {
22902         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
22903                 skip "Need MDS version at least 2.4.52"
22904
22905         flock_deadlock $DIR/$tfile
22906         local RC=$?
22907         case $RC in
22908                 0)
22909                 ;;
22910                 124) error "process hangs on a deadlock"
22911                 ;;
22912                 *) error "error executing flock_deadlock $DIR/$tfile"
22913                 ;;
22914         esac
22915 }
22916 run_test 235 "LU-1715: flock deadlock detection does not work properly"
22917
22918 #LU-2935
22919 test_236() {
22920         check_swap_layouts_support
22921
22922         local ref1=/etc/passwd
22923         local ref2=/etc/group
22924         local file1=$DIR/$tdir/f1
22925         local file2=$DIR/$tdir/f2
22926
22927         test_mkdir -c1 $DIR/$tdir
22928         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
22929         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
22930         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
22931         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
22932         local fd=$(free_fd)
22933         local cmd="exec $fd<>$file2"
22934         eval $cmd
22935         rm $file2
22936         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
22937                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
22938         cmd="exec $fd>&-"
22939         eval $cmd
22940         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
22941
22942         #cleanup
22943         rm -rf $DIR/$tdir
22944 }
22945 run_test 236 "Layout swap on open unlinked file"
22946
22947 # LU-4659 linkea consistency
22948 test_238() {
22949         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
22950                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
22951                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
22952                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22953
22954         touch $DIR/$tfile
22955         ln $DIR/$tfile $DIR/$tfile.lnk
22956         touch $DIR/$tfile.new
22957         mv $DIR/$tfile.new $DIR/$tfile
22958         local fid1=$($LFS path2fid $DIR/$tfile)
22959         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22960         local path1=$($LFS fid2path $FSNAME "$fid1")
22961         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22962         local path2=$($LFS fid2path $FSNAME "$fid2")
22963         [ $tfile.lnk == $path2 ] ||
22964                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22965         rm -f $DIR/$tfile*
22966 }
22967 run_test 238 "Verify linkea consistency"
22968
22969 test_239A() { # was test_239
22970         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22971                 skip "Need MDS version at least 2.5.60"
22972
22973         local list=$(comma_list $(mdts_nodes))
22974
22975         mkdir -p $DIR/$tdir
22976         createmany -o $DIR/$tdir/f- 5000
22977         unlinkmany $DIR/$tdir/f- 5000
22978         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22979                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22980         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22981                         osp.*MDT*.sync_in_flight" | calc_sum)
22982         [ "$changes" -eq 0 ] || error "$changes not synced"
22983 }
22984 run_test 239A "osp_sync test"
22985
22986 test_239a() { #LU-5297
22987         remote_mds_nodsh && skip "remote MDS with nodsh"
22988
22989         touch $DIR/$tfile
22990         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22991         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22992         chgrp $RUNAS_GID $DIR/$tfile
22993         wait_delete_completed
22994 }
22995 run_test 239a "process invalid osp sync record correctly"
22996
22997 test_239b() { #LU-5297
22998         remote_mds_nodsh && skip "remote MDS with nodsh"
22999
23000         touch $DIR/$tfile1
23001         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23002         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23003         chgrp $RUNAS_GID $DIR/$tfile1
23004         wait_delete_completed
23005         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23006         touch $DIR/$tfile2
23007         chgrp $RUNAS_GID $DIR/$tfile2
23008         wait_delete_completed
23009 }
23010 run_test 239b "process osp sync record with ENOMEM error correctly"
23011
23012 test_240() {
23013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23014         remote_mds_nodsh && skip "remote MDS with nodsh"
23015
23016         mkdir -p $DIR/$tdir
23017
23018         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23019                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23020         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23021                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23022
23023         umount_client $MOUNT || error "umount failed"
23024         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23025         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23026         mount_client $MOUNT || error "failed to mount client"
23027
23028         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23029         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23030 }
23031 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23032
23033 test_241_bio() {
23034         local count=$1
23035         local bsize=$2
23036
23037         for LOOP in $(seq $count); do
23038                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23039                 cancel_lru_locks $OSC || true
23040         done
23041 }
23042
23043 test_241_dio() {
23044         local count=$1
23045         local bsize=$2
23046
23047         for LOOP in $(seq $1); do
23048                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23049                         2>/dev/null
23050         done
23051 }
23052
23053 test_241a() { # was test_241
23054         local bsize=$PAGE_SIZE
23055
23056         (( bsize < 40960 )) && bsize=40960
23057         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23058         ls -la $DIR/$tfile
23059         cancel_lru_locks $OSC
23060         test_241_bio 1000 $bsize &
23061         PID=$!
23062         test_241_dio 1000 $bsize
23063         wait $PID
23064 }
23065 run_test 241a "bio vs dio"
23066
23067 test_241b() {
23068         local bsize=$PAGE_SIZE
23069
23070         (( bsize < 40960 )) && bsize=40960
23071         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23072         ls -la $DIR/$tfile
23073         test_241_dio 1000 $bsize &
23074         PID=$!
23075         test_241_dio 1000 $bsize
23076         wait $PID
23077 }
23078 run_test 241b "dio vs dio"
23079
23080 test_242() {
23081         remote_mds_nodsh && skip "remote MDS with nodsh"
23082
23083         mkdir_on_mdt0 $DIR/$tdir
23084         touch $DIR/$tdir/$tfile
23085
23086         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23087         do_facet mds1 lctl set_param fail_loc=0x105
23088         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23089
23090         do_facet mds1 lctl set_param fail_loc=0
23091         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23092 }
23093 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23094
23095 test_243()
23096 {
23097         test_mkdir $DIR/$tdir
23098         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23099 }
23100 run_test 243 "various group lock tests"
23101
23102 test_244a()
23103 {
23104         test_mkdir $DIR/$tdir
23105         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23106         sendfile_grouplock $DIR/$tdir/$tfile || \
23107                 error "sendfile+grouplock failed"
23108         rm -rf $DIR/$tdir
23109 }
23110 run_test 244a "sendfile with group lock tests"
23111
23112 test_244b()
23113 {
23114         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23115
23116         local threads=50
23117         local size=$((1024*1024))
23118
23119         test_mkdir $DIR/$tdir
23120         for i in $(seq 1 $threads); do
23121                 local file=$DIR/$tdir/file_$((i / 10))
23122                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23123                 local pids[$i]=$!
23124         done
23125         for i in $(seq 1 $threads); do
23126                 wait ${pids[$i]}
23127         done
23128 }
23129 run_test 244b "multi-threaded write with group lock"
23130
23131 test_245a() {
23132         local flagname="multi_mod_rpcs"
23133         local connect_data_name="max_mod_rpcs"
23134         local out
23135
23136         # check if multiple modify RPCs flag is set
23137         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23138                 grep "connect_flags:")
23139         echo "$out"
23140
23141         echo "$out" | grep -qw $flagname
23142         if [ $? -ne 0 ]; then
23143                 echo "connect flag $flagname is not set"
23144                 return
23145         fi
23146
23147         # check if multiple modify RPCs data is set
23148         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23149         echo "$out"
23150
23151         echo "$out" | grep -qw $connect_data_name ||
23152                 error "import should have connect data $connect_data_name"
23153 }
23154 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23155
23156 test_245b() {
23157         local flagname="multi_mod_rpcs"
23158         local connect_data_name="max_mod_rpcs"
23159         local out
23160
23161         remote_mds_nodsh && skip "remote MDS with nodsh"
23162         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23163
23164         # check if multiple modify RPCs flag is set
23165         out=$(do_facet mds1 \
23166               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23167               grep "connect_flags:")
23168         echo "$out"
23169
23170         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23171
23172         # check if multiple modify RPCs data is set
23173         out=$(do_facet mds1 \
23174               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23175
23176         [[ "$out" =~ $connect_data_name ]] ||
23177                 {
23178                         echo "$out"
23179                         error "missing connect data $connect_data_name"
23180                 }
23181 }
23182 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23183
23184 cleanup_247() {
23185         local submount=$1
23186
23187         trap 0
23188         umount_client $submount
23189         rmdir $submount
23190 }
23191
23192 test_247a() {
23193         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23194                 grep -q subtree ||
23195                 skip_env "Fileset feature is not supported"
23196
23197         local submount=${MOUNT}_$tdir
23198
23199         mkdir $MOUNT/$tdir
23200         mkdir -p $submount || error "mkdir $submount failed"
23201         FILESET="$FILESET/$tdir" mount_client $submount ||
23202                 error "mount $submount failed"
23203         trap "cleanup_247 $submount" EXIT
23204         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23205         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23206                 error "read $MOUNT/$tdir/$tfile failed"
23207         cleanup_247 $submount
23208 }
23209 run_test 247a "mount subdir as fileset"
23210
23211 test_247b() {
23212         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23213                 skip_env "Fileset feature is not supported"
23214
23215         local submount=${MOUNT}_$tdir
23216
23217         rm -rf $MOUNT/$tdir
23218         mkdir -p $submount || error "mkdir $submount failed"
23219         SKIP_FILESET=1
23220         FILESET="$FILESET/$tdir" mount_client $submount &&
23221                 error "mount $submount should fail"
23222         rmdir $submount
23223 }
23224 run_test 247b "mount subdir that dose not exist"
23225
23226 test_247c() {
23227         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23228                 skip_env "Fileset feature is not supported"
23229
23230         local submount=${MOUNT}_$tdir
23231
23232         mkdir -p $MOUNT/$tdir/dir1
23233         mkdir -p $submount || error "mkdir $submount failed"
23234         trap "cleanup_247 $submount" EXIT
23235         FILESET="$FILESET/$tdir" mount_client $submount ||
23236                 error "mount $submount failed"
23237         local fid=$($LFS path2fid $MOUNT/)
23238         $LFS fid2path $submount $fid && error "fid2path should fail"
23239         cleanup_247 $submount
23240 }
23241 run_test 247c "running fid2path outside subdirectory root"
23242
23243 test_247d() {
23244         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23245                 skip "Fileset feature is not supported"
23246
23247         local submount=${MOUNT}_$tdir
23248
23249         mkdir -p $MOUNT/$tdir/dir1
23250         mkdir -p $submount || error "mkdir $submount failed"
23251         FILESET="$FILESET/$tdir" mount_client $submount ||
23252                 error "mount $submount failed"
23253         trap "cleanup_247 $submount" EXIT
23254
23255         local td=$submount/dir1
23256         local fid=$($LFS path2fid $td)
23257         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23258
23259         # check that we get the same pathname back
23260         local rootpath
23261         local found
23262         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23263                 echo "$rootpath $fid"
23264                 found=$($LFS fid2path $rootpath "$fid")
23265                 [ -n "$found" ] || error "fid2path should succeed"
23266                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23267         done
23268         # check wrong root path format
23269         rootpath=$submount"_wrong"
23270         found=$($LFS fid2path $rootpath "$fid")
23271         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23272
23273         cleanup_247 $submount
23274 }
23275 run_test 247d "running fid2path inside subdirectory root"
23276
23277 # LU-8037
23278 test_247e() {
23279         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23280                 grep -q subtree ||
23281                 skip "Fileset feature is not supported"
23282
23283         local submount=${MOUNT}_$tdir
23284
23285         mkdir $MOUNT/$tdir
23286         mkdir -p $submount || error "mkdir $submount failed"
23287         FILESET="$FILESET/.." mount_client $submount &&
23288                 error "mount $submount should fail"
23289         rmdir $submount
23290 }
23291 run_test 247e "mount .. as fileset"
23292
23293 test_247f() {
23294         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23295         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23296                 skip "Need at least version 2.14.50.162"
23297         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23298                 skip "Fileset feature is not supported"
23299
23300         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23301         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23302                 error "mkdir remote failed"
23303         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23304                 error "mkdir remote/subdir failed"
23305         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23306                 error "mkdir striped failed"
23307         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23308
23309         local submount=${MOUNT}_$tdir
23310
23311         mkdir -p $submount || error "mkdir $submount failed"
23312         stack_trap "rmdir $submount"
23313
23314         local dir
23315         local fileset=$FILESET
23316         local mdts=$(comma_list $(mdts_nodes))
23317
23318         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23319         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23320                 $tdir/striped/subdir $tdir/striped/.; do
23321                 FILESET="$fileset/$dir" mount_client $submount ||
23322                         error "mount $dir failed"
23323                 umount_client $submount
23324         done
23325 }
23326 run_test 247f "mount striped or remote directory as fileset"
23327
23328 test_subdir_mount_lock()
23329 {
23330         local testdir=$1
23331         local submount=${MOUNT}_$(basename $testdir)
23332
23333         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23334
23335         mkdir -p $submount || error "mkdir $submount failed"
23336         stack_trap "rmdir $submount"
23337
23338         FILESET="$fileset/$testdir" mount_client $submount ||
23339                 error "mount $FILESET failed"
23340         stack_trap "umount $submount"
23341
23342         local mdts=$(comma_list $(mdts_nodes))
23343
23344         local nrpcs
23345
23346         stat $submount > /dev/null || error "stat $submount failed"
23347         cancel_lru_locks $MDC
23348         stat $submount > /dev/null || error "stat $submount failed"
23349         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23350         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23351         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23352         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23353                 awk '/getattr/ {sum += $2} END {print sum}')
23354
23355         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23356 }
23357
23358 test_247g() {
23359         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23360
23361         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23362                 error "mkdir $tdir failed"
23363         test_subdir_mount_lock $tdir
23364 }
23365 run_test 247g "striped directory submount revalidate ROOT from cache"
23366
23367 test_247h() {
23368         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23369         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23370                 skip "Need MDS version at least 2.15.51"
23371
23372         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23373         test_subdir_mount_lock $tdir
23374         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23375         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23376                 error "mkdir $tdir.1 failed"
23377         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23378 }
23379 run_test 247h "remote directory submount revalidate ROOT from cache"
23380
23381 test_248a() {
23382         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23383         [ -z "$fast_read_sav" ] && skip "no fast read support"
23384
23385         # create a large file for fast read verification
23386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23387
23388         # make sure the file is created correctly
23389         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23390                 { rm -f $DIR/$tfile; skip "file creation error"; }
23391
23392         echo "Test 1: verify that fast read is 4 times faster on cache read"
23393
23394         # small read with fast read enabled
23395         $LCTL set_param -n llite.*.fast_read=1
23396         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23397                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23398                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23399         # small read with fast read disabled
23400         $LCTL set_param -n llite.*.fast_read=0
23401         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23402                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23403                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23404
23405         # verify that fast read is 4 times faster for cache read
23406         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23407                 error_not_in_vm "fast read was not 4 times faster: " \
23408                            "$t_fast vs $t_slow"
23409
23410         echo "Test 2: verify the performance between big and small read"
23411         $LCTL set_param -n llite.*.fast_read=1
23412
23413         # 1k non-cache read
23414         cancel_lru_locks osc
23415         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23416                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23417                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23418
23419         # 1M non-cache read
23420         cancel_lru_locks osc
23421         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23422                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23423                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23424
23425         # verify that big IO is not 4 times faster than small IO
23426         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23427                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23428
23429         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23430         rm -f $DIR/$tfile
23431 }
23432 run_test 248a "fast read verification"
23433
23434 test_248b() {
23435         # Default short_io_bytes=16384, try both smaller and larger sizes.
23436         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23437         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23438         echo "bs=53248 count=113 normal buffered write"
23439         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23440                 error "dd of initial data file failed"
23441         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23442
23443         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23444         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23445                 error "dd with sync normal writes failed"
23446         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23447
23448         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23449         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23450                 error "dd with sync small writes failed"
23451         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23452
23453         cancel_lru_locks osc
23454
23455         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23456         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23457         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23458         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23459                 iflag=direct || error "dd with O_DIRECT small read failed"
23460         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23461         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23462                 error "compare $TMP/$tfile.1 failed"
23463
23464         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23465         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23466
23467         # just to see what the maximum tunable value is, and test parsing
23468         echo "test invalid parameter 2MB"
23469         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23470                 error "too-large short_io_bytes allowed"
23471         echo "test maximum parameter 512KB"
23472         # if we can set a larger short_io_bytes, run test regardless of version
23473         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23474                 # older clients may not allow setting it this large, that's OK
23475                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23476                         skip "Need at least client version 2.13.50"
23477                 error "medium short_io_bytes failed"
23478         fi
23479         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23480         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23481
23482         echo "test large parameter 64KB"
23483         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23484         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23485
23486         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23487         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23488                 error "dd with sync large writes failed"
23489         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23490
23491         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23492         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23493         num=$((113 * 4096 / PAGE_SIZE))
23494         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23495         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23496                 error "dd with O_DIRECT large writes failed"
23497         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23498                 error "compare $DIR/$tfile.3 failed"
23499
23500         cancel_lru_locks osc
23501
23502         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23503         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23504                 error "dd with O_DIRECT large read failed"
23505         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23506                 error "compare $TMP/$tfile.2 failed"
23507
23508         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23509         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23510                 error "dd with O_DIRECT large read failed"
23511         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23512                 error "compare $TMP/$tfile.3 failed"
23513 }
23514 run_test 248b "test short_io read and write for both small and large sizes"
23515
23516 test_249() { # LU-7890
23517         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23518                 skip "Need at least version 2.8.54"
23519
23520         rm -f $DIR/$tfile
23521         $LFS setstripe -c 1 $DIR/$tfile
23522         # Offset 2T == 4k * 512M
23523         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23524                 error "dd to 2T offset failed"
23525 }
23526 run_test 249 "Write above 2T file size"
23527
23528 test_250() {
23529         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23530          && skip "no 16TB file size limit on ZFS"
23531
23532         $LFS setstripe -c 1 $DIR/$tfile
23533         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23534         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23535         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23536         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23537                 conv=notrunc,fsync && error "append succeeded"
23538         return 0
23539 }
23540 run_test 250 "Write above 16T limit"
23541
23542 test_251() {
23543         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23544
23545         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23546         #Skip once - writing the first stripe will succeed
23547         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23548         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23549                 error "short write happened"
23550
23551         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23552         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23553                 error "short read happened"
23554
23555         rm -f $DIR/$tfile
23556 }
23557 run_test 251 "Handling short read and write correctly"
23558
23559 test_252() {
23560         remote_mds_nodsh && skip "remote MDS with nodsh"
23561         remote_ost_nodsh && skip "remote OST with nodsh"
23562         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23563                 skip_env "ldiskfs only test"
23564         fi
23565
23566         local tgt
23567         local dev
23568         local out
23569         local uuid
23570         local num
23571         local gen
23572
23573         # check lr_reader on OST0000
23574         tgt=ost1
23575         dev=$(facet_device $tgt)
23576         out=$(do_facet $tgt $LR_READER $dev)
23577         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23578         echo "$out"
23579         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23580         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23581                 error "Invalid uuid returned by $LR_READER on target $tgt"
23582         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23583
23584         # check lr_reader -c on MDT0000
23585         tgt=mds1
23586         dev=$(facet_device $tgt)
23587         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23588                 skip "$LR_READER does not support additional options"
23589         fi
23590         out=$(do_facet $tgt $LR_READER -c $dev)
23591         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23592         echo "$out"
23593         num=$(echo "$out" | grep -c "mdtlov")
23594         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23595                 error "Invalid number of mdtlov clients returned by $LR_READER"
23596         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23597
23598         # check lr_reader -cr on MDT0000
23599         out=$(do_facet $tgt $LR_READER -cr $dev)
23600         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23601         echo "$out"
23602         echo "$out" | grep -q "^reply_data:$" ||
23603                 error "$LR_READER should have returned 'reply_data' section"
23604         num=$(echo "$out" | grep -c "client_generation")
23605         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23606 }
23607 run_test 252 "check lr_reader tool"
23608
23609 test_253() {
23610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23611         remote_mds_nodsh && skip "remote MDS with nodsh"
23612         remote_mgs_nodsh && skip "remote MGS with nodsh"
23613
23614         local ostidx=0
23615         local rc=0
23616         local ost_name=$(ostname_from_index $ostidx)
23617
23618         # on the mdt's osc
23619         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23620         do_facet $SINGLEMDS $LCTL get_param -n \
23621                 osp.$mdtosc_proc1.reserved_mb_high ||
23622                 skip  "remote MDS does not support reserved_mb_high"
23623
23624         rm -rf $DIR/$tdir
23625         wait_mds_ost_sync
23626         wait_delete_completed
23627         mkdir $DIR/$tdir
23628         stack_trap "rm -rf $DIR/$tdir"
23629
23630         pool_add $TESTNAME || error "Pool creation failed"
23631         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23632
23633         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23634                 error "Setstripe failed"
23635
23636         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23637
23638         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
23639                     grep "watermarks")
23640         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
23641
23642         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23643                         osp.$mdtosc_proc1.prealloc_status)
23644         echo "prealloc_status $oa_status"
23645
23646         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23647                 error "File creation should fail"
23648
23649         #object allocation was stopped, but we still able to append files
23650         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23651                 oflag=append || error "Append failed"
23652
23653         rm -f $DIR/$tdir/$tfile.0
23654
23655         # For this test, we want to delete the files we created to go out of
23656         # space but leave the watermark, so we remain nearly out of space
23657         ost_watermarks_enospc_delete_files $tfile $ostidx
23658
23659         wait_delete_completed
23660
23661         sleep_maxage
23662
23663         for i in $(seq 10 12); do
23664                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23665                         2>/dev/null || error "File creation failed after rm"
23666         done
23667
23668         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23669                         osp.$mdtosc_proc1.prealloc_status)
23670         echo "prealloc_status $oa_status"
23671
23672         if (( oa_status != 0 )); then
23673                 error "Object allocation still disable after rm"
23674         fi
23675 }
23676 run_test 253 "Check object allocation limit"
23677
23678 test_254() {
23679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23680         remote_mds_nodsh && skip "remote MDS with nodsh"
23681
23682         local mdt=$(facet_svc $SINGLEMDS)
23683
23684         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23685                 skip "MDS does not support changelog_size"
23686
23687         local cl_user
23688
23689         changelog_register || error "changelog_register failed"
23690
23691         changelog_clear 0 || error "changelog_clear failed"
23692
23693         local size1=$(do_facet $SINGLEMDS \
23694                       $LCTL get_param -n mdd.$mdt.changelog_size)
23695         echo "Changelog size $size1"
23696
23697         rm -rf $DIR/$tdir
23698         $LFS mkdir -i 0 $DIR/$tdir
23699         # change something
23700         mkdir -p $DIR/$tdir/pics/2008/zachy
23701         touch $DIR/$tdir/pics/2008/zachy/timestamp
23702         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23703         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23704         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23705         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23706         rm $DIR/$tdir/pics/desktop.jpg
23707
23708         local size2=$(do_facet $SINGLEMDS \
23709                       $LCTL get_param -n mdd.$mdt.changelog_size)
23710         echo "Changelog size after work $size2"
23711
23712         (( $size2 > $size1 )) ||
23713                 error "new Changelog size=$size2 less than old size=$size1"
23714 }
23715 run_test 254 "Check changelog size"
23716
23717 ladvise_no_type()
23718 {
23719         local type=$1
23720         local file=$2
23721
23722         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23723                 awk -F: '{print $2}' | grep $type > /dev/null
23724         if [ $? -ne 0 ]; then
23725                 return 0
23726         fi
23727         return 1
23728 }
23729
23730 ladvise_no_ioctl()
23731 {
23732         local file=$1
23733
23734         lfs ladvise -a willread $file > /dev/null 2>&1
23735         if [ $? -eq 0 ]; then
23736                 return 1
23737         fi
23738
23739         lfs ladvise -a willread $file 2>&1 |
23740                 grep "Inappropriate ioctl for device" > /dev/null
23741         if [ $? -eq 0 ]; then
23742                 return 0
23743         fi
23744         return 1
23745 }
23746
23747 percent() {
23748         bc <<<"scale=2; ($1 - $2) * 100 / $2"
23749 }
23750
23751 # run a random read IO workload
23752 # usage: random_read_iops <filename> <filesize> <iosize>
23753 random_read_iops() {
23754         local file=$1
23755         local fsize=$2
23756         local iosize=${3:-4096}
23757
23758         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
23759                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
23760 }
23761
23762 drop_file_oss_cache() {
23763         local file="$1"
23764         local nodes="$2"
23765
23766         $LFS ladvise -a dontneed $file 2>/dev/null ||
23767                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
23768 }
23769
23770 ladvise_willread_performance()
23771 {
23772         local repeat=10
23773         local average_origin=0
23774         local average_cache=0
23775         local average_ladvise=0
23776
23777         for ((i = 1; i <= $repeat; i++)); do
23778                 echo "Iter $i/$repeat: reading without willread hint"
23779                 cancel_lru_locks osc
23780                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23781                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
23782                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
23783                 average_origin=$(bc <<<"$average_origin + $speed_origin")
23784
23785                 cancel_lru_locks osc
23786                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
23787                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
23788                 average_cache=$(bc <<<"$average_cache + $speed_cache")
23789
23790                 cancel_lru_locks osc
23791                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
23792                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
23793                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
23794                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
23795                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
23796         done
23797         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
23798         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
23799         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
23800
23801         speedup_cache=$(percent $average_cache $average_origin)
23802         speedup_ladvise=$(percent $average_ladvise $average_origin)
23803
23804         echo "Average uncached read: $average_origin"
23805         echo "Average speedup with OSS cached read: " \
23806                 "$average_cache = +$speedup_cache%"
23807         echo "Average speedup with ladvise willread: " \
23808                 "$average_ladvise = +$speedup_ladvise%"
23809
23810         local lowest_speedup=20
23811         if (( ${average_cache%.*} < $lowest_speedup )); then
23812                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
23813                      " got $average_cache%. Skipping ladvise willread check."
23814                 return 0
23815         fi
23816
23817         # the test won't work on ZFS until it supports 'ladvise dontneed', but
23818         # it is still good to run until then to exercise 'ladvise willread'
23819         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23820                 [ "$ost1_FSTYPE" = "zfs" ] &&
23821                 echo "osd-zfs does not support dontneed or drop_caches" &&
23822                 return 0
23823
23824         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
23825         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
23826                 error_not_in_vm "Speedup with willread is less than " \
23827                         "$lowest_speedup%, got $average_ladvise%"
23828 }
23829
23830 test_255a() {
23831         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23832                 skip "lustre < 2.8.54 does not support ladvise "
23833         remote_ost_nodsh && skip "remote OST with nodsh"
23834
23835         stack_trap "rm -f $DIR/$tfile"
23836         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
23837
23838         ladvise_no_type willread $DIR/$tfile &&
23839                 skip "willread ladvise is not supported"
23840
23841         ladvise_no_ioctl $DIR/$tfile &&
23842                 skip "ladvise ioctl is not supported"
23843
23844         local size_mb=100
23845         local size=$((size_mb * 1048576))
23846         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23847                 error "dd to $DIR/$tfile failed"
23848
23849         lfs ladvise -a willread $DIR/$tfile ||
23850                 error "Ladvise failed with no range argument"
23851
23852         lfs ladvise -a willread -s 0 $DIR/$tfile ||
23853                 error "Ladvise failed with no -l or -e argument"
23854
23855         lfs ladvise -a willread -e 1 $DIR/$tfile ||
23856                 error "Ladvise failed with only -e argument"
23857
23858         lfs ladvise -a willread -l 1 $DIR/$tfile ||
23859                 error "Ladvise failed with only -l argument"
23860
23861         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
23862                 error "End offset should not be smaller than start offset"
23863
23864         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
23865                 error "End offset should not be equal to start offset"
23866
23867         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
23868                 error "Ladvise failed with overflowing -s argument"
23869
23870         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
23871                 error "Ladvise failed with overflowing -e argument"
23872
23873         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
23874                 error "Ladvise failed with overflowing -l argument"
23875
23876         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
23877                 error "Ladvise succeeded with conflicting -l and -e arguments"
23878
23879         echo "Synchronous ladvise should wait"
23880         local delay=8
23881 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
23882         do_nodes $(comma_list $(osts_nodes)) \
23883                 $LCTL set_param fail_val=$delay fail_loc=0x237
23884         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
23885                 $LCTL set_param fail_loc=0"
23886
23887         local start_ts=$SECONDS
23888         lfs ladvise -a willread $DIR/$tfile ||
23889                 error "Ladvise failed with no range argument"
23890         local end_ts=$SECONDS
23891         local inteval_ts=$((end_ts - start_ts))
23892
23893         if [ $inteval_ts -lt $(($delay - 1)) ]; then
23894                 error "Synchronous advice didn't wait reply"
23895         fi
23896
23897         echo "Asynchronous ladvise shouldn't wait"
23898         local start_ts=$SECONDS
23899         lfs ladvise -a willread -b $DIR/$tfile ||
23900                 error "Ladvise failed with no range argument"
23901         local end_ts=$SECONDS
23902         local inteval_ts=$((end_ts - start_ts))
23903
23904         if [ $inteval_ts -gt $(($delay / 2)) ]; then
23905                 error "Asynchronous advice blocked"
23906         fi
23907
23908         ladvise_willread_performance
23909 }
23910 run_test 255a "check 'lfs ladvise -a willread'"
23911
23912 facet_meminfo() {
23913         local facet=$1
23914         local info=$2
23915
23916         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
23917 }
23918
23919 test_255b() {
23920         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
23921                 skip "lustre < 2.8.54 does not support ladvise "
23922         remote_ost_nodsh && skip "remote OST with nodsh"
23923
23924         stack_trap "rm -f $DIR/$tfile"
23925         lfs setstripe -c 1 -i 0 $DIR/$tfile
23926
23927         ladvise_no_type dontneed $DIR/$tfile &&
23928                 skip "dontneed ladvise is not supported"
23929
23930         ladvise_no_ioctl $DIR/$tfile &&
23931                 skip "ladvise ioctl is not supported"
23932
23933         ! $LFS ladvise -a dontneed $DIR/$tfile &&
23934                 [ "$ost1_FSTYPE" = "zfs" ] &&
23935                 skip "zfs-osd does not support 'ladvise dontneed'"
23936
23937         local size_mb=100
23938         local size=$((size_mb * 1048576))
23939         # In order to prevent disturbance of other processes, only check 3/4
23940         # of the memory usage
23941         local kibibytes=$((size_mb * 1024 * 3 / 4))
23942
23943         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
23944                 error "dd to $DIR/$tfile failed"
23945
23946         #force write to complete before dropping OST cache & checking memory
23947         sync
23948
23949         local total=$(facet_meminfo ost1 MemTotal)
23950         echo "Total memory: $total KiB"
23951
23952         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
23953         local before_read=$(facet_meminfo ost1 Cached)
23954         echo "Cache used before read: $before_read KiB"
23955
23956         lfs ladvise -a willread $DIR/$tfile ||
23957                 error "Ladvise willread failed"
23958         local after_read=$(facet_meminfo ost1 Cached)
23959         echo "Cache used after read: $after_read KiB"
23960
23961         lfs ladvise -a dontneed $DIR/$tfile ||
23962                 error "Ladvise dontneed again failed"
23963         local no_read=$(facet_meminfo ost1 Cached)
23964         echo "Cache used after dontneed ladvise: $no_read KiB"
23965
23966         if [ $total -lt $((before_read + kibibytes)) ]; then
23967                 echo "Memory is too small, abort checking"
23968                 return 0
23969         fi
23970
23971         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23972                 error "Ladvise willread should use more memory" \
23973                         "than $kibibytes KiB"
23974         fi
23975
23976         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23977                 error "Ladvise dontneed should release more memory" \
23978                         "than $kibibytes KiB"
23979         fi
23980 }
23981 run_test 255b "check 'lfs ladvise -a dontneed'"
23982
23983 test_255c() {
23984         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23985                 skip "lustre < 2.10.50 does not support lockahead"
23986
23987         local ost1_imp=$(get_osc_import_name client ost1)
23988         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23989                          cut -d'.' -f2)
23990         local count
23991         local new_count
23992         local difference
23993         local i
23994         local rc
23995
23996         test_mkdir -p $DIR/$tdir
23997         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23998
23999         #test 10 returns only success/failure
24000         i=10
24001         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24002         rc=$?
24003         if [ $rc -eq 255 ]; then
24004                 error "Ladvise test${i} failed, ${rc}"
24005         fi
24006
24007         #test 11 counts lock enqueue requests, all others count new locks
24008         i=11
24009         count=$(do_facet ost1 \
24010                 $LCTL get_param -n ost.OSS.ost.stats)
24011         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24012
24013         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24014         rc=$?
24015         if [ $rc -eq 255 ]; then
24016                 error "Ladvise test${i} failed, ${rc}"
24017         fi
24018
24019         new_count=$(do_facet ost1 \
24020                 $LCTL get_param -n ost.OSS.ost.stats)
24021         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24022                    awk '{ print $2 }')
24023
24024         difference="$((new_count - count))"
24025         if [ $difference -ne $rc ]; then
24026                 error "Ladvise test${i}, bad enqueue count, returned " \
24027                       "${rc}, actual ${difference}"
24028         fi
24029
24030         for i in $(seq 12 21); do
24031                 # If we do not do this, we run the risk of having too many
24032                 # locks and starting lock cancellation while we are checking
24033                 # lock counts.
24034                 cancel_lru_locks osc
24035
24036                 count=$($LCTL get_param -n \
24037                        ldlm.namespaces.$imp_name.lock_unused_count)
24038
24039                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24040                 rc=$?
24041                 if [ $rc -eq 255 ]; then
24042                         error "Ladvise test ${i} failed, ${rc}"
24043                 fi
24044
24045                 new_count=$($LCTL get_param -n \
24046                        ldlm.namespaces.$imp_name.lock_unused_count)
24047                 difference="$((new_count - count))"
24048
24049                 # Test 15 output is divided by 100 to map down to valid return
24050                 if [ $i -eq 15 ]; then
24051                         rc="$((rc * 100))"
24052                 fi
24053
24054                 if [ $difference -ne $rc ]; then
24055                         error "Ladvise test ${i}, bad lock count, returned " \
24056                               "${rc}, actual ${difference}"
24057                 fi
24058         done
24059
24060         #test 22 returns only success/failure
24061         i=22
24062         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24063         rc=$?
24064         if [ $rc -eq 255 ]; then
24065                 error "Ladvise test${i} failed, ${rc}"
24066         fi
24067 }
24068 run_test 255c "suite of ladvise lockahead tests"
24069
24070 test_256() {
24071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24072         remote_mds_nodsh && skip "remote MDS with nodsh"
24073         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24074         changelog_users $SINGLEMDS | grep "^cl" &&
24075                 skip "active changelog user"
24076
24077         local cl_user
24078         local cat_sl
24079         local mdt_dev
24080
24081         mdt_dev=$(facet_device $SINGLEMDS)
24082         echo $mdt_dev
24083
24084         changelog_register || error "changelog_register failed"
24085
24086         rm -rf $DIR/$tdir
24087         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24088
24089         changelog_clear 0 || error "changelog_clear failed"
24090
24091         # change something
24092         touch $DIR/$tdir/{1..10}
24093
24094         # stop the MDT
24095         stop $SINGLEMDS || error "Fail to stop MDT"
24096
24097         # remount the MDT
24098         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24099                 error "Fail to start MDT"
24100
24101         #after mount new plainllog is used
24102         touch $DIR/$tdir/{11..19}
24103         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24104         stack_trap "rm -f $tmpfile"
24105         cat_sl=$(do_facet $SINGLEMDS "sync; \
24106                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24107                  llog_reader $tmpfile | grep -c type=1064553b")
24108         do_facet $SINGLEMDS llog_reader $tmpfile
24109
24110         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24111
24112         changelog_clear 0 || error "changelog_clear failed"
24113
24114         cat_sl=$(do_facet $SINGLEMDS "sync; \
24115                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24116                  llog_reader $tmpfile | grep -c type=1064553b")
24117
24118         if (( cat_sl == 2 )); then
24119                 error "Empty plain llog was not deleted from changelog catalog"
24120         elif (( cat_sl != 1 )); then
24121                 error "Active plain llog shouldn't be deleted from catalog"
24122         fi
24123 }
24124 run_test 256 "Check llog delete for empty and not full state"
24125
24126 test_257() {
24127         remote_mds_nodsh && skip "remote MDS with nodsh"
24128         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24129                 skip "Need MDS version at least 2.8.55"
24130
24131         test_mkdir $DIR/$tdir
24132
24133         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24134                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24135         stat $DIR/$tdir
24136
24137 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24138         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24139         local facet=mds$((mdtidx + 1))
24140         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24141         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24142
24143         stop $facet || error "stop MDS failed"
24144         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24145                 error "start MDS fail"
24146         wait_recovery_complete $facet
24147 }
24148 run_test 257 "xattr locks are not lost"
24149
24150 # Verify we take the i_mutex when security requires it
24151 test_258a() {
24152 #define OBD_FAIL_IMUTEX_SEC 0x141c
24153         $LCTL set_param fail_loc=0x141c
24154         touch $DIR/$tfile
24155         chmod u+s $DIR/$tfile
24156         chmod a+rwx $DIR/$tfile
24157         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24158         RC=$?
24159         if [ $RC -ne 0 ]; then
24160                 error "error, failed to take i_mutex, rc=$?"
24161         fi
24162         rm -f $DIR/$tfile
24163 }
24164 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24165
24166 # Verify we do NOT take the i_mutex in the normal case
24167 test_258b() {
24168 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24169         $LCTL set_param fail_loc=0x141d
24170         touch $DIR/$tfile
24171         chmod a+rwx $DIR
24172         chmod a+rw $DIR/$tfile
24173         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24174         RC=$?
24175         if [ $RC -ne 0 ]; then
24176                 error "error, took i_mutex unnecessarily, rc=$?"
24177         fi
24178         rm -f $DIR/$tfile
24179
24180 }
24181 run_test 258b "verify i_mutex security behavior"
24182
24183 test_259() {
24184         local file=$DIR/$tfile
24185         local before
24186         local after
24187
24188         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24189
24190         stack_trap "rm -f $file" EXIT
24191
24192         wait_delete_completed
24193         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24194         echo "before: $before"
24195
24196         $LFS setstripe -i 0 -c 1 $file
24197         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24198         sync_all_data
24199         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24200         echo "after write: $after"
24201
24202 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24203         do_facet ost1 $LCTL set_param fail_loc=0x2301
24204         $TRUNCATE $file 0
24205         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24206         echo "after truncate: $after"
24207
24208         stop ost1
24209         do_facet ost1 $LCTL set_param fail_loc=0
24210         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24211         sleep 2
24212         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24213         echo "after restart: $after"
24214         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24215                 error "missing truncate?"
24216
24217         return 0
24218 }
24219 run_test 259 "crash at delayed truncate"
24220
24221 test_260() {
24222 #define OBD_FAIL_MDC_CLOSE               0x806
24223         $LCTL set_param fail_loc=0x80000806
24224         touch $DIR/$tfile
24225
24226 }
24227 run_test 260 "Check mdc_close fail"
24228
24229 ### Data-on-MDT sanity tests ###
24230 test_270a() {
24231         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24232                 skip "Need MDS version at least 2.10.55 for DoM"
24233
24234         # create DoM file
24235         local dom=$DIR/$tdir/dom_file
24236         local tmp=$DIR/$tdir/tmp_file
24237
24238         mkdir_on_mdt0 $DIR/$tdir
24239
24240         # basic checks for DoM component creation
24241         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24242                 error "Can set MDT layout to non-first entry"
24243
24244         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24245                 error "Can define multiple entries as MDT layout"
24246
24247         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24248
24249         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24250         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24251         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24252
24253         local mdtidx=$($LFS getstripe -m $dom)
24254         local mdtname=MDT$(printf %04x $mdtidx)
24255         local facet=mds$((mdtidx + 1))
24256         local space_check=1
24257
24258         # Skip free space checks with ZFS
24259         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24260
24261         # write
24262         sync
24263         local size_tmp=$((65536 * 3))
24264         local mdtfree1=$(do_facet $facet \
24265                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24266
24267         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24268         # check also direct IO along write
24269         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24270         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24271         sync
24272         cmp $tmp $dom || error "file data is different"
24273         [ $(stat -c%s $dom) == $size_tmp ] ||
24274                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24275         if [ $space_check == 1 ]; then
24276                 local mdtfree2=$(do_facet $facet \
24277                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24278
24279                 # increase in usage from by $size_tmp
24280                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24281                         error "MDT free space wrong after write: " \
24282                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24283         fi
24284
24285         # truncate
24286         local size_dom=10000
24287
24288         $TRUNCATE $dom $size_dom
24289         [ $(stat -c%s $dom) == $size_dom ] ||
24290                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24291         if [ $space_check == 1 ]; then
24292                 mdtfree1=$(do_facet $facet \
24293                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24294                 # decrease in usage from $size_tmp to new $size_dom
24295                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24296                   $(((size_tmp - size_dom) / 1024)) ] ||
24297                         error "MDT free space is wrong after truncate: " \
24298                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24299         fi
24300
24301         # append
24302         cat $tmp >> $dom
24303         sync
24304         size_dom=$((size_dom + size_tmp))
24305         [ $(stat -c%s $dom) == $size_dom ] ||
24306                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24307         if [ $space_check == 1 ]; then
24308                 mdtfree2=$(do_facet $facet \
24309                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24310                 # increase in usage by $size_tmp from previous
24311                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24312                         error "MDT free space is wrong after append: " \
24313                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24314         fi
24315
24316         # delete
24317         rm $dom
24318         if [ $space_check == 1 ]; then
24319                 mdtfree1=$(do_facet $facet \
24320                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24321                 # decrease in usage by $size_dom from previous
24322                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24323                         error "MDT free space is wrong after removal: " \
24324                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24325         fi
24326
24327         # combined striping
24328         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24329                 error "Can't create DoM + OST striping"
24330
24331         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24332         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24333         # check also direct IO along write
24334         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24335         sync
24336         cmp $tmp $dom || error "file data is different"
24337         [ $(stat -c%s $dom) == $size_tmp ] ||
24338                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24339         rm $dom $tmp
24340
24341         return 0
24342 }
24343 run_test 270a "DoM: basic functionality tests"
24344
24345 test_270b() {
24346         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24347                 skip "Need MDS version at least 2.10.55"
24348
24349         local dom=$DIR/$tdir/dom_file
24350         local max_size=1048576
24351
24352         mkdir -p $DIR/$tdir
24353         $LFS setstripe -E $max_size -L mdt $dom
24354
24355         # truncate over the limit
24356         $TRUNCATE $dom $(($max_size + 1)) &&
24357                 error "successful truncate over the maximum size"
24358         # write over the limit
24359         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24360                 error "successful write over the maximum size"
24361         # append over the limit
24362         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24363         echo "12345" >> $dom && error "successful append over the maximum size"
24364         rm $dom
24365
24366         return 0
24367 }
24368 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24369
24370 test_270c() {
24371         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24372                 skip "Need MDS version at least 2.10.55"
24373
24374         mkdir -p $DIR/$tdir
24375         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24376
24377         # check files inherit DoM EA
24378         touch $DIR/$tdir/first
24379         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24380                 error "bad pattern"
24381         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24382                 error "bad stripe count"
24383         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24384                 error "bad stripe size"
24385
24386         # check directory inherits DoM EA and uses it as default
24387         mkdir $DIR/$tdir/subdir
24388         touch $DIR/$tdir/subdir/second
24389         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24390                 error "bad pattern in sub-directory"
24391         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24392                 error "bad stripe count in sub-directory"
24393         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24394                 error "bad stripe size in sub-directory"
24395         return 0
24396 }
24397 run_test 270c "DoM: DoM EA inheritance tests"
24398
24399 test_270d() {
24400         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24401                 skip "Need MDS version at least 2.10.55"
24402
24403         mkdir -p $DIR/$tdir
24404         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24405
24406         # inherit default DoM striping
24407         mkdir $DIR/$tdir/subdir
24408         touch $DIR/$tdir/subdir/f1
24409
24410         # change default directory striping
24411         $LFS setstripe -c 1 $DIR/$tdir/subdir
24412         touch $DIR/$tdir/subdir/f2
24413         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24414                 error "wrong default striping in file 2"
24415         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24416                 error "bad pattern in file 2"
24417         return 0
24418 }
24419 run_test 270d "DoM: change striping from DoM to RAID0"
24420
24421 test_270e() {
24422         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24423                 skip "Need MDS version at least 2.10.55"
24424
24425         mkdir -p $DIR/$tdir/dom
24426         mkdir -p $DIR/$tdir/norm
24427         DOMFILES=20
24428         NORMFILES=10
24429         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24430         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24431
24432         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24433         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24434
24435         # find DoM files by layout
24436         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24437         [ $NUM -eq  $DOMFILES ] ||
24438                 error "lfs find -L: found $NUM, expected $DOMFILES"
24439         echo "Test 1: lfs find 20 DOM files by layout: OK"
24440
24441         # there should be 1 dir with default DOM striping
24442         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24443         [ $NUM -eq  1 ] ||
24444                 error "lfs find -L: found $NUM, expected 1 dir"
24445         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24446
24447         # find DoM files by stripe size
24448         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24449         [ $NUM -eq  $DOMFILES ] ||
24450                 error "lfs find -S: found $NUM, expected $DOMFILES"
24451         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24452
24453         # find files by stripe offset except DoM files
24454         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24455         [ $NUM -eq  $NORMFILES ] ||
24456                 error "lfs find -i: found $NUM, expected $NORMFILES"
24457         echo "Test 5: lfs find no DOM files by stripe index: OK"
24458         return 0
24459 }
24460 run_test 270e "DoM: lfs find with DoM files test"
24461
24462 test_270f() {
24463         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24464                 skip "Need MDS version at least 2.10.55"
24465
24466         local mdtname=${FSNAME}-MDT0000-mdtlov
24467         local dom=$DIR/$tdir/dom_file
24468         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24469                                                 lod.$mdtname.dom_stripesize)
24470         local dom_limit=131072
24471
24472         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24473         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24474                                                 lod.$mdtname.dom_stripesize)
24475         [ ${dom_limit} -eq ${dom_current} ] ||
24476                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24477
24478         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24479         $LFS setstripe -d $DIR/$tdir
24480         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24481                 error "Can't set directory default striping"
24482
24483         # exceed maximum stripe size
24484         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24485                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24486         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24487                 error "Able to create DoM component size more than LOD limit"
24488
24489         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24490         dom_current=$(do_facet mds1 $LCTL get_param -n \
24491                                                 lod.$mdtname.dom_stripesize)
24492         [ 0 -eq ${dom_current} ] ||
24493                 error "Can't set zero DoM stripe limit"
24494         rm $dom
24495
24496         # attempt to create DoM file on server with disabled DoM should
24497         # remove DoM entry from layout and be succeed
24498         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24499                 error "Can't create DoM file (DoM is disabled)"
24500         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24501                 error "File has DoM component while DoM is disabled"
24502         rm $dom
24503
24504         # attempt to create DoM file with only DoM stripe should return error
24505         $LFS setstripe -E $dom_limit -L mdt $dom &&
24506                 error "Able to create DoM-only file while DoM is disabled"
24507
24508         # too low values to be aligned with smallest stripe size 64K
24509         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24510         dom_current=$(do_facet mds1 $LCTL get_param -n \
24511                                                 lod.$mdtname.dom_stripesize)
24512         [ 30000 -eq ${dom_current} ] &&
24513                 error "Can set too small DoM stripe limit"
24514
24515         # 64K is a minimal stripe size in Lustre, expect limit of that size
24516         [ 65536 -eq ${dom_current} ] ||
24517                 error "Limit is not set to 64K but ${dom_current}"
24518
24519         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24520         dom_current=$(do_facet mds1 $LCTL get_param -n \
24521                                                 lod.$mdtname.dom_stripesize)
24522         echo $dom_current
24523         [ 2147483648 -eq ${dom_current} ] &&
24524                 error "Can set too large DoM stripe limit"
24525
24526         do_facet mds1 $LCTL set_param -n \
24527                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24528         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24529                 error "Can't create DoM component size after limit change"
24530         do_facet mds1 $LCTL set_param -n \
24531                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24532         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24533                 error "Can't create DoM file after limit decrease"
24534         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24535                 error "Can create big DoM component after limit decrease"
24536         touch ${dom}_def ||
24537                 error "Can't create file with old default layout"
24538
24539         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24540         return 0
24541 }
24542 run_test 270f "DoM: maximum DoM stripe size checks"
24543
24544 test_270g() {
24545         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24546                 skip "Need MDS version at least 2.13.52"
24547         local dom=$DIR/$tdir/$tfile
24548
24549         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24550         local lodname=${FSNAME}-MDT0000-mdtlov
24551
24552         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24553         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24554         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24555         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24556
24557         local dom_limit=1024
24558         local dom_threshold="50%"
24559
24560         $LFS setstripe -d $DIR/$tdir
24561         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24562                 error "Can't set directory default striping"
24563
24564         do_facet mds1 $LCTL set_param -n \
24565                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24566         # set 0 threshold and create DOM file to change tunable stripesize
24567         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24568         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24569                 error "Failed to create $dom file"
24570         # now tunable dom_cur_stripesize should reach maximum
24571         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24572                                         lod.${lodname}.dom_stripesize_cur_kb)
24573         [[ $dom_current == $dom_limit ]] ||
24574                 error "Current DOM stripesize is not maximum"
24575         rm $dom
24576
24577         # set threshold for further tests
24578         do_facet mds1 $LCTL set_param -n \
24579                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24580         echo "DOM threshold is $dom_threshold free space"
24581         local dom_def
24582         local dom_set
24583         # Spoof bfree to exceed threshold
24584         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24585         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24586         for spfree in 40 20 0 15 30 55; do
24587                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24588                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24589                         error "Failed to create $dom file"
24590                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24591                                         lod.${lodname}.dom_stripesize_cur_kb)
24592                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24593                 [[ $dom_def != $dom_current ]] ||
24594                         error "Default stripe size was not changed"
24595                 if (( spfree > 0 )) ; then
24596                         dom_set=$($LFS getstripe -S $dom)
24597                         (( dom_set == dom_def * 1024 )) ||
24598                                 error "DOM component size is still old"
24599                 else
24600                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24601                                 error "DoM component is set with no free space"
24602                 fi
24603                 rm $dom
24604                 dom_current=$dom_def
24605         done
24606 }
24607 run_test 270g "DoM: default DoM stripe size depends on free space"
24608
24609 test_270h() {
24610         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24611                 skip "Need MDS version at least 2.13.53"
24612
24613         local mdtname=${FSNAME}-MDT0000-mdtlov
24614         local dom=$DIR/$tdir/$tfile
24615         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24616
24617         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24618         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24619
24620         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24621         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24622                 error "can't create OST file"
24623         # mirrored file with DOM entry in the second mirror
24624         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24625                 error "can't create mirror with DoM component"
24626
24627         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24628
24629         # DOM component in the middle and has other enries in the same mirror,
24630         # should succeed but lost DoM component
24631         $LFS setstripe --copy=${dom}_1 $dom ||
24632                 error "Can't create file from OST|DOM mirror layout"
24633         # check new file has no DoM layout after all
24634         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24635                 error "File has DoM component while DoM is disabled"
24636 }
24637 run_test 270h "DoM: DoM stripe removal when disabled on server"
24638
24639 test_270i() {
24640         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24641                 skip "Need MDS version at least 2.14.54"
24642
24643         mkdir $DIR/$tdir
24644         # DoM with plain layout
24645         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24646                 error "default plain layout with DoM must fail"
24647         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24648                 error "setstripe plain file layout with DoM must fail"
24649         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24650                 error "default DoM layout with bad striping must fail"
24651         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24652                 error "setstripe to DoM layout with bad striping must fail"
24653         return 0
24654 }
24655 run_test 270i "DoM: setting invalid DoM striping should fail"
24656
24657 test_270j() {
24658         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24659                 skip "Need MDS version at least 2.15.55.203"
24660
24661         local dom=$DIR/$tdir/$tfile
24662         local odv
24663         local ndv
24664
24665         mkdir -p $DIR/$tdir
24666
24667         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24668
24669         odv=$($LFS data_version $dom)
24670         chmod 666 $dom
24671         mv $dom ${dom}_moved
24672         link ${dom}_moved $dom
24673         setfattr -n user.attrx -v "some_attr" $dom
24674         ndv=$($LFS data_version $dom)
24675         (( $ndv == $odv )) ||
24676                 error "data version was changed by metadata operations"
24677
24678         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24679                 error "failed to write data into $dom"
24680         cancel_lru_locks mdc
24681         ndv=$($LFS data_version $dom)
24682         (( $ndv != $odv )) ||
24683                 error "data version wasn't changed on write"
24684
24685         odv=$ndv
24686         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24687         ndv=$($LFS data_version $dom)
24688         (( $ndv != $odv )) ||
24689                 error "data version wasn't changed on truncate down"
24690
24691         odv=$ndv
24692         $TRUNCATE $dom 25000
24693         ndv=$($LFS data_version $dom)
24694         (( $ndv != $odv )) ||
24695                 error "data version wasn't changed on truncate up"
24696
24697         # check also fallocate for ldiskfs
24698         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24699                 odv=$ndv
24700                 fallocate -l 1048576 $dom
24701                 ndv=$($LFS data_version $dom)
24702                 (( $ndv != $odv )) ||
24703                         error "data version wasn't changed on fallocate"
24704
24705                 odv=$ndv
24706                 fallocate -p --offset 4096 -l 4096 $dom
24707                 ndv=$($LFS data_version $dom)
24708                 (( $ndv != $odv )) ||
24709                         error "data version wasn't changed on fallocate punch"
24710         fi
24711 }
24712 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24713
24714 test_271a() {
24715         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24716                 skip "Need MDS version at least 2.10.55"
24717
24718         local dom=$DIR/$tdir/dom
24719
24720         mkdir -p $DIR/$tdir
24721
24722         $LFS setstripe -E 1024K -L mdt $dom
24723
24724         lctl set_param -n mdc.*.stats=clear
24725         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24726         cat $dom > /dev/null
24727         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24728         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24729         ls $dom
24730         rm -f $dom
24731 }
24732 run_test 271a "DoM: data is cached for read after write"
24733
24734 test_271b() {
24735         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24736                 skip "Need MDS version at least 2.10.55"
24737
24738         local dom=$DIR/$tdir/dom
24739
24740         mkdir -p $DIR/$tdir
24741
24742         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24743
24744         lctl set_param -n mdc.*.stats=clear
24745         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24746         cancel_lru_locks mdc
24747         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
24748         # second stat to check size is cached on client
24749         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
24750         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24751         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
24752         rm -f $dom
24753 }
24754 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
24755
24756 test_271ba() {
24757         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24758                 skip "Need MDS version at least 2.10.55"
24759
24760         local dom=$DIR/$tdir/dom
24761
24762         mkdir -p $DIR/$tdir
24763
24764         $LFS setstripe -E 1024K -L mdt -E EOF $dom
24765
24766         lctl set_param -n mdc.*.stats=clear
24767         lctl set_param -n osc.*.stats=clear
24768         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
24769         cancel_lru_locks mdc
24770         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24771         # second stat to check size is cached on client
24772         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
24773         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
24774         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
24775         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
24776         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
24777         rm -f $dom
24778 }
24779 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
24780
24781
24782 get_mdc_stats() {
24783         local mdtidx=$1
24784         local param=$2
24785         local mdt=MDT$(printf %04x $mdtidx)
24786
24787         if [ -z $param ]; then
24788                 lctl get_param -n mdc.*$mdt*.stats
24789         else
24790                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
24791         fi
24792 }
24793
24794 test_271c() {
24795         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24796                 skip "Need MDS version at least 2.10.55"
24797
24798         local dom=$DIR/$tdir/dom
24799
24800         mkdir -p $DIR/$tdir
24801
24802         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24803
24804         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24805         local facet=mds$((mdtidx + 1))
24806
24807         cancel_lru_locks mdc
24808         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
24809         createmany -o $dom 1000
24810         lctl set_param -n mdc.*.stats=clear
24811         smalliomany -w $dom 1000 200
24812         get_mdc_stats $mdtidx
24813         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24814         # Each file has 1 open, 1 IO enqueues, total 2000
24815         # but now we have also +1 getxattr for security.capability, total 3000
24816         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
24817         unlinkmany $dom 1000
24818
24819         cancel_lru_locks mdc
24820         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
24821         createmany -o $dom 1000
24822         lctl set_param -n mdc.*.stats=clear
24823         smalliomany -w $dom 1000 200
24824         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
24825         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
24826         # for OPEN and IO lock.
24827         [ $((enq - enq_2)) -ge 1000 ] ||
24828                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
24829         unlinkmany $dom 1000
24830         return 0
24831 }
24832 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
24833
24834 cleanup_271def_tests() {
24835         trap 0
24836         rm -f $1
24837 }
24838
24839 test_271d() {
24840         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24841                 skip "Need MDS version at least 2.10.57"
24842
24843         local dom=$DIR/$tdir/dom
24844         local tmp=$TMP/$tfile
24845         trap "cleanup_271def_tests $tmp" EXIT
24846
24847         mkdir -p $DIR/$tdir
24848
24849         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24850
24851         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24852
24853         cancel_lru_locks mdc
24854         dd if=/dev/urandom of=$tmp bs=1000 count=1
24855         dd if=$tmp of=$dom bs=1000 count=1
24856         cancel_lru_locks mdc
24857
24858         cat /etc/hosts >> $tmp
24859         lctl set_param -n mdc.*.stats=clear
24860
24861         # append data to the same file it should update local page
24862         echo "Append to the same page"
24863         cat /etc/hosts >> $dom
24864         local num=$(get_mdc_stats $mdtidx ost_read)
24865         local ra=$(get_mdc_stats $mdtidx req_active)
24866         local rw=$(get_mdc_stats $mdtidx req_waittime)
24867
24868         [ -z $num ] || error "$num READ RPC occured"
24869         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24870         echo "... DONE"
24871
24872         # compare content
24873         cmp $tmp $dom || error "file miscompare"
24874
24875         cancel_lru_locks mdc
24876         lctl set_param -n mdc.*.stats=clear
24877
24878         echo "Open and read file"
24879         cat $dom > /dev/null
24880         local num=$(get_mdc_stats $mdtidx ost_read)
24881         local ra=$(get_mdc_stats $mdtidx req_active)
24882         local rw=$(get_mdc_stats $mdtidx req_waittime)
24883
24884         [ -z $num ] || error "$num READ RPC occured"
24885         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24886         echo "... DONE"
24887
24888         # compare content
24889         cmp $tmp $dom || error "file miscompare"
24890
24891         return 0
24892 }
24893 run_test 271d "DoM: read on open (1K file in reply buffer)"
24894
24895 test_271f() {
24896         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
24897                 skip "Need MDS version at least 2.10.57"
24898
24899         local dom=$DIR/$tdir/dom
24900         local tmp=$TMP/$tfile
24901         trap "cleanup_271def_tests $tmp" EXIT
24902
24903         mkdir -p $DIR/$tdir
24904
24905         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24906
24907         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
24908
24909         cancel_lru_locks mdc
24910         dd if=/dev/urandom of=$tmp bs=265000 count=1
24911         dd if=$tmp of=$dom bs=265000 count=1
24912         cancel_lru_locks mdc
24913         cat /etc/hosts >> $tmp
24914         lctl set_param -n mdc.*.stats=clear
24915
24916         echo "Append to the same page"
24917         cat /etc/hosts >> $dom
24918         local num=$(get_mdc_stats $mdtidx ost_read)
24919         local ra=$(get_mdc_stats $mdtidx req_active)
24920         local rw=$(get_mdc_stats $mdtidx req_waittime)
24921
24922         [ -z $num ] || error "$num READ RPC occured"
24923         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24924         echo "... DONE"
24925
24926         # compare content
24927         cmp $tmp $dom || error "file miscompare"
24928
24929         cancel_lru_locks mdc
24930         lctl set_param -n mdc.*.stats=clear
24931
24932         echo "Open and read file"
24933         cat $dom > /dev/null
24934         local num=$(get_mdc_stats $mdtidx ost_read)
24935         local ra=$(get_mdc_stats $mdtidx req_active)
24936         local rw=$(get_mdc_stats $mdtidx req_waittime)
24937
24938         [ -z $num ] && num=0
24939         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
24940         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
24941         echo "... DONE"
24942
24943         # compare content
24944         cmp $tmp $dom || error "file miscompare"
24945
24946         return 0
24947 }
24948 run_test 271f "DoM: read on open (200K file and read tail)"
24949
24950 test_271g() {
24951         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
24952                 skip "Skipping due to old client or server version"
24953
24954         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
24955         # to get layout
24956         $CHECKSTAT -t file $DIR1/$tfile
24957
24958         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
24959         MULTIOP_PID=$!
24960         sleep 1
24961         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
24962         $LCTL set_param fail_loc=0x80000314
24963         rm $DIR1/$tfile || error "Unlink fails"
24964         RC=$?
24965         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
24966         [ $RC -eq 0 ] || error "Failed write to stale object"
24967 }
24968 run_test 271g "Discard DoM data vs client flush race"
24969
24970 test_272a() {
24971         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24972                 skip "Need MDS version at least 2.11.50"
24973
24974         local dom=$DIR/$tdir/dom
24975         mkdir -p $DIR/$tdir
24976
24977         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
24978         dd if=/dev/urandom of=$dom bs=512K count=1 ||
24979                 error "failed to write data into $dom"
24980         local old_md5=$(md5sum $dom)
24981
24982         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
24983                 error "failed to migrate to the same DoM component"
24984
24985         local new_md5=$(md5sum $dom)
24986
24987         [ "$old_md5" == "$new_md5" ] ||
24988                 error "md5sum differ: $old_md5, $new_md5"
24989
24990         [ $($LFS getstripe -c $dom) -eq 2 ] ||
24991                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
24992 }
24993 run_test 272a "DoM migration: new layout with the same DOM component"
24994
24995 test_272b() {
24996         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24997                 skip "Need MDS version at least 2.11.50"
24998
24999         local dom=$DIR/$tdir/dom
25000         mkdir -p $DIR/$tdir
25001         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25002         stack_trap "rm -rf $DIR/$tdir"
25003
25004         local mdtidx=$($LFS getstripe -m $dom)
25005         local mdtname=MDT$(printf %04x $mdtidx)
25006         local facet=mds$((mdtidx + 1))
25007
25008         local mdtfree1=$(do_facet $facet \
25009                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25010         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25011                 error "failed to write data into $dom"
25012         local old_md5=$(md5sum $dom)
25013         cancel_lru_locks mdc
25014         local mdtfree1=$(do_facet $facet \
25015                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25016
25017         $LFS migrate -c2 $dom ||
25018                 error "failed to migrate to the new composite layout"
25019         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25020                 error "MDT stripe was not removed"
25021         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25022                 error "$dir1 shouldn't have DATAVER EA"
25023
25024         cancel_lru_locks mdc
25025         local new_md5=$(md5sum $dom)
25026         [ "$old_md5" == "$new_md5" ] ||
25027                 error "$old_md5 != $new_md5"
25028
25029         # Skip free space checks with ZFS
25030         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25031                 local mdtfree2=$(do_facet $facet \
25032                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25033                 [ $mdtfree2 -gt $mdtfree1 ] ||
25034                         error "MDT space is not freed after migration"
25035         fi
25036         return 0
25037 }
25038 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25039
25040 test_272c() {
25041         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25042                 skip "Need MDS version at least 2.11.50"
25043
25044         local dom=$DIR/$tdir/$tfile
25045         mkdir -p $DIR/$tdir
25046         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25047         stack_trap "rm -rf $DIR/$tdir"
25048
25049         local mdtidx=$($LFS getstripe -m $dom)
25050         local mdtname=MDT$(printf %04x $mdtidx)
25051         local facet=mds$((mdtidx + 1))
25052
25053         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25054                 error "failed to write data into $dom"
25055         local old_md5=$(md5sum $dom)
25056         cancel_lru_locks mdc
25057         local mdtfree1=$(do_facet $facet \
25058                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25059
25060         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25061                 error "failed to migrate to the new composite layout"
25062         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25063                 error "MDT stripe was not removed"
25064
25065         cancel_lru_locks mdc
25066         local new_md5=$(md5sum $dom)
25067         [ "$old_md5" == "$new_md5" ] ||
25068                 error "$old_md5 != $new_md5"
25069
25070         # Skip free space checks with ZFS
25071         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25072                 local mdtfree2=$(do_facet $facet \
25073                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25074                 [ $mdtfree2 -gt $mdtfree1 ] ||
25075                         error "MDS space is not freed after migration"
25076         fi
25077         return 0
25078 }
25079 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25080
25081 test_272d() {
25082         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25083                 skip "Need MDS version at least 2.12.55"
25084
25085         local dom=$DIR/$tdir/$tfile
25086         mkdir -p $DIR/$tdir
25087         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25088
25089         local mdtidx=$($LFS getstripe -m $dom)
25090         local mdtname=MDT$(printf %04x $mdtidx)
25091         local facet=mds$((mdtidx + 1))
25092
25093         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25094                 error "failed to write data into $dom"
25095         local old_md5=$(md5sum $dom)
25096         cancel_lru_locks mdc
25097         local mdtfree1=$(do_facet $facet \
25098                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25099
25100         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25101                 error "failed mirroring to the new composite layout"
25102         $LFS mirror resync $dom ||
25103                 error "failed mirror resync"
25104         $LFS mirror split --mirror-id 1 -d $dom ||
25105                 error "failed mirror split"
25106
25107         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25108                 error "MDT stripe was not removed"
25109
25110         cancel_lru_locks mdc
25111         local new_md5=$(md5sum $dom)
25112         [ "$old_md5" == "$new_md5" ] ||
25113                 error "$old_md5 != $new_md5"
25114
25115         # Skip free space checks with ZFS
25116         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25117                 local mdtfree2=$(do_facet $facet \
25118                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25119                 [ $mdtfree2 -gt $mdtfree1 ] ||
25120                         error "MDS space is not freed after DOM mirror deletion"
25121         fi
25122         return 0
25123 }
25124 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25125
25126 test_272e() {
25127         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25128                 skip "Need MDS version at least 2.12.55"
25129
25130         local dom=$DIR/$tdir/$tfile
25131         mkdir -p $DIR/$tdir
25132         $LFS setstripe -c 2 $dom
25133
25134         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25135                 error "failed to write data into $dom"
25136         local old_md5=$(md5sum $dom)
25137         cancel_lru_locks
25138
25139         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25140                 error "failed mirroring to the DOM layout"
25141         $LFS mirror resync $dom ||
25142                 error "failed mirror resync"
25143         $LFS mirror split --mirror-id 1 -d $dom ||
25144                 error "failed mirror split"
25145
25146         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25147                 error "MDT stripe wasn't set"
25148
25149         cancel_lru_locks
25150         local new_md5=$(md5sum $dom)
25151         [ "$old_md5" == "$new_md5" ] ||
25152                 error "$old_md5 != $new_md5"
25153
25154         return 0
25155 }
25156 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25157
25158 test_272f() {
25159         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25160                 skip "Need MDS version at least 2.12.55"
25161
25162         local dom=$DIR/$tdir/$tfile
25163         mkdir -p $DIR/$tdir
25164         $LFS setstripe -c 2 $dom
25165
25166         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25167                 error "failed to write data into $dom"
25168         local old_md5=$(md5sum $dom)
25169         cancel_lru_locks
25170
25171         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25172                 error "failed migrating to the DOM file"
25173
25174         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25175                 error "MDT stripe wasn't set"
25176
25177         cancel_lru_locks
25178         local new_md5=$(md5sum $dom)
25179         [ "$old_md5" != "$new_md5" ] &&
25180                 error "$old_md5 != $new_md5"
25181
25182         return 0
25183 }
25184 run_test 272f "DoM migration: OST-striped file to DOM file"
25185
25186 test_273a() {
25187         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25188                 skip "Need MDS version at least 2.11.50"
25189
25190         # Layout swap cannot be done if either file has DOM component,
25191         # this will never be supported, migration should be used instead
25192
25193         local dom=$DIR/$tdir/$tfile
25194         mkdir -p $DIR/$tdir
25195
25196         $LFS setstripe -c2 ${dom}_plain
25197         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25198         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25199                 error "can swap layout with DoM component"
25200         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25201                 error "can swap layout with DoM component"
25202
25203         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25204         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25205                 error "can swap layout with DoM component"
25206         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25207                 error "can swap layout with DoM component"
25208         return 0
25209 }
25210 run_test 273a "DoM: layout swapping should fail with DOM"
25211
25212 test_273b() {
25213         mkdir -p $DIR/$tdir
25214         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25215
25216 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25217         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25218
25219         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25220 }
25221 run_test 273b "DoM: race writeback and object destroy"
25222
25223 test_273c() {
25224         mkdir -p $DIR/$tdir
25225         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25226
25227         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25228         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25229
25230         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25231 }
25232 run_test 273c "race writeback and object destroy"
25233
25234 test_275() {
25235         remote_ost_nodsh && skip "remote OST with nodsh"
25236         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25237                 skip "Need OST version >= 2.10.57"
25238
25239         local file=$DIR/$tfile
25240         local oss
25241
25242         oss=$(comma_list $(osts_nodes))
25243
25244         dd if=/dev/urandom of=$file bs=1M count=2 ||
25245                 error "failed to create a file"
25246         stack_trap "rm -f $file"
25247         cancel_lru_locks osc
25248
25249         #lock 1
25250         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25251                 error "failed to read a file"
25252
25253 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25254         $LCTL set_param fail_loc=0x8000031f
25255
25256         cancel_lru_locks osc &
25257         sleep 1
25258
25259 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25260         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25261         #IO takes another lock, but matches the PENDING one
25262         #and places it to the IO RPC
25263         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25264                 error "failed to read a file with PENDING lock"
25265 }
25266 run_test 275 "Read on a canceled duplicate lock"
25267
25268 test_276() {
25269         remote_ost_nodsh && skip "remote OST with nodsh"
25270         local pid
25271
25272         do_facet ost1 "(while true; do \
25273                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25274                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25275         pid=$!
25276
25277         for LOOP in $(seq 20); do
25278                 stop ost1
25279                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25280         done
25281         kill -9 $pid
25282         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25283                 rm $TMP/sanity_276_pid"
25284 }
25285 run_test 276 "Race between mount and obd_statfs"
25286
25287 test_277() {
25288         $LCTL set_param ldlm.namespaces.*.lru_size=0
25289         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25290         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25291                           awk '/^used_mb/ { print $2 }')
25292         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25293         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25294                 oflag=direct conv=notrunc
25295         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25296                     awk '/^used_mb/ { print $2 }')
25297         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25298 }
25299 run_test 277 "Direct IO shall drop page cache"
25300
25301 test_278() {
25302         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25303         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25304         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25305                 skip "needs the same host for mdt1 mdt2" && return
25306
25307         local pid1
25308         local pid2
25309
25310 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25311         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25312         stop mds2 &
25313         pid2=$!
25314
25315         stop mds1
25316
25317         echo "Starting MDTs"
25318         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25319         wait $pid2
25320 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25321 #will return NULL
25322         do_facet mds2 $LCTL set_param fail_loc=0
25323
25324         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25325         wait_recovery_complete mds2
25326 }
25327 run_test 278 "Race starting MDS between MDTs stop/start"
25328
25329 test_280() {
25330         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25331                 skip "Need MGS version at least 2.13.52"
25332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25333         combined_mgs_mds || skip "needs combined MGS/MDT"
25334
25335         umount_client $MOUNT
25336 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25337         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25338
25339         mount_client $MOUNT &
25340         sleep 1
25341         stop mgs || error "stop mgs failed"
25342         #for a race mgs would crash
25343         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25344         # make sure we unmount client before remounting
25345         wait
25346         umount_client $MOUNT
25347         mount_client $MOUNT || error "mount client failed"
25348 }
25349 run_test 280 "Race between MGS umount and client llog processing"
25350
25351 cleanup_test_300() {
25352         trap 0
25353         umask $SAVE_UMASK
25354 }
25355 test_striped_dir() {
25356         local mdt_index=$1
25357         local stripe_count
25358         local stripe_index
25359
25360         mkdir -p $DIR/$tdir
25361
25362         SAVE_UMASK=$(umask)
25363         trap cleanup_test_300 RETURN EXIT
25364
25365         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25366                                                 $DIR/$tdir/striped_dir ||
25367                 error "set striped dir error"
25368
25369         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25370         [ "$mode" = "755" ] || error "expect 755 got $mode"
25371
25372         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25373                 error "getdirstripe failed"
25374         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25375         if [ "$stripe_count" != "2" ]; then
25376                 error "1:stripe_count is $stripe_count, expect 2"
25377         fi
25378         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25379         if [ "$stripe_count" != "2" ]; then
25380                 error "2:stripe_count is $stripe_count, expect 2"
25381         fi
25382
25383         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25384         if [ "$stripe_index" != "$mdt_index" ]; then
25385                 error "stripe_index is $stripe_index, expect $mdt_index"
25386         fi
25387
25388         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25389                 error "nlink error after create striped dir"
25390
25391         mkdir $DIR/$tdir/striped_dir/a
25392         mkdir $DIR/$tdir/striped_dir/b
25393
25394         stat $DIR/$tdir/striped_dir/a ||
25395                 error "create dir under striped dir failed"
25396         stat $DIR/$tdir/striped_dir/b ||
25397                 error "create dir under striped dir failed"
25398
25399         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25400                 error "nlink error after mkdir"
25401
25402         rmdir $DIR/$tdir/striped_dir/a
25403         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25404                 error "nlink error after rmdir"
25405
25406         rmdir $DIR/$tdir/striped_dir/b
25407         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25408                 error "nlink error after rmdir"
25409
25410         chattr +i $DIR/$tdir/striped_dir
25411         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25412                 error "immutable flags not working under striped dir!"
25413         chattr -i $DIR/$tdir/striped_dir
25414
25415         rmdir $DIR/$tdir/striped_dir ||
25416                 error "rmdir striped dir error"
25417
25418         cleanup_test_300
25419
25420         true
25421 }
25422
25423 test_300a() {
25424         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25425                 skip "skipped for lustre < 2.7.0"
25426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25428
25429         test_striped_dir 0 || error "failed on striped dir on MDT0"
25430         test_striped_dir 1 || error "failed on striped dir on MDT0"
25431 }
25432 run_test 300a "basic striped dir sanity test"
25433
25434 test_300b() {
25435         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25436                 skip "skipped for lustre < 2.7.0"
25437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25438         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25439
25440         local i
25441         local mtime1
25442         local mtime2
25443         local mtime3
25444
25445         test_mkdir $DIR/$tdir || error "mkdir fail"
25446         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25447                 error "set striped dir error"
25448         for i in {0..9}; do
25449                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25450                 sleep 1
25451                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25452                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25453                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25454                 sleep 1
25455                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25456                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25457                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25458         done
25459         true
25460 }
25461 run_test 300b "check ctime/mtime for striped dir"
25462
25463 test_300c() {
25464         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25465                 skip "skipped for lustre < 2.7.0"
25466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25468
25469         local file_count
25470
25471         mkdir_on_mdt0 $DIR/$tdir
25472         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25473                 error "set striped dir error"
25474
25475         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25476                 error "chown striped dir failed"
25477
25478         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25479                 error "create 5k files failed"
25480
25481         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25482
25483         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25484
25485         rm -rf $DIR/$tdir
25486 }
25487 run_test 300c "chown && check ls under striped directory"
25488
25489 test_300d() {
25490         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25491                 skip "skipped for lustre < 2.7.0"
25492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25494
25495         local stripe_count
25496         local file
25497
25498         mkdir -p $DIR/$tdir
25499         $LFS setstripe -c 2 $DIR/$tdir
25500
25501         #local striped directory
25502         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25503                 error "set striped dir error"
25504         #look at the directories for debug purposes
25505         ls -l $DIR/$tdir
25506         $LFS getdirstripe $DIR/$tdir
25507         ls -l $DIR/$tdir/striped_dir
25508         $LFS getdirstripe $DIR/$tdir/striped_dir
25509         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25510                 error "create 10 files failed"
25511
25512         #remote striped directory
25513         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25514                 error "set striped dir error"
25515         #look at the directories for debug purposes
25516         ls -l $DIR/$tdir
25517         $LFS getdirstripe $DIR/$tdir
25518         ls -l $DIR/$tdir/remote_striped_dir
25519         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25520         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25521                 error "create 10 files failed"
25522
25523         for file in $(find $DIR/$tdir); do
25524                 stripe_count=$($LFS getstripe -c $file)
25525                 [ $stripe_count -eq 2 ] ||
25526                         error "wrong stripe $stripe_count for $file"
25527         done
25528
25529         rm -rf $DIR/$tdir
25530 }
25531 run_test 300d "check default stripe under striped directory"
25532
25533 test_300e() {
25534         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25535                 skip "Need MDS version at least 2.7.55"
25536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25537         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25538
25539         local stripe_count
25540         local file
25541
25542         mkdir -p $DIR/$tdir
25543
25544         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25545                 error "set striped dir error"
25546
25547         touch $DIR/$tdir/striped_dir/a
25548         touch $DIR/$tdir/striped_dir/b
25549         touch $DIR/$tdir/striped_dir/c
25550
25551         mkdir $DIR/$tdir/striped_dir/dir_a
25552         mkdir $DIR/$tdir/striped_dir/dir_b
25553         mkdir $DIR/$tdir/striped_dir/dir_c
25554
25555         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25556                 error "set striped adir under striped dir error"
25557
25558         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25559                 error "set striped bdir under striped dir error"
25560
25561         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25562                 error "set striped cdir under striped dir error"
25563
25564         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25565                 error "rename dir under striped dir fails"
25566
25567         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25568                 error "rename dir under different stripes fails"
25569
25570         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25571                 error "rename file under striped dir should succeed"
25572
25573         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25574                 error "rename dir under striped dir should succeed"
25575
25576         rm -rf $DIR/$tdir
25577 }
25578 run_test 300e "check rename under striped directory"
25579
25580 test_300f() {
25581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25583         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25584                 skip "Need MDS version at least 2.7.55"
25585
25586         local stripe_count
25587         local file
25588
25589         rm -rf $DIR/$tdir
25590         mkdir -p $DIR/$tdir
25591
25592         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25593                 error "set striped dir error"
25594
25595         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25596                 error "set striped dir error"
25597
25598         touch $DIR/$tdir/striped_dir/a
25599         mkdir $DIR/$tdir/striped_dir/dir_a
25600         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25601                 error "create striped dir under striped dir fails"
25602
25603         touch $DIR/$tdir/striped_dir1/b
25604         mkdir $DIR/$tdir/striped_dir1/dir_b
25605         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25606                 error "create striped dir under striped dir fails"
25607
25608         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25609                 error "rename dir under different striped dir should fail"
25610
25611         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25612                 error "rename striped dir under diff striped dir should fail"
25613
25614         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25615                 error "rename file under diff striped dirs fails"
25616
25617         rm -rf $DIR/$tdir
25618 }
25619 run_test 300f "check rename cross striped directory"
25620
25621 test_300_check_default_striped_dir()
25622 {
25623         local dirname=$1
25624         local default_count=$2
25625         local default_index=$3
25626         local stripe_count
25627         local stripe_index
25628         local dir_stripe_index
25629         local dir
25630
25631         echo "checking $dirname $default_count $default_index"
25632         $LFS setdirstripe -D -c $default_count -i $default_index \
25633                                 -H all_char $DIR/$tdir/$dirname ||
25634                 error "set default stripe on striped dir error"
25635         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25636         [ $stripe_count -eq $default_count ] ||
25637                 error "expect $default_count get $stripe_count for $dirname"
25638
25639         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25640         [ $stripe_index -eq $default_index ] ||
25641                 error "expect $default_index get $stripe_index for $dirname"
25642
25643         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25644                                                 error "create dirs failed"
25645
25646         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25647         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25648         for dir in $(find $DIR/$tdir/$dirname/*); do
25649                 stripe_count=$($LFS getdirstripe -c $dir)
25650                 (( $stripe_count == $default_count )) ||
25651                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25652                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25653                 error "stripe count $default_count != $stripe_count for $dir"
25654
25655                 stripe_index=$($LFS getdirstripe -i $dir)
25656                 [ $default_index -eq -1 ] ||
25657                         [ $stripe_index -eq $default_index ] ||
25658                         error "$stripe_index != $default_index for $dir"
25659
25660                 #check default stripe
25661                 stripe_count=$($LFS getdirstripe -D -c $dir)
25662                 [ $stripe_count -eq $default_count ] ||
25663                 error "default count $default_count != $stripe_count for $dir"
25664
25665                 stripe_index=$($LFS getdirstripe -D -i $dir)
25666                 [ $stripe_index -eq $default_index ] ||
25667                 error "default index $default_index != $stripe_index for $dir"
25668         done
25669         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25670 }
25671
25672 test_300g() {
25673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25674         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25675                 skip "Need MDS version at least 2.7.55"
25676
25677         local dir
25678         local stripe_count
25679         local stripe_index
25680
25681         mkdir_on_mdt0 $DIR/$tdir
25682         mkdir $DIR/$tdir/normal_dir
25683
25684         #Checking when client cache stripe index
25685         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25686         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25687                 error "create striped_dir failed"
25688
25689         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25690                 error "create dir0 fails"
25691         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25692         [ $stripe_index -eq 0 ] ||
25693                 error "dir0 expect index 0 got $stripe_index"
25694
25695         mkdir $DIR/$tdir/striped_dir/dir1 ||
25696                 error "create dir1 fails"
25697         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25698         [ $stripe_index -eq 1 ] ||
25699                 error "dir1 expect index 1 got $stripe_index"
25700
25701         #check default stripe count/stripe index
25702         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25703         test_300_check_default_striped_dir normal_dir 1 0
25704         test_300_check_default_striped_dir normal_dir -1 1
25705         test_300_check_default_striped_dir normal_dir 2 -1
25706
25707         #delete default stripe information
25708         echo "delete default stripeEA"
25709         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25710                 error "set default stripe on striped dir error"
25711
25712         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25713         for dir in $(find $DIR/$tdir/normal_dir/*); do
25714                 stripe_count=$($LFS getdirstripe -c $dir)
25715                 [ $stripe_count -eq 0 ] ||
25716                         error "expect 1 get $stripe_count for $dir"
25717         done
25718 }
25719 run_test 300g "check default striped directory for normal directory"
25720
25721 test_300h() {
25722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25723         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25724                 skip "Need MDS version at least 2.7.55"
25725
25726         local dir
25727         local stripe_count
25728
25729         mkdir $DIR/$tdir
25730         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25731                 error "set striped dir error"
25732
25733         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25734         test_300_check_default_striped_dir striped_dir 1 0
25735         test_300_check_default_striped_dir striped_dir -1 1
25736         test_300_check_default_striped_dir striped_dir 2 -1
25737
25738         #delete default stripe information
25739         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25740                 error "set default stripe on striped dir error"
25741
25742         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
25743         for dir in $(find $DIR/$tdir/striped_dir/*); do
25744                 stripe_count=$($LFS getdirstripe -c $dir)
25745                 [ $stripe_count -eq 0 ] ||
25746                         error "expect 1 get $stripe_count for $dir"
25747         done
25748 }
25749 run_test 300h "check default striped directory for striped directory"
25750
25751 test_300i() {
25752         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
25753         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
25754         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
25755                 skip "Need MDS version at least 2.7.55"
25756
25757         local stripe_count
25758         local file
25759
25760         mkdir $DIR/$tdir
25761
25762         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25763                 error "set striped dir error"
25764
25765         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25766                 error "create files under striped dir failed"
25767
25768         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
25769                 error "set striped hashdir error"
25770
25771         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
25772                 error "create dir0 under hash dir failed"
25773         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
25774                 error "create dir1 under hash dir failed"
25775         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
25776                 error "create dir2 under hash dir failed"
25777
25778         # unfortunately, we need to umount to clear dir layout cache for now
25779         # once we fully implement dir layout, we can drop this
25780         umount_client $MOUNT || error "umount failed"
25781         mount_client $MOUNT || error "mount failed"
25782
25783         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
25784         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
25785         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
25786
25787         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
25788                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
25789                         error "create crush2 dir $tdir/hashdir/d3 failed"
25790                 $LFS find -H crush2 $DIR/$tdir/hashdir
25791                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
25792                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
25793
25794                 # mkdir with an invalid hash type (hash=fail_val) from client
25795                 # should be replaced on MDS with a valid (default) hash type
25796                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25797                 $LCTL set_param fail_loc=0x1901 fail_val=99
25798                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
25799
25800                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
25801                 local expect=$(do_facet mds1 \
25802                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
25803                 [[ $hash == $expect ]] ||
25804                         error "d99 hash '$hash' != expected hash '$expect'"
25805         fi
25806
25807         #set the stripe to be unknown hash type on read
25808         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
25809         $LCTL set_param fail_loc=0x1901 fail_val=99
25810         for ((i = 0; i < 10; i++)); do
25811                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
25812                         error "stat f-$i failed"
25813                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
25814         done
25815
25816         touch $DIR/$tdir/striped_dir/f0 &&
25817                 error "create under striped dir with unknown hash should fail"
25818
25819         $LCTL set_param fail_loc=0
25820
25821         umount_client $MOUNT || error "umount failed"
25822         mount_client $MOUNT || error "mount failed"
25823
25824         return 0
25825 }
25826 run_test 300i "client handle unknown hash type striped directory"
25827
25828 test_300j() {
25829         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25831         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25832                 skip "Need MDS version at least 2.7.55"
25833
25834         local stripe_count
25835         local file
25836
25837         mkdir $DIR/$tdir
25838
25839         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
25840         $LCTL set_param fail_loc=0x1702
25841         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25842                 error "set striped dir error"
25843
25844         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
25845                 error "create files under striped dir failed"
25846
25847         $LCTL set_param fail_loc=0
25848
25849         rm -rf $DIR/$tdir || error "unlink striped dir fails"
25850
25851         return 0
25852 }
25853 run_test 300j "test large update record"
25854
25855 test_300k() {
25856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25858         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25859                 skip "Need MDS version at least 2.7.55"
25860
25861         # this test needs a huge transaction
25862         local kb
25863         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25864              osd*.$FSNAME-MDT0000.kbytestotal")
25865         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
25866
25867         local stripe_count
25868         local file
25869
25870         mkdir $DIR/$tdir
25871
25872         #define OBD_FAIL_LARGE_STRIPE   0x1703
25873         $LCTL set_param fail_loc=0x1703
25874         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
25875                 error "set striped dir error"
25876         $LCTL set_param fail_loc=0
25877
25878         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25879                 error "getstripeddir fails"
25880         rm -rf $DIR/$tdir/striped_dir ||
25881                 error "unlink striped dir fails"
25882
25883         return 0
25884 }
25885 run_test 300k "test large striped directory"
25886
25887 test_300l() {
25888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25890         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25891                 skip "Need MDS version at least 2.7.55"
25892
25893         local stripe_index
25894
25895         test_mkdir -p $DIR/$tdir/striped_dir
25896         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
25897                         error "chown $RUNAS_ID failed"
25898         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
25899                 error "set default striped dir failed"
25900
25901         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
25902         $LCTL set_param fail_loc=0x80000158
25903         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
25904
25905         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
25906         [ $stripe_index -eq 1 ] ||
25907                 error "expect 1 get $stripe_index for $dir"
25908 }
25909 run_test 300l "non-root user to create dir under striped dir with stale layout"
25910
25911 test_300m() {
25912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25913         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
25914         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25915                 skip "Need MDS version at least 2.7.55"
25916
25917         mkdir -p $DIR/$tdir/striped_dir
25918         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
25919                 error "set default stripes dir error"
25920
25921         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
25922
25923         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
25924         [ $stripe_count -eq 0 ] ||
25925                         error "expect 0 get $stripe_count for a"
25926
25927         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
25928                 error "set default stripes dir error"
25929
25930         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
25931
25932         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
25933         [ $stripe_count -eq 0 ] ||
25934                         error "expect 0 get $stripe_count for b"
25935
25936         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
25937                 error "set default stripes dir error"
25938
25939         mkdir $DIR/$tdir/striped_dir/c &&
25940                 error "default stripe_index is invalid, mkdir c should fails"
25941
25942         rm -rf $DIR/$tdir || error "rmdir fails"
25943 }
25944 run_test 300m "setstriped directory on single MDT FS"
25945
25946 cleanup_300n() {
25947         local list=$(comma_list $(mdts_nodes))
25948
25949         trap 0
25950         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25951 }
25952
25953 test_300n() {
25954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25956         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25957                 skip "Need MDS version at least 2.7.55"
25958         remote_mds_nodsh && skip "remote MDS with nodsh"
25959
25960         local stripe_index
25961         local list=$(comma_list $(mdts_nodes))
25962
25963         trap cleanup_300n RETURN EXIT
25964         mkdir -p $DIR/$tdir
25965         chmod 777 $DIR/$tdir
25966         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
25967                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25968                 error "create striped dir succeeds with gid=0"
25969
25970         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25971         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
25972                 error "create striped dir fails with gid=-1"
25973
25974         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25975         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
25976                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
25977                 error "set default striped dir succeeds with gid=0"
25978
25979
25980         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
25981         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
25982                 error "set default striped dir fails with gid=-1"
25983
25984
25985         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
25986         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
25987                                         error "create test_dir fails"
25988         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
25989                                         error "create test_dir1 fails"
25990         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
25991                                         error "create test_dir2 fails"
25992         cleanup_300n
25993 }
25994 run_test 300n "non-root user to create dir under striped dir with default EA"
25995
25996 test_300o() {
25997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25998         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25999         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26000                 skip "Need MDS version at least 2.7.55"
26001
26002         local numfree1
26003         local numfree2
26004
26005         mkdir -p $DIR/$tdir
26006
26007         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26008         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26009         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26010                 skip "not enough free inodes $numfree1 $numfree2"
26011         fi
26012
26013         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26014         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26015         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26016                 skip "not enough free space $numfree1 $numfree2"
26017         fi
26018
26019         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26020                 error "setdirstripe fails"
26021
26022         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26023                 error "create dirs fails"
26024
26025         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26026         ls $DIR/$tdir/striped_dir > /dev/null ||
26027                 error "ls striped dir fails"
26028         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26029                 error "unlink big striped dir fails"
26030 }
26031 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26032
26033 test_300p() {
26034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26036         remote_mds_nodsh && skip "remote MDS with nodsh"
26037
26038         mkdir_on_mdt0 $DIR/$tdir
26039
26040         #define OBD_FAIL_OUT_ENOSPC     0x1704
26041         do_facet mds2 lctl set_param fail_loc=0x80001704
26042         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26043                  && error "create striped directory should fail"
26044
26045         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26046
26047         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26048         true
26049 }
26050 run_test 300p "create striped directory without space"
26051
26052 test_300q() {
26053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26055
26056         local fd=$(free_fd)
26057         local cmd="exec $fd<$tdir"
26058         cd $DIR
26059         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26060         eval $cmd
26061         cmd="exec $fd<&-"
26062         trap "eval $cmd" EXIT
26063         cd $tdir || error "cd $tdir fails"
26064         rmdir  ../$tdir || error "rmdir $tdir fails"
26065         mkdir local_dir && error "create dir succeeds"
26066         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26067         eval $cmd
26068         return 0
26069 }
26070 run_test 300q "create remote directory under orphan directory"
26071
26072 test_300r() {
26073         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26074                 skip "Need MDS version at least 2.7.55" && return
26075         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26076
26077         mkdir $DIR/$tdir
26078
26079         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26080                 error "set striped dir error"
26081
26082         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26083                 error "getstripeddir fails"
26084
26085         local stripe_count
26086         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26087                       awk '/lmv_stripe_count:/ { print $2 }')
26088
26089         [ $MDSCOUNT -ne $stripe_count ] &&
26090                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26091
26092         rm -rf $DIR/$tdir/striped_dir ||
26093                 error "unlink striped dir fails"
26094 }
26095 run_test 300r "test -1 striped directory"
26096
26097 test_300s_helper() {
26098         local count=$1
26099
26100         local stripe_dir=$DIR/$tdir/striped_dir.$count
26101
26102         $LFS mkdir -c $count $stripe_dir ||
26103                 error "lfs mkdir -c error"
26104
26105         $LFS getdirstripe $stripe_dir ||
26106                 error "lfs getdirstripe fails"
26107
26108         local stripe_count
26109         stripe_count=$($LFS getdirstripe $stripe_dir |
26110                       awk '/lmv_stripe_count:/ { print $2 }')
26111
26112         [ $count -ne $stripe_count ] &&
26113                 error_noexit "bad stripe count $stripe_count expected $count"
26114
26115         local dupe_stripes
26116         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26117                 awk '/0x/ {count[$1] += 1}; END {
26118                         for (idx in count) {
26119                                 if (count[idx]>1) {
26120                                         print "index " idx " count " count[idx]
26121                                 }
26122                         }
26123                 }')
26124
26125         if [[ -n "$dupe_stripes" ]] ; then
26126                 lfs getdirstripe $stripe_dir
26127                 error_noexit "Dupe MDT above: $dupe_stripes "
26128         fi
26129
26130         rm -rf $stripe_dir ||
26131                 error_noexit "unlink $stripe_dir fails"
26132 }
26133
26134 test_300s() {
26135         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26136                 skip "Need MDS version at least 2.7.55" && return
26137         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26138
26139         mkdir $DIR/$tdir
26140         for count in $(seq 2 $MDSCOUNT); do
26141                 test_300s_helper $count
26142         done
26143 }
26144 run_test 300s "test lfs mkdir -c without -i"
26145
26146 test_300t() {
26147         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26148                 skip "need MDS 2.14.55 or later"
26149         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26150
26151         local testdir="$DIR/$tdir/striped_dir"
26152         local dir1=$testdir/dir1
26153         local dir2=$testdir/dir2
26154
26155         mkdir -p $testdir
26156
26157         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26158                 error "failed to set default stripe count for $testdir"
26159
26160         mkdir $dir1
26161         local stripe_count=$($LFS getdirstripe -c $dir1)
26162
26163         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26164
26165         local max_count=$((MDSCOUNT - 1))
26166         local mdts=$(comma_list $(mdts_nodes))
26167
26168         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26169         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26170
26171         mkdir $dir2
26172         stripe_count=$($LFS getdirstripe -c $dir2)
26173
26174         (( $stripe_count == $max_count )) || error "wrong stripe count"
26175 }
26176 run_test 300t "test max_mdt_stripecount"
26177
26178 prepare_remote_file() {
26179         mkdir $DIR/$tdir/src_dir ||
26180                 error "create remote source failed"
26181
26182         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26183                  error "cp to remote source failed"
26184         touch $DIR/$tdir/src_dir/a
26185
26186         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26187                 error "create remote target dir failed"
26188
26189         touch $DIR/$tdir/tgt_dir/b
26190
26191         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26192                 error "rename dir cross MDT failed!"
26193
26194         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26195                 error "src_child still exists after rename"
26196
26197         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26198                 error "missing file(a) after rename"
26199
26200         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26201                 error "diff after rename"
26202 }
26203
26204 test_310a() {
26205         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26207
26208         local remote_file=$DIR/$tdir/tgt_dir/b
26209
26210         mkdir -p $DIR/$tdir
26211
26212         prepare_remote_file || error "prepare remote file failed"
26213
26214         #open-unlink file
26215         $OPENUNLINK $remote_file $remote_file ||
26216                 error "openunlink $remote_file failed"
26217         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26218 }
26219 run_test 310a "open unlink remote file"
26220
26221 test_310b() {
26222         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26224
26225         local remote_file=$DIR/$tdir/tgt_dir/b
26226
26227         mkdir -p $DIR/$tdir
26228
26229         prepare_remote_file || error "prepare remote file failed"
26230
26231         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26232         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26233         $CHECKSTAT -t file $remote_file || error "check file failed"
26234 }
26235 run_test 310b "unlink remote file with multiple links while open"
26236
26237 test_310c() {
26238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26239         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26240
26241         local remote_file=$DIR/$tdir/tgt_dir/b
26242
26243         mkdir -p $DIR/$tdir
26244
26245         prepare_remote_file || error "prepare remote file failed"
26246
26247         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26248         multiop_bg_pause $remote_file O_uc ||
26249                         error "mulitop failed for remote file"
26250         MULTIPID=$!
26251         $MULTIOP $DIR/$tfile Ouc
26252         kill -USR1 $MULTIPID
26253         wait $MULTIPID
26254 }
26255 run_test 310c "open-unlink remote file with multiple links"
26256
26257 #LU-4825
26258 test_311() {
26259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26260         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26261         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26262                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26263         remote_mds_nodsh && skip "remote MDS with nodsh"
26264
26265         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26266         local mdts=$(comma_list $(mdts_nodes))
26267
26268         mkdir -p $DIR/$tdir
26269         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26270         createmany -o $DIR/$tdir/$tfile. 1000
26271
26272         # statfs data is not real time, let's just calculate it
26273         old_iused=$((old_iused + 1000))
26274
26275         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26276                         osp.*OST0000*MDT0000.create_count")
26277         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26278                                 osp.*OST0000*MDT0000.max_create_count")
26279         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26280
26281         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26282         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26283         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26284
26285         unlinkmany $DIR/$tdir/$tfile. 1000
26286
26287         do_nodes $mdts "$LCTL set_param -n \
26288                         osp.*OST0000*.max_create_count=$max_count"
26289         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26290                 do_nodes $mdts "$LCTL set_param -n \
26291                                 osp.*OST0000*.create_count=$count"
26292         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26293                         grep "=0" && error "create_count is zero"
26294
26295         local new_iused
26296         for i in $(seq 120); do
26297                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26298                 # system may be too busy to destroy all objs in time, use
26299                 # a somewhat small value to not fail autotest
26300                 [ $((old_iused - new_iused)) -gt 400 ] && break
26301                 sleep 1
26302         done
26303
26304         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26305         [ $((old_iused - new_iused)) -gt 400 ] ||
26306                 error "objs not destroyed after unlink"
26307 }
26308 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26309
26310 zfs_get_objid()
26311 {
26312         local ost=$1
26313         local tf=$2
26314         local fid=($($LFS getstripe $tf | grep 0x))
26315         local seq=${fid[3]#0x}
26316         local objid=${fid[1]}
26317
26318         local vdevdir=$(dirname $(facet_vdevice $ost))
26319         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26320         local zfs_zapid=$(do_facet $ost $cmd |
26321                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26322                           awk '/Object/{getline; print $1}')
26323         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26324                           awk "/$objid = /"'{printf $3}')
26325
26326         echo $zfs_objid
26327 }
26328
26329 zfs_object_blksz() {
26330         local ost=$1
26331         local objid=$2
26332
26333         local vdevdir=$(dirname $(facet_vdevice $ost))
26334         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26335         local blksz=$(do_facet $ost $cmd $objid |
26336                       awk '/dblk/{getline; printf $4}')
26337
26338         case "${blksz: -1}" in
26339                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26340                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26341                 *) ;;
26342         esac
26343
26344         echo $blksz
26345 }
26346
26347 test_312() { # LU-4856
26348         remote_ost_nodsh && skip "remote OST with nodsh"
26349         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26350
26351         local max_blksz=$(do_facet ost1 \
26352                           $ZFS get -p recordsize $(facet_device ost1) |
26353                           awk '!/VALUE/{print $3}')
26354         local tf=$DIR/$tfile
26355
26356         $LFS setstripe -c1 $tf
26357         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26358
26359         # Get ZFS object id
26360         local zfs_objid=$(zfs_get_objid $facet $tf)
26361         # block size change by sequential overwrite
26362         local bs
26363
26364         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26365                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26366
26367                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26368                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26369         done
26370         rm -f $tf
26371
26372         $LFS setstripe -c1 $tf
26373         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26374
26375         # block size change by sequential append write
26376         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26377         zfs_objid=$(zfs_get_objid $facet $tf)
26378         local count
26379
26380         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26381                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26382                         oflag=sync conv=notrunc
26383
26384                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26385                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26386                         error "blksz error, actual $blksz, " \
26387                                 "expected: 2 * $count * $PAGE_SIZE"
26388         done
26389         rm -f $tf
26390
26391         # random write
26392         $LFS setstripe -c1 $tf
26393         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26394         zfs_objid=$(zfs_get_objid $facet $tf)
26395
26396         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26397         blksz=$(zfs_object_blksz $facet $zfs_objid)
26398         (( blksz == PAGE_SIZE )) ||
26399                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26400
26401         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26402         blksz=$(zfs_object_blksz $facet $zfs_objid)
26403         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26404
26405         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26406         blksz=$(zfs_object_blksz $facet $zfs_objid)
26407         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26408 }
26409 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26410
26411 test_313() {
26412         remote_ost_nodsh && skip "remote OST with nodsh"
26413
26414         local file=$DIR/$tfile
26415
26416         rm -f $file
26417         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26418
26419         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26420         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26421         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26422                 error "write should failed"
26423         do_facet ost1 "$LCTL set_param fail_loc=0"
26424         rm -f $file
26425 }
26426 run_test 313 "io should fail after last_rcvd update fail"
26427
26428 test_314() {
26429         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26430
26431         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26432         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26433         rm -f $DIR/$tfile
26434         wait_delete_completed
26435         do_facet ost1 "$LCTL set_param fail_loc=0"
26436 }
26437 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26438
26439 test_315() { # LU-618
26440         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26441
26442         local file=$DIR/$tfile
26443         rm -f $file
26444
26445         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26446                 error "multiop file write failed"
26447         $MULTIOP $file oO_RDONLY:r4063232_c &
26448         PID=$!
26449
26450         sleep 2
26451
26452         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26453         kill -USR1 $PID
26454
26455         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26456         rm -f $file
26457 }
26458 run_test 315 "read should be accounted"
26459
26460 test_316() {
26461         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26462         large_xattr_enabled || skip "ea_inode feature disabled"
26463
26464         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26465         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26466         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26467         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26468
26469         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26470 }
26471 run_test 316 "lfs migrate of file with large_xattr enabled"
26472
26473 test_317() {
26474         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26475                 skip "Need MDS version at least 2.11.53"
26476         if [ "$ost1_FSTYPE" == "zfs" ]; then
26477                 skip "LU-10370: no implementation for ZFS"
26478         fi
26479
26480         local trunc_sz
26481         local grant_blk_size
26482
26483         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26484                         awk '/grant_block_size:/ { print $2; exit; }')
26485         #
26486         # Create File of size 5M. Truncate it to below size's and verify
26487         # blocks count.
26488         #
26489         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26490                 error "Create file $DIR/$tfile failed"
26491         stack_trap "rm -f $DIR/$tfile" EXIT
26492
26493         for trunc_sz in 2097152 4097 4000 509 0; do
26494                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26495                         error "truncate $tfile to $trunc_sz failed"
26496                 local sz=$(stat --format=%s $DIR/$tfile)
26497                 local blk=$(stat --format=%b $DIR/$tfile)
26498                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26499                                      grant_blk_size) * 8))
26500
26501                 if [[ $blk -ne $trunc_blk ]]; then
26502                         $(which stat) $DIR/$tfile
26503                         error "Expected Block $trunc_blk got $blk for $tfile"
26504                 fi
26505
26506                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26507                         error "Expected Size $trunc_sz got $sz for $tfile"
26508         done
26509
26510         #
26511         # sparse file test
26512         # Create file with a hole and write actual 65536 bytes which aligned
26513         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26514         #
26515         local bs=65536
26516         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26517                 error "Create file : $DIR/$tfile"
26518
26519         #
26520         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26521         # blocks. The block count must drop to 8.
26522         #
26523         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26524                 ((bs - grant_blk_size) + 1)))
26525         $TRUNCATE $DIR/$tfile $trunc_sz ||
26526                 error "truncate $tfile to $trunc_sz failed"
26527
26528         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26529         sz=$(stat --format=%s $DIR/$tfile)
26530         blk=$(stat --format=%b $DIR/$tfile)
26531
26532         if [[ $blk -ne $trunc_bsz ]]; then
26533                 $(which stat) $DIR/$tfile
26534                 error "Expected Block $trunc_bsz got $blk for $tfile"
26535         fi
26536
26537         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26538                 error "Expected Size $trunc_sz got $sz for $tfile"
26539 }
26540 run_test 317 "Verify blocks get correctly update after truncate"
26541
26542 test_318() {
26543         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26544         local old_max_active=$($LCTL get_param -n \
26545                             ${llite_name}.max_read_ahead_async_active \
26546                             2>/dev/null)
26547
26548         $LCTL set_param llite.*.max_read_ahead_async_active=256
26549         local max_active=$($LCTL get_param -n \
26550                            ${llite_name}.max_read_ahead_async_active \
26551                            2>/dev/null)
26552         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26553
26554         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26555                 error "set max_read_ahead_async_active should succeed"
26556
26557         $LCTL set_param llite.*.max_read_ahead_async_active=512
26558         max_active=$($LCTL get_param -n \
26559                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26560         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26561
26562         # restore @max_active
26563         [ $old_max_active -ne 0 ] && $LCTL set_param \
26564                 llite.*.max_read_ahead_async_active=$old_max_active
26565
26566         local old_threshold=$($LCTL get_param -n \
26567                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26568         local max_per_file_mb=$($LCTL get_param -n \
26569                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26570
26571         local invalid=$(($max_per_file_mb + 1))
26572         $LCTL set_param \
26573                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26574                         && error "set $invalid should fail"
26575
26576         local valid=$(($invalid - 1))
26577         $LCTL set_param \
26578                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26579                         error "set $valid should succeed"
26580         local threshold=$($LCTL get_param -n \
26581                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26582         [ $threshold -eq $valid ] || error \
26583                 "expect threshold $valid got $threshold"
26584         $LCTL set_param \
26585                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26586 }
26587 run_test 318 "Verify async readahead tunables"
26588
26589 test_319() {
26590         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26591
26592         local before=$(date +%s)
26593         local evict
26594         local mdir=$DIR/$tdir
26595         local file=$mdir/xxx
26596
26597         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26598         touch $file
26599
26600 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26601         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26602         $LFS migrate -m1 $mdir &
26603
26604         sleep 1
26605         dd if=$file of=/dev/null
26606         wait
26607         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26608           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26609
26610         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26611 }
26612 run_test 319 "lost lease lock on migrate error"
26613
26614 test_360() {
26615         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26616                 skip "Need OST version at least 2.15.58.96"
26617         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26618
26619         check_set_fallocate_or_skip
26620         local param="osd-ldiskfs.delayed_unlink_mb"
26621         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26622
26623         do_facet ost1 "$LCTL set_param $param=1MiB"
26624         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26625
26626         mkdir $DIR/$tdir/
26627         do_facet ost1 $LCTL set_param debug=+inode
26628         do_facet ost1 $LCTL clear
26629         local files=100
26630
26631         for ((i = 0; i < $files; i++)); do
26632                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26633                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26634         done
26635         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26636
26637         for ((i = 0; i < $files; i++)); do
26638                 unlink $DIR/$tdir/$tfile.$i ||
26639                         error "unlink $DIR/$tdir/$tfile.$i failed"
26640         done
26641
26642         local count=0
26643         local loop
26644
26645         for (( loop = 0; loop < 30 && count < min; loop++)); do
26646                 sleep 1
26647                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26648                 echo "Count[$loop]: $count"
26649         done
26650         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26651 }
26652 run_test 360 "ldiskfs unlink in a separate thread"
26653
26654 test_398a() { # LU-4198
26655         local ost1_imp=$(get_osc_import_name client ost1)
26656         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26657                          cut -d'.' -f2)
26658
26659         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26660         stack_trap "rm -f $DIR/$tfile"
26661         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26662
26663         # request a new lock on client
26664         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26665
26666         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26667         local lock_count=$($LCTL get_param -n \
26668                            ldlm.namespaces.$imp_name.lru_size)
26669         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26670
26671         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26672
26673         # no lock cached, should use lockless DIO and not enqueue new lock
26674         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26675         lock_count=$($LCTL get_param -n \
26676                      ldlm.namespaces.$imp_name.lru_size)
26677         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26678
26679         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26680
26681         # no lock cached, should use locked DIO append
26682         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26683                 conv=notrunc || error "DIO append failed"
26684         lock_count=$($LCTL get_param -n \
26685                      ldlm.namespaces.$imp_name.lru_size)
26686         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26687 }
26688 run_test 398a "direct IO should cancel lock otherwise lockless"
26689
26690 test_398b() { # LU-4198
26691         local before=$(date +%s)
26692         local njobs=4
26693         local size=48
26694
26695         which fio || skip_env "no fio installed"
26696         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26697         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26698
26699         # Single page, multiple pages, stripe size, 4*stripe size
26700         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26701                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26702                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26703                         --numjobs=$njobs --fallocate=none \
26704                         --iodepth=16 --allow_file_create=0 \
26705                         --size=$((size/njobs))M \
26706                         --filename=$DIR/$tfile &
26707                 bg_pid=$!
26708
26709                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26710                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26711                         --numjobs=$njobs --fallocate=none \
26712                         --iodepth=16 --allow_file_create=0 \
26713                         --size=$((size/njobs))M \
26714                         --filename=$DIR/$tfile || true
26715                 wait $bg_pid
26716         done
26717
26718         evict=$(do_facet client $LCTL get_param \
26719                 osc.$FSNAME-OST*-osc-*/state |
26720             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26721
26722         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26723                 (do_facet client $LCTL get_param \
26724                         osc.$FSNAME-OST*-osc-*/state;
26725                     error "eviction happened: $evict before:$before")
26726
26727         rm -f $DIR/$tfile
26728 }
26729 run_test 398b "DIO and buffer IO race"
26730
26731 test_398c() { # LU-4198
26732         local ost1_imp=$(get_osc_import_name client ost1)
26733         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26734                          cut -d'.' -f2)
26735
26736         which fio || skip_env "no fio installed"
26737
26738         saved_debug=$($LCTL get_param -n debug)
26739         $LCTL set_param debug=0
26740
26741         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
26742         ((size /= 1024)) # by megabytes
26743         ((size /= 2)) # write half of the OST at most
26744         [ $size -gt 40 ] && size=40 #reduce test time anyway
26745
26746         $LFS setstripe -c 1 $DIR/$tfile
26747
26748         # it seems like ldiskfs reserves more space than necessary if the
26749         # writing blocks are not mapped, so it extends the file firstly
26750         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
26751         cancel_lru_locks osc
26752
26753         # clear and verify rpc_stats later
26754         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
26755
26756         local njobs=4
26757         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
26758         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
26759                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26760                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26761                 --filename=$DIR/$tfile
26762         [ $? -eq 0 ] || error "fio write error"
26763
26764         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
26765                 error "Locks were requested while doing AIO"
26766
26767         # get the percentage of 1-page I/O
26768         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
26769                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
26770                 awk '{print $7}')
26771         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
26772
26773         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
26774         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
26775                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
26776                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
26777                 --filename=$DIR/$tfile
26778         [ $? -eq 0 ] || error "fio mixed read write error"
26779
26780         echo "AIO with large block size ${size}M"
26781         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
26782                 --numjobs=1 --fallocate=none --ioengine=libaio \
26783                 --iodepth=16 --allow_file_create=0 --size=${size}M \
26784                 --filename=$DIR/$tfile
26785         [ $? -eq 0 ] || error "fio large block size failed"
26786
26787         rm -f $DIR/$tfile
26788         $LCTL set_param debug="$saved_debug"
26789 }
26790 run_test 398c "run fio to test AIO"
26791
26792 test_398d() { #  LU-13846
26793         which aiocp || skip_env "no aiocp installed"
26794         local aio_file=$DIR/$tfile.aio
26795
26796         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26797
26798         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
26799         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
26800         stack_trap "rm -f $DIR/$tfile $aio_file"
26801
26802         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26803
26804         # test memory unaligned aio
26805         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
26806                 error "unaligned aio failed"
26807         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
26808
26809         rm -f $DIR/$tfile $aio_file
26810 }
26811 run_test 398d "run aiocp to verify block size > stripe size"
26812
26813 test_398e() {
26814         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
26815         touch $DIR/$tfile.new
26816         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
26817 }
26818 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
26819
26820 test_398f() { #  LU-14687
26821         which aiocp || skip_env "no aiocp installed"
26822         local aio_file=$DIR/$tfile.aio
26823
26824         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
26825
26826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
26827         stack_trap "rm -f $DIR/$tfile $aio_file"
26828
26829         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26830         $LCTL set_param fail_loc=0x1418
26831         # make sure we don't crash and fail properly
26832         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
26833                 error "aio with page allocation failure succeeded"
26834         $LCTL set_param fail_loc=0
26835         diff $DIR/$tfile $aio_file
26836         [[ $? != 0 ]] || error "no diff after failed aiocp"
26837 }
26838 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
26839
26840 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
26841 # stripe and i/o size must be > stripe size
26842 # Old style synchronous DIO waits after submitting each chunk, resulting in a
26843 # single RPC in flight.  This test shows async DIO submission is working by
26844 # showing multiple RPCs in flight.
26845 test_398g() { #  LU-13798
26846         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26847
26848         # We need to do some i/o first to acquire enough grant to put our RPCs
26849         # in flight; otherwise a new connection may not have enough grant
26850         # available
26851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26852                 error "parallel dio failed"
26853         stack_trap "rm -f $DIR/$tfile"
26854
26855         # Reduce RPC size to 1M to avoid combination in to larger RPCs
26856         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26857         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26858         stack_trap "$LCTL set_param -n $pages_per_rpc"
26859
26860         # Recreate file so it's empty
26861         rm -f $DIR/$tfile
26862         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
26863         #Pause rpc completion to guarantee we see multiple rpcs in flight
26864         #define OBD_FAIL_OST_BRW_PAUSE_BULK
26865         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
26866         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
26867
26868         # Clear rpc stats
26869         $LCTL set_param osc.*.rpc_stats=c
26870
26871         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26872                 error "parallel dio failed"
26873         stack_trap "rm -f $DIR/$tfile"
26874
26875         $LCTL get_param osc.*-OST0000-*.rpc_stats
26876         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26877                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26878                 grep "8:" | awk '{print $8}')
26879         # We look at the "8 rpcs in flight" field, and verify A) it is present
26880         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
26881         # as expected for an 8M DIO to a file with 1M stripes.
26882         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
26883
26884         # Verify turning off parallel dio works as expected
26885         # Clear rpc stats
26886         $LCTL set_param osc.*.rpc_stats=c
26887         $LCTL set_param llite.*.parallel_dio=0
26888         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
26889
26890         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
26891                 error "dio with parallel dio disabled failed"
26892
26893         # Ideally, we would see only one RPC in flight here, but there is an
26894         # unavoidable race between i/o completion and RPC in flight counting,
26895         # so while only 1 i/o is in flight at a time, the RPC in flight counter
26896         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
26897         # So instead we just verify it's always < 8.
26898         $LCTL get_param osc.*-OST0000-*.rpc_stats
26899         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
26900                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
26901                 grep '^$' -B1 | grep . | awk '{print $1}')
26902         [ $ret != "8:" ] ||
26903                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
26904 }
26905 run_test 398g "verify parallel dio async RPC submission"
26906
26907 test_398h() { #  LU-13798
26908         local dio_file=$DIR/$tfile.dio
26909
26910         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26911
26912         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26913         stack_trap "rm -f $DIR/$tfile $dio_file"
26914
26915         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
26916                 error "parallel dio failed"
26917         diff $DIR/$tfile $dio_file
26918         [[ $? == 0 ]] || error "file diff after aiocp"
26919 }
26920 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
26921
26922 test_398i() { #  LU-13798
26923         local dio_file=$DIR/$tfile.dio
26924
26925         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
26926
26927         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26928         stack_trap "rm -f $DIR/$tfile $dio_file"
26929
26930         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
26931         $LCTL set_param fail_loc=0x1418
26932         # make sure we don't crash and fail properly
26933         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
26934                 error "parallel dio page allocation failure succeeded"
26935         diff $DIR/$tfile $dio_file
26936         [[ $? != 0 ]] || error "no diff after failed aiocp"
26937 }
26938 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
26939
26940 test_398j() { #  LU-13798
26941         # Stripe size > RPC size but less than i/o size tests split across
26942         # stripes and RPCs for individual i/o op
26943         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
26944
26945         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
26946         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
26947         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
26948         stack_trap "$LCTL set_param -n $pages_per_rpc"
26949
26950         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26951                 error "parallel dio write failed"
26952         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
26953
26954         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
26955                 error "parallel dio read failed"
26956         diff $DIR/$tfile $DIR/$tfile.2
26957         [[ $? == 0 ]] || error "file diff after parallel dio read"
26958 }
26959 run_test 398j "test parallel dio where stripe size > rpc_size"
26960
26961 test_398k() { #  LU-13798
26962         wait_delete_completed
26963         wait_mds_ost_sync
26964
26965         # 4 stripe file; we will cause out of space on OST0
26966         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
26967
26968         # Fill OST0 (if it's not too large)
26969         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
26970                    head -n1)
26971         if [[ $ORIGFREE -gt $MAXFREE ]]; then
26972                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
26973         fi
26974         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
26975         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
26976                 error "dd should fill OST0"
26977         stack_trap "rm -f $DIR/$tfile.1"
26978
26979         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
26980         err=$?
26981
26982         ls -la $DIR/$tfile
26983         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
26984                 error "file is not 0 bytes in size"
26985
26986         # dd above should not succeed, but don't error until here so we can
26987         # get debug info above
26988         [[ $err != 0 ]] ||
26989                 error "parallel dio write with enospc succeeded"
26990         stack_trap "rm -f $DIR/$tfile"
26991 }
26992 run_test 398k "test enospc on first stripe"
26993
26994 test_398l() { #  LU-13798
26995         wait_delete_completed
26996         wait_mds_ost_sync
26997
26998         # 4 stripe file; we will cause out of space on OST0
26999         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27000         # happens on the second i/o chunk we issue
27001         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27002
27003         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27004         stack_trap "rm -f $DIR/$tfile"
27005
27006         # Fill OST0 (if it's not too large)
27007         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27008                    head -n1)
27009         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27010                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27011         fi
27012         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27013         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27014                 error "dd should fill OST0"
27015         stack_trap "rm -f $DIR/$tfile.1"
27016
27017         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27018         err=$?
27019         stack_trap "rm -f $DIR/$tfile.2"
27020
27021         # Check that short write completed as expected
27022         ls -la $DIR/$tfile.2
27023         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27024                 error "file is not 1M in size"
27025
27026         # dd above should not succeed, but don't error until here so we can
27027         # get debug info above
27028         [[ $err != 0 ]] ||
27029                 error "parallel dio write with enospc succeeded"
27030
27031         # Truncate source file to same length as output file and diff them
27032         $TRUNCATE $DIR/$tfile 1048576
27033         diff $DIR/$tfile $DIR/$tfile.2
27034         [[ $? == 0 ]] || error "data incorrect after short write"
27035 }
27036 run_test 398l "test enospc on intermediate stripe/RPC"
27037
27038 test_398m() { #  LU-13798
27039         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27040
27041         # Set up failure on OST0, the first stripe:
27042         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27043         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27044         # OST0 is on ost1, OST1 is on ost2.
27045         # So this fail_val specifies OST0
27046         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27047         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27048
27049         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27050                 error "parallel dio write with failure on first stripe succeeded"
27051         stack_trap "rm -f $DIR/$tfile"
27052         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27053
27054         # Place data in file for read
27055         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27056                 error "parallel dio write failed"
27057
27058         # Fail read on OST0, first stripe
27059         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27060         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27061         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27062                 error "parallel dio read with error on first stripe succeeded"
27063         rm -f $DIR/$tfile.2
27064         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27065
27066         # Switch to testing on OST1, second stripe
27067         # Clear file contents, maintain striping
27068         echo > $DIR/$tfile
27069         # Set up failure on OST1, second stripe:
27070         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27071         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27072
27073         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27074                 error "parallel dio write with failure on second stripe succeeded"
27075         stack_trap "rm -f $DIR/$tfile"
27076         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27077
27078         # Place data in file for read
27079         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27080                 error "parallel dio write failed"
27081
27082         # Fail read on OST1, second stripe
27083         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27084         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27085         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27086                 error "parallel dio read with error on second stripe succeeded"
27087         rm -f $DIR/$tfile.2
27088         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27089 }
27090 run_test 398m "test RPC failures with parallel dio"
27091
27092 # Parallel submission of DIO should not cause problems for append, but it's
27093 # important to verify.
27094 test_398n() { #  LU-13798
27095         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27096
27097         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27098                 error "dd to create source file failed"
27099         stack_trap "rm -f $DIR/$tfile"
27100
27101         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27102                 error "parallel dio write with failure on second stripe succeeded"
27103         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27104         diff $DIR/$tfile $DIR/$tfile.1
27105         [[ $? == 0 ]] || error "data incorrect after append"
27106
27107 }
27108 run_test 398n "test append with parallel DIO"
27109
27110 test_398o() {
27111         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27112 }
27113 run_test 398o "right kms with DIO"
27114
27115 test_398p()
27116 {
27117         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27118         which aiocp || skip_env "no aiocp installed"
27119
27120         local stripe_size=$((1024 * 1024)) #1 MiB
27121         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27122         local file_size=$((25 * stripe_size))
27123
27124         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27125         stack_trap "rm -f $DIR/$tfile*"
27126         # Just a bit bigger than the largest size in the test set below
27127         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27128                 error "buffered i/o to create file failed"
27129
27130         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27131                 $((stripe_size * 4)); do
27132
27133                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27134
27135                 echo "bs: $bs, file_size $file_size"
27136                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27137                         $DIR/$tfile.1 $DIR/$tfile.2 &
27138                 pid_dio1=$!
27139                 # Buffered I/O with similar but not the same block size
27140                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27141                         conv=notrunc &
27142                 pid_bio2=$!
27143                 wait $pid_dio1
27144                 rc1=$?
27145                 wait $pid_bio2
27146                 rc2=$?
27147                 if (( rc1 != 0 )); then
27148                         error "aio copy 1 w/bsize $bs failed: $rc1"
27149                 fi
27150                 if (( rc2 != 0 )); then
27151                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27152                 fi
27153
27154                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27155                         error "size incorrect"
27156                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27157                         error "files differ, bsize $bs"
27158                 rm -f $DIR/$tfile.2
27159         done
27160 }
27161 run_test 398p "race aio with buffered i/o"
27162
27163 test_398q()
27164 {
27165         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27166
27167         local stripe_size=$((1024 * 1024)) #1 MiB
27168         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27169         local file_size=$((25 * stripe_size))
27170
27171         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27172         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27173
27174         # Just a bit bigger than the largest size in the test set below
27175         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27176                 error "buffered i/o to create file failed"
27177
27178         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27179                 $((stripe_size * 4)); do
27180
27181                 echo "bs: $bs, file_size $file_size"
27182                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/tfile.2 \
27183                         conv=notrunc oflag=direct iflag=direct &
27184                 pid_dio1=$!
27185                 # Buffered I/O with similar but not the same block size
27186                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27187                         conv=notrunc &
27188                 pid_bio2=$!
27189                 wait $pid_dio1
27190                 rc1=$?
27191                 wait $pid_bio2
27192                 rc2=$?
27193                 if (( rc1 != 0 )); then
27194                         error "dio copy 1 w/bsize $bs failed: $rc1"
27195                 fi
27196                 if (( rc2 != 0 )); then
27197                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27198                 fi
27199
27200                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27201                         error "size incorrect"
27202                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27203                         error "files differ, bsize $bs"
27204         done
27205
27206         rm -f $DIR/$tfile*
27207 }
27208 run_test 398q "race dio with buffered i/o"
27209
27210 test_fake_rw() {
27211         local read_write=$1
27212         if [ "$read_write" = "write" ]; then
27213                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27214         elif [ "$read_write" = "read" ]; then
27215                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27216         else
27217                 error "argument error"
27218         fi
27219
27220         # turn off debug for performance testing
27221         local saved_debug=$($LCTL get_param -n debug)
27222         $LCTL set_param debug=0
27223
27224         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27225
27226         # get ost1 size - $FSNAME-OST0000
27227         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27228         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27229         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27230
27231         if [ "$read_write" = "read" ]; then
27232                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27233         fi
27234
27235         local start_time=$(date +%s.%N)
27236         $dd_cmd bs=1M count=$blocks oflag=sync ||
27237                 error "real dd $read_write error"
27238         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27239
27240         if [ "$read_write" = "write" ]; then
27241                 rm -f $DIR/$tfile
27242         fi
27243
27244         # define OBD_FAIL_OST_FAKE_RW           0x238
27245         do_facet ost1 $LCTL set_param fail_loc=0x238
27246
27247         local start_time=$(date +%s.%N)
27248         $dd_cmd bs=1M count=$blocks oflag=sync ||
27249                 error "fake dd $read_write error"
27250         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27251
27252         if [ "$read_write" = "write" ]; then
27253                 # verify file size
27254                 cancel_lru_locks osc
27255                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27256                         error "$tfile size not $blocks MB"
27257         fi
27258         do_facet ost1 $LCTL set_param fail_loc=0
27259
27260         echo "fake $read_write $duration_fake vs. normal $read_write" \
27261                 "$duration in seconds"
27262         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27263                 error_not_in_vm "fake write is slower"
27264
27265         $LCTL set_param -n debug="$saved_debug"
27266         rm -f $DIR/$tfile
27267 }
27268 test_399a() { # LU-7655 for OST fake write
27269         remote_ost_nodsh && skip "remote OST with nodsh"
27270
27271         test_fake_rw write
27272 }
27273 run_test 399a "fake write should not be slower than normal write"
27274
27275 test_399b() { # LU-8726 for OST fake read
27276         remote_ost_nodsh && skip "remote OST with nodsh"
27277         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27278                 skip_env "ldiskfs only test"
27279         fi
27280
27281         test_fake_rw read
27282 }
27283 run_test 399b "fake read should not be slower than normal read"
27284
27285 test_400a() { # LU-1606, was conf-sanity test_74
27286         if ! which $CC > /dev/null 2>&1; then
27287                 skip_env "$CC is not installed"
27288         fi
27289
27290         local extra_flags=''
27291         local out=$TMP/$tfile
27292         local prefix=/usr/include/lustre
27293         local prog
27294
27295         # Oleg removes .c files in his test rig so test if any c files exist
27296         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27297                 skip_env "Needed .c test files are missing"
27298
27299         if ! [[ -d $prefix ]]; then
27300                 # Assume we're running in tree and fixup the include path.
27301                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27302                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27303                 extra_flags+=" -L$LUSTRE/utils/.libs"
27304         fi
27305
27306         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27307                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27308                         error "client api broken"
27309         done
27310         rm -f $out
27311 }
27312 run_test 400a "Lustre client api program can compile and link"
27313
27314 test_400b() { # LU-1606, LU-5011
27315         local header
27316         local out=$TMP/$tfile
27317         local prefix=/usr/include/linux/lustre
27318
27319         # We use a hard coded prefix so that this test will not fail
27320         # when run in tree. There are headers in lustre/include/lustre/
27321         # that are not packaged (like lustre_idl.h) and have more
27322         # complicated include dependencies (like config.h and lnet/types.h).
27323         # Since this test about correct packaging we just skip them when
27324         # they don't exist (see below) rather than try to fixup cppflags.
27325
27326         if ! which $CC > /dev/null 2>&1; then
27327                 skip_env "$CC is not installed"
27328         fi
27329
27330         for header in $prefix/*.h; do
27331                 if ! [[ -f "$header" ]]; then
27332                         continue
27333                 fi
27334
27335                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27336                         continue # lustre_ioctl.h is internal header
27337                 fi
27338
27339                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27340                         error "cannot compile '$header'"
27341         done
27342         rm -f $out
27343 }
27344 run_test 400b "packaged headers can be compiled"
27345
27346 test_401a() { #LU-7437
27347         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27348         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27349
27350         #count the number of parameters by "list_param -R"
27351         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27352         #count the number of parameters by listing proc files
27353         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27354         echo "proc_dirs='$proc_dirs'"
27355         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27356         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27357                       sort -u | wc -l)
27358
27359         [ $params -eq $procs ] ||
27360                 error "found $params parameters vs. $procs proc files"
27361
27362         # test the list_param -D option only returns directories
27363         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27364         #count the number of parameters by listing proc directories
27365         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27366                 sort -u | wc -l)
27367
27368         [ $params -eq $procs ] ||
27369                 error "found $params parameters vs. $procs proc files"
27370 }
27371 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27372
27373 test_401b() {
27374         # jobid_var may not allow arbitrary values, so use jobid_name
27375         # if available
27376         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27377                 local testname=jobid_name tmp='testing%p'
27378         else
27379                 local testname=jobid_var tmp=testing
27380         fi
27381
27382         local save=$($LCTL get_param -n $testname)
27383
27384         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27385                 error "no error returned when setting bad parameters"
27386
27387         local jobid_new=$($LCTL get_param -n foe $testname baz)
27388         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27389
27390         $LCTL set_param -n fog=bam $testname=$save bat=fog
27391         local jobid_old=$($LCTL get_param -n foe $testname bag)
27392         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27393 }
27394 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27395
27396 test_401c() {
27397         # jobid_var may not allow arbitrary values, so use jobid_name
27398         # if available
27399         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27400                 local testname=jobid_name
27401         else
27402                 local testname=jobid_var
27403         fi
27404
27405         local jobid_var_old=$($LCTL get_param -n $testname)
27406         local jobid_var_new
27407
27408         $LCTL set_param $testname= &&
27409                 error "no error returned for 'set_param a='"
27410
27411         jobid_var_new=$($LCTL get_param -n $testname)
27412         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27413                 error "$testname was changed by setting without value"
27414
27415         $LCTL set_param $testname &&
27416                 error "no error returned for 'set_param a'"
27417
27418         jobid_var_new=$($LCTL get_param -n $testname)
27419         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27420                 error "$testname was changed by setting without value"
27421 }
27422 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27423
27424 test_401d() {
27425         # jobid_var may not allow arbitrary values, so use jobid_name
27426         # if available
27427         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27428                 local testname=jobid_name new_value='foo=bar%p'
27429         else
27430                 local testname=jobid_var new_valuie=foo=bar
27431         fi
27432
27433         local jobid_var_old=$($LCTL get_param -n $testname)
27434         local jobid_var_new
27435
27436         $LCTL set_param $testname=$new_value ||
27437                 error "'set_param a=b' did not accept a value containing '='"
27438
27439         jobid_var_new=$($LCTL get_param -n $testname)
27440         [[ "$jobid_var_new" == "$new_value" ]] ||
27441                 error "'set_param a=b' failed on a value containing '='"
27442
27443         # Reset the $testname to test the other format
27444         $LCTL set_param $testname=$jobid_var_old
27445         jobid_var_new=$($LCTL get_param -n $testname)
27446         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27447                 error "failed to reset $testname"
27448
27449         $LCTL set_param $testname $new_value ||
27450                 error "'set_param a b' did not accept a value containing '='"
27451
27452         jobid_var_new=$($LCTL get_param -n $testname)
27453         [[ "$jobid_var_new" == "$new_value" ]] ||
27454                 error "'set_param a b' failed on a value containing '='"
27455
27456         $LCTL set_param $testname $jobid_var_old
27457         jobid_var_new=$($LCTL get_param -n $testname)
27458         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27459                 error "failed to reset $testname"
27460 }
27461 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27462
27463 test_401e() { # LU-14779
27464         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27465                 error "lctl list_param MGC* failed"
27466         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27467         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27468                 error "lctl get_param lru_size failed"
27469 }
27470 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27471
27472 test_402() {
27473         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27474         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27475                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27476         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27477                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27478                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27479         remote_mds_nodsh && skip "remote MDS with nodsh"
27480
27481         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27482 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27483         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27484         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27485                 echo "Touch failed - OK"
27486 }
27487 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27488
27489 test_403() {
27490         local file1=$DIR/$tfile.1
27491         local file2=$DIR/$tfile.2
27492         local tfile=$TMP/$tfile
27493
27494         rm -f $file1 $file2 $tfile
27495
27496         touch $file1
27497         ln $file1 $file2
27498
27499         # 30 sec OBD_TIMEOUT in ll_getattr()
27500         # right before populating st_nlink
27501         $LCTL set_param fail_loc=0x80001409
27502         stat -c %h $file1 > $tfile &
27503
27504         # create an alias, drop all locks and reclaim the dentry
27505         < $file2
27506         cancel_lru_locks mdc
27507         cancel_lru_locks osc
27508         sysctl -w vm.drop_caches=2
27509
27510         wait
27511
27512         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27513
27514         rm -f $tfile $file1 $file2
27515 }
27516 run_test 403 "i_nlink should not drop to zero due to aliasing"
27517
27518 test_404() { # LU-6601
27519         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27520                 skip "Need server version newer than 2.8.52"
27521         remote_mds_nodsh && skip "remote MDS with nodsh"
27522
27523         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27524                 awk '/osp .*-osc-MDT/ { print $4}')
27525
27526         local osp
27527         for osp in $mosps; do
27528                 echo "Deactivate: " $osp
27529                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27530                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27531                         awk -vp=$osp '$4 == p { print $2 }')
27532                 [ $stat = IN ] || {
27533                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27534                         error "deactivate error"
27535                 }
27536                 echo "Activate: " $osp
27537                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27538                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27539                         awk -vp=$osp '$4 == p { print $2 }')
27540                 [ $stat = UP ] || {
27541                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27542                         error "activate error"
27543                 }
27544         done
27545 }
27546 run_test 404 "validate manual {de}activated works properly for OSPs"
27547
27548 test_405() {
27549         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27550         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27551                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27552                         skip "Layout swap lock is not supported"
27553
27554         check_swap_layouts_support
27555         check_swap_layout_no_dom $DIR
27556
27557         test_mkdir $DIR/$tdir
27558         swap_lock_test -d $DIR/$tdir ||
27559                 error "One layout swap locked test failed"
27560 }
27561 run_test 405 "Various layout swap lock tests"
27562
27563 test_406() {
27564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27566         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27568         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27569                 skip "Need MDS version at least 2.8.50"
27570
27571         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27572         local test_pool=$TESTNAME
27573
27574         pool_add $test_pool || error "pool_add failed"
27575         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27576                 error "pool_add_targets failed"
27577
27578         save_layout_restore_at_exit $MOUNT
27579
27580         # parent set default stripe count only, child will stripe from both
27581         # parent and fs default
27582         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27583                 error "setstripe $MOUNT failed"
27584         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27585         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27586         for i in $(seq 10); do
27587                 local f=$DIR/$tdir/$tfile.$i
27588                 touch $f || error "touch failed"
27589                 local count=$($LFS getstripe -c $f)
27590                 [ $count -eq $OSTCOUNT ] ||
27591                         error "$f stripe count $count != $OSTCOUNT"
27592                 local offset=$($LFS getstripe -i $f)
27593                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27594                 local size=$($LFS getstripe -S $f)
27595                 [ $size -eq $((def_stripe_size * 2)) ] ||
27596                         error "$f stripe size $size != $((def_stripe_size * 2))"
27597                 local pool=$($LFS getstripe -p $f)
27598                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27599         done
27600
27601         # change fs default striping, delete parent default striping, now child
27602         # will stripe from new fs default striping only
27603         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27604                 error "change $MOUNT default stripe failed"
27605         $LFS setstripe -c 0 $DIR/$tdir ||
27606                 error "delete $tdir default stripe failed"
27607         for i in $(seq 11 20); do
27608                 local f=$DIR/$tdir/$tfile.$i
27609                 touch $f || error "touch $f failed"
27610                 local count=$($LFS getstripe -c $f)
27611                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27612                 local offset=$($LFS getstripe -i $f)
27613                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27614                 local size=$($LFS getstripe -S $f)
27615                 [ $size -eq $def_stripe_size ] ||
27616                         error "$f stripe size $size != $def_stripe_size"
27617                 local pool=$($LFS getstripe -p $f)
27618                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27619         done
27620
27621         unlinkmany $DIR/$tdir/$tfile. 1 20
27622
27623         local f=$DIR/$tdir/$tfile
27624         pool_remove_all_targets $test_pool $f
27625         pool_remove $test_pool $f
27626 }
27627 run_test 406 "DNE support fs default striping"
27628
27629 test_407() {
27630         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27631         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27632                 skip "Need MDS version at least 2.8.55"
27633         remote_mds_nodsh && skip "remote MDS with nodsh"
27634
27635         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27636                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27637         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27638                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27639         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27640
27641         #define OBD_FAIL_DT_TXN_STOP    0x2019
27642         for idx in $(seq $MDSCOUNT); do
27643                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27644         done
27645         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27646         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27647                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27648         true
27649 }
27650 run_test 407 "transaction fail should cause operation fail"
27651
27652 test_408() {
27653         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27654
27655         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27656         lctl set_param fail_loc=0x8000040a
27657         # let ll_prepare_partial_page() fail
27658         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27659
27660         rm -f $DIR/$tfile
27661
27662         # create at least 100 unused inodes so that
27663         # shrink_icache_memory(0) should not return 0
27664         touch $DIR/$tfile-{0..100}
27665         rm -f $DIR/$tfile-{0..100}
27666         sync
27667
27668         echo 2 > /proc/sys/vm/drop_caches
27669 }
27670 run_test 408 "drop_caches should not hang due to page leaks"
27671
27672 test_409()
27673 {
27674         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27675
27676         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27677         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27678         touch $DIR/$tdir/guard || error "(2) Fail to create"
27679
27680         local PREFIX=$(str_repeat 'A' 128)
27681         echo "Create 1K hard links start at $(date)"
27682         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27683                 error "(3) Fail to hard link"
27684
27685         echo "Links count should be right although linkEA overflow"
27686         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27687         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27688         [ $linkcount -eq 1001 ] ||
27689                 error "(5) Unexpected hard links count: $linkcount"
27690
27691         echo "List all links start at $(date)"
27692         ls -l $DIR/$tdir/foo > /dev/null ||
27693                 error "(6) Fail to list $DIR/$tdir/foo"
27694
27695         echo "Unlink hard links start at $(date)"
27696         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27697                 error "(7) Fail to unlink"
27698         echo "Unlink hard links finished at $(date)"
27699 }
27700 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27701
27702 test_410()
27703 {
27704         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27705                 skip "Need client version at least 2.9.59"
27706         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27707                 skip "Need MODULES build"
27708
27709         # Create a file, and stat it from the kernel
27710         local testfile=$DIR/$tfile
27711         touch $testfile
27712
27713         local run_id=$RANDOM
27714         local my_ino=$(stat --format "%i" $testfile)
27715
27716         # Try to insert the module. This will always fail as the
27717         # module is designed to not be inserted.
27718         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27719             &> /dev/null
27720
27721         # Anything but success is a test failure
27722         dmesg | grep -q \
27723             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27724             error "no inode match"
27725 }
27726 run_test 410 "Test inode number returned from kernel thread"
27727
27728 cleanup_test411_cgroup() {
27729         trap 0
27730         cat $1/memory.stat
27731         rmdir "$1"
27732 }
27733
27734 test_411a() {
27735         local cg_basedir=/sys/fs/cgroup/memory
27736         # LU-9966
27737         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27738                 skip "no setup for cgroup"
27739
27740         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
27741                 error "test file creation failed"
27742         cancel_lru_locks osc
27743
27744         # Create a very small memory cgroup to force a slab allocation error
27745         local cgdir=$cg_basedir/osc_slab_alloc
27746         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27747         trap "cleanup_test411_cgroup $cgdir" EXIT
27748         echo 2M > $cgdir/memory.kmem.limit_in_bytes
27749         echo 1M > $cgdir/memory.limit_in_bytes
27750
27751         # Should not LBUG, just be killed by oom-killer
27752         # dd will return 0 even allocation failure in some environment.
27753         # So don't check return value
27754         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
27755         cleanup_test411_cgroup $cgdir
27756
27757         return 0
27758 }
27759 run_test 411a "Slab allocation error with cgroup does not LBUG"
27760
27761 test_411b() {
27762         local cg_basedir=/sys/fs/cgroup/memory
27763         # LU-9966
27764         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
27765                 skip "no setup for cgroup"
27766         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27767         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
27768         # limit, so we have 384M in cgroup
27769         # (arm) this seems to hit OOM more often than x86, so 1024M
27770         if [[ $(uname -m) = aarch64 ]]; then
27771                 local memlimit_mb=1024
27772         else
27773                 local memlimit_mb=384
27774         fi
27775
27776         # Create a cgroup and set memory limit
27777         # (tfile is used as an easy way to get a recognizable cgroup name)
27778         local cgdir=$cg_basedir/$tfile
27779         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
27780         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
27781         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
27782
27783         echo "writing first file"
27784         # Write a file 4x the memory limit in size
27785         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
27786                 error "(1) failed to write successfully"
27787
27788         sync
27789         cancel_lru_locks osc
27790
27791         rm -f $DIR/$tfile
27792         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
27793
27794         # Try writing at a larger block size
27795         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
27796         # so test with 1/4 cgroup size (this seems reasonable to me - we do
27797         # need *some* memory to do IO in)
27798         echo "writing at larger block size"
27799         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
27800                 error "(3) failed to write successfully"
27801
27802         sync
27803         cancel_lru_locks osc
27804         rm -f $DIR/$tfile
27805         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
27806
27807         # Try writing multiple files at once
27808         echo "writing multiple files"
27809         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
27810         local pid1=$!
27811         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
27812         local pid2=$!
27813         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
27814         local pid3=$!
27815         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
27816         local pid4=$!
27817
27818         wait $pid1
27819         local rc1=$?
27820         wait $pid2
27821         local rc2=$?
27822         wait $pid3
27823         local rc3=$?
27824         wait $pid4
27825         local rc4=$?
27826         if (( rc1 != 0)); then
27827                 error "error $rc1 writing to file from $pid1"
27828         fi
27829         if (( rc2 != 0)); then
27830                 error "error $rc2 writing to file from $pid2"
27831         fi
27832         if (( rc3 != 0)); then
27833                 error "error $rc3 writing to file from $pid3"
27834         fi
27835         if (( rc4 != 0)); then
27836                 error "error $rc4 writing to file from $pid4"
27837         fi
27838
27839         sync
27840         cancel_lru_locks osc
27841
27842         # These files can be large-ish (~1 GiB total), so delete them rather
27843         # than leave for later cleanup
27844         rm -f $DIR/$tfile.*
27845         return 0
27846 }
27847 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
27848
27849 test_412() {
27850         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
27851         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
27852                 skip "Need server version at least 2.10.55"
27853
27854         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
27855                 error "mkdir failed"
27856         $LFS getdirstripe $DIR/$tdir
27857         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
27858         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
27859                 error "expect $((MDSCOUT - 1)) get $stripe_index"
27860         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
27861         [ $stripe_count -eq 2 ] ||
27862                 error "expect 2 get $stripe_count"
27863
27864         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
27865
27866         local index
27867         local index2
27868
27869         # subdirs should be on the same MDT as parent
27870         for i in $(seq 0 $((MDSCOUNT - 1))); do
27871                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
27872                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
27873                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
27874                 (( index == i )) || error "mdt$i/sub on MDT$index"
27875         done
27876
27877         # stripe offset -1, ditto
27878         for i in {1..10}; do
27879                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
27880                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
27881                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
27882                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
27883                 (( index == index2 )) ||
27884                         error "qos$i on MDT$index, sub on MDT$index2"
27885         done
27886
27887         local testdir=$DIR/$tdir/inherit
27888
27889         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
27890         # inherit 2 levels
27891         for i in 1 2; do
27892                 testdir=$testdir/s$i
27893                 mkdir $testdir || error "mkdir $testdir failed"
27894                 index=$($LFS getstripe -m $testdir)
27895                 (( index == 1 )) ||
27896                         error "$testdir on MDT$index"
27897         done
27898
27899         # not inherit any more
27900         testdir=$testdir/s3
27901         mkdir $testdir || error "mkdir $testdir failed"
27902         getfattr -d -m dmv $testdir | grep dmv &&
27903                 error "default LMV set on $testdir" || true
27904 }
27905 run_test 412 "mkdir on specific MDTs"
27906
27907 TEST413_COUNT=${TEST413_COUNT:-200}
27908
27909 #
27910 # set_maxage() is used by test_413 only.
27911 # This is a helper function to set maxage. Does not return any value.
27912 # Input: maxage to set
27913 #
27914 set_maxage() {
27915         local lmv_qos_maxage
27916         local lod_qos_maxage
27917         local new_maxage=$1
27918
27919         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27920         $LCTL set_param lmv.*.qos_maxage=$new_maxage
27921         stack_trap "$LCTL set_param \
27922                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27923         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27924                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27925         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27926                 lod.*.mdt_qos_maxage=$new_maxage
27927         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27928                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
27929 }
27930
27931 generate_uneven_mdts() {
27932         local threshold=$1
27933         local ffree
27934         local bavail
27935         local max
27936         local min
27937         local max_index
27938         local min_index
27939         local tmp
27940         local i
27941
27942         echo
27943         echo "Check for uneven MDTs: "
27944
27945         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
27946         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
27947         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
27948
27949         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27950         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
27951         max_index=0
27952         min_index=0
27953         for ((i = 1; i < ${#ffree[@]}; i++)); do
27954                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
27955                 if [ $tmp -gt $max ]; then
27956                         max=$tmp
27957                         max_index=$i
27958                 fi
27959                 if [ $tmp -lt $min ]; then
27960                         min=$tmp
27961                         min_index=$i
27962                 fi
27963         done
27964
27965         (( min > 0 )) || skip "low space on MDT$min_index"
27966         (( ${ffree[min_index]} > 0 )) ||
27967                 skip "no free files on MDT$min_index"
27968         (( ${ffree[min_index]} < 10000000 )) ||
27969                 skip "too many free files on MDT$min_index"
27970
27971         # Check if we need to generate uneven MDTs
27972         local diff=$(((max - min) * 100 / min))
27973         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
27974         local testdir # individual folder within $testdirp
27975         local start
27976         local cmd
27977
27978         # fallocate is faster to consume space on MDT, if available
27979         if check_fallocate_supported mds$((min_index + 1)); then
27980                 cmd="fallocate -l 128K "
27981         else
27982                 cmd="dd if=/dev/zero bs=128K count=1 of="
27983         fi
27984
27985         echo "using cmd $cmd"
27986         for (( i = 0; diff < threshold; i++ )); do
27987                 testdir=${testdirp}/$i
27988                 [ -d $testdir ] && continue
27989
27990                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
27991
27992                 mkdir -p $testdirp
27993                 # generate uneven MDTs, create till $threshold% diff
27994                 echo -n "weight diff=$diff% must be > $threshold% ..."
27995                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
27996                 $LFS mkdir -i $min_index $testdir ||
27997                         error "mkdir $testdir failed"
27998                 $LFS setstripe -E 1M -L mdt $testdir ||
27999                         error "setstripe $testdir failed"
28000                 start=$SECONDS
28001                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28002                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28003                 done
28004                 sync; sleep 1; sync
28005
28006                 # wait for QOS to update
28007                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28008
28009                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28010                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28011                 max=$(((${ffree[max_index]} >> 8) *
28012                         (${bavail[max_index]} * bsize >> 16)))
28013                 min=$(((${ffree[min_index]} >> 8) *
28014                         (${bavail[min_index]} * bsize >> 16)))
28015                 (( min > 0 )) || skip "low space on MDT$min_index"
28016                 diff=$(((max - min) * 100 / min))
28017         done
28018
28019         echo "MDT filesfree available: ${ffree[*]}"
28020         echo "MDT blocks available: ${bavail[*]}"
28021         echo "weight diff=$diff%"
28022 }
28023
28024 test_qos_mkdir() {
28025         local mkdir_cmd=$1
28026         local stripe_count=$2
28027         local mdts=$(comma_list $(mdts_nodes))
28028
28029         local testdir
28030         local lmv_qos_prio_free
28031         local lmv_qos_threshold_rr
28032         local lod_qos_prio_free
28033         local lod_qos_threshold_rr
28034         local total
28035         local count
28036         local i
28037
28038         # @total is total directories created if it's testing plain
28039         # directories, otherwise it's total stripe object count for
28040         # striped directories test.
28041         # remote/striped directory unlinking is slow on zfs and may
28042         # timeout, test with fewer directories
28043         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28044
28045         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28046         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28047         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28048                 head -n1)
28049         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28050         stack_trap "$LCTL set_param \
28051                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28052         stack_trap "$LCTL set_param \
28053                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28054
28055         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28056                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28057         lod_qos_prio_free=${lod_qos_prio_free%%%}
28058         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28059                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28060         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28061         stack_trap "do_nodes $mdts $LCTL set_param \
28062                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28063         stack_trap "do_nodes $mdts $LCTL set_param \
28064                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28065
28066         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28067         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28068
28069         testdir=$DIR/$tdir-s$stripe_count/rr
28070
28071         local stripe_index=$($LFS getstripe -m $testdir)
28072         local test_mkdir_rr=true
28073
28074         getfattr -d -m dmv -e hex $testdir | grep dmv
28075         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28076                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28077                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28078                         test_mkdir_rr=false
28079         fi
28080
28081         echo
28082         $test_mkdir_rr &&
28083                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28084                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28085
28086         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28087         for (( i = 0; i < total / stripe_count; i++ )); do
28088                 eval $mkdir_cmd $testdir/subdir$i ||
28089                         error "$mkdir_cmd subdir$i failed"
28090         done
28091
28092         for (( i = 0; i < $MDSCOUNT; i++ )); do
28093                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28094                 echo "$count directories created on MDT$i"
28095                 if $test_mkdir_rr; then
28096                         (( count == total / stripe_count / MDSCOUNT )) ||
28097                                 error "subdirs are not evenly distributed"
28098                 elif (( i == stripe_index )); then
28099                         (( count == total / stripe_count )) ||
28100                                 error "$count subdirs created on MDT$i"
28101                 else
28102                         (( count == 0 )) ||
28103                                 error "$count subdirs created on MDT$i"
28104                 fi
28105
28106                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28107                         count=$($LFS getdirstripe $testdir/* |
28108                                 grep -c -P "^\s+$i\t")
28109                         echo "$count stripes created on MDT$i"
28110                         # deviation should < 5% of average
28111                         delta=$((count - total / MDSCOUNT))
28112                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28113                                 error "stripes are not evenly distributed"
28114                 fi
28115         done
28116
28117         echo
28118         echo "Check for uneven MDTs: "
28119
28120         local ffree
28121         local bavail
28122         local max
28123         local min
28124         local max_index
28125         local min_index
28126         local tmp
28127
28128         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28129         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28130         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28131
28132         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28133         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28134         max_index=0
28135         min_index=0
28136         for ((i = 1; i < ${#ffree[@]}; i++)); do
28137                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28138                 if [ $tmp -gt $max ]; then
28139                         max=$tmp
28140                         max_index=$i
28141                 fi
28142                 if [ $tmp -lt $min ]; then
28143                         min=$tmp
28144                         min_index=$i
28145                 fi
28146         done
28147         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28148
28149         (( min > 0 )) || skip "low space on MDT$min_index"
28150         (( ${ffree[min_index]} < 10000000 )) ||
28151                 skip "too many free files on MDT$min_index"
28152
28153         generate_uneven_mdts 120
28154
28155         echo "MDT filesfree available: ${ffree[*]}"
28156         echo "MDT blocks available: ${bavail[*]}"
28157         echo "weight diff=$(((max - min) * 100 / min))%"
28158         echo
28159         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28160
28161         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28162         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28163         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28164         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28165         # decrease statfs age, so that it can be updated in time
28166         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28167         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28168
28169         sleep 1
28170
28171         testdir=$DIR/$tdir-s$stripe_count/qos
28172
28173         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28174         for (( i = 0; i < total / stripe_count; i++ )); do
28175                 eval $mkdir_cmd $testdir/subdir$i ||
28176                         error "$mkdir_cmd subdir$i failed"
28177         done
28178
28179         max=0
28180         for (( i = 0; i < $MDSCOUNT; i++ )); do
28181                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28182                 (( count > max )) && max=$count
28183                 echo "$count directories created on MDT$i : curmax=$max"
28184         done
28185
28186         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28187
28188         # D-value should > 10% of average
28189         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28190                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28191
28192         # ditto for stripes
28193         if (( stripe_count > 1 )); then
28194                 max=0
28195                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28196                         count=$($LFS getdirstripe $testdir/* |
28197                                 grep -c -P "^\s+$i\t")
28198                         (( count > max )) && max=$count
28199                         echo "$count stripes created on MDT$i"
28200                 done
28201
28202                 min=$($LFS getdirstripe $testdir/* |
28203                         grep -c -P "^\s+$min_index\t")
28204                 (( max - min > total / MDSCOUNT / 10 )) ||
28205                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28206         fi
28207 }
28208
28209 most_full_mdt() {
28210         local ffree
28211         local bavail
28212         local bsize
28213         local min
28214         local min_index
28215         local tmp
28216
28217         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28218         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28219         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28220
28221         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28222         min_index=0
28223         for ((i = 1; i < ${#ffree[@]}; i++)); do
28224                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28225                 (( tmp < min )) && min=$tmp && min_index=$i
28226         done
28227
28228         echo -n $min_index
28229 }
28230
28231 test_413a() {
28232         [ $MDSCOUNT -lt 2 ] &&
28233                 skip "We need at least 2 MDTs for this test"
28234
28235         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28236                 skip "Need server version at least 2.12.52"
28237
28238         local stripe_max=$((MDSCOUNT - 1))
28239         local stripe_count
28240
28241         # let caller set maxage for latest result
28242         set_maxage 1
28243
28244         # fill MDT unevenly
28245         generate_uneven_mdts 120
28246
28247         # test 4-stripe directory at most, otherwise it's too slow
28248         # We are being very defensive. Although Autotest uses 4 MDTs.
28249         # We make sure stripe_max does not go over 4.
28250         (( stripe_max > 4 )) && stripe_max=4
28251         # unlinking striped directory is slow on zfs, and may timeout, only test
28252         # plain directory
28253         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28254         for stripe_count in $(seq 1 $stripe_max); do
28255                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28256                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28257                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28258                         error "mkdir failed"
28259                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28260         done
28261 }
28262 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28263
28264 test_413b() {
28265         [ $MDSCOUNT -lt 2 ] &&
28266                 skip "We need at least 2 MDTs for this test"
28267
28268         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28269                 skip "Need server version at least 2.12.52"
28270
28271         local stripe_max=$((MDSCOUNT - 1))
28272         local testdir
28273         local stripe_count
28274
28275         # let caller set maxage for latest result
28276         set_maxage 1
28277
28278         # fill MDT unevenly
28279         generate_uneven_mdts 120
28280
28281         # test 4-stripe directory at most, otherwise it's too slow
28282         # We are being very defensive. Although Autotest uses 4 MDTs.
28283         # We make sure stripe_max does not go over 4.
28284         (( stripe_max > 4 )) && stripe_max=4
28285         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28286         for stripe_count in $(seq 1 $stripe_max); do
28287                 testdir=$DIR/$tdir-s$stripe_count
28288                 mkdir $testdir || error "mkdir $testdir failed"
28289                 mkdir $testdir/rr || error "mkdir rr failed"
28290                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28291                         error "mkdir qos failed"
28292                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28293                         $testdir/rr || error "setdirstripe rr failed"
28294                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28295                         error "setdirstripe failed"
28296                 test_qos_mkdir "mkdir" $stripe_count
28297         done
28298 }
28299 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28300
28301 test_413c() {
28302         (( $MDSCOUNT >= 2 )) ||
28303                 skip "We need at least 2 MDTs for this test"
28304
28305         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28306                 skip "Need server version at least 2.14.51"
28307
28308         local testdir
28309         local inherit
28310         local inherit_rr
28311         local lmv_qos_maxage
28312         local lod_qos_maxage
28313
28314         # let caller set maxage for latest result
28315         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28316         $LCTL set_param lmv.*.qos_maxage=1
28317         stack_trap "$LCTL set_param \
28318                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28319         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28320                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28321         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28322                 lod.*.mdt_qos_maxage=1
28323         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28324                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28325
28326         # fill MDT unevenly
28327         generate_uneven_mdts 120
28328
28329         testdir=$DIR/${tdir}-s1
28330         mkdir $testdir || error "mkdir $testdir failed"
28331         mkdir $testdir/rr || error "mkdir rr failed"
28332         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28333         # default max_inherit is -1, default max_inherit_rr is 0
28334         $LFS setdirstripe -D -c 1 $testdir/rr ||
28335                 error "setdirstripe rr failed"
28336         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28337                 error "setdirstripe qos failed"
28338         test_qos_mkdir "mkdir" 1
28339
28340         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28341         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28342         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28343         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28344         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28345
28346         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28347         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28348         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28349         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28350         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28351         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28352         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28353                 error "level2 shouldn't have default LMV" || true
28354 }
28355 run_test 413c "mkdir with default LMV max inherit rr"
28356
28357 test_413d() {
28358         (( MDSCOUNT >= 2 )) ||
28359                 skip "We need at least 2 MDTs for this test"
28360
28361         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28362                 skip "Need server version at least 2.14.51"
28363
28364         local lmv_qos_threshold_rr
28365
28366         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28367                 head -n1)
28368         stack_trap "$LCTL set_param \
28369                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28370
28371         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28372         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28373         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28374                 error "$tdir shouldn't have default LMV"
28375         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28376                 error "mkdir sub failed"
28377
28378         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28379
28380         (( count == 100 )) || error "$count subdirs on MDT0"
28381 }
28382 run_test 413d "inherit ROOT default LMV"
28383
28384 test_413e() {
28385         (( MDSCOUNT >= 2 )) ||
28386                 skip "We need at least 2 MDTs for this test"
28387         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28388                 skip "Need server version at least 2.14.55"
28389
28390         local testdir=$DIR/$tdir
28391         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28392         local max_inherit
28393         local sub_max_inherit
28394
28395         mkdir -p $testdir || error "failed to create $testdir"
28396
28397         # set default max-inherit to -1 if stripe count is 0 or 1
28398         $LFS setdirstripe -D -c 1 $testdir ||
28399                 error "failed to set default LMV"
28400         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28401         (( max_inherit == -1 )) ||
28402                 error "wrong max_inherit value $max_inherit"
28403
28404         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28405         $LFS setdirstripe -D -c -1 $testdir ||
28406                 error "failed to set default LMV"
28407         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28408         (( max_inherit > 0 )) ||
28409                 error "wrong max_inherit value $max_inherit"
28410
28411         # and the subdir will decrease the max_inherit by 1
28412         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28413         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28414         (( sub_max_inherit == max_inherit - 1)) ||
28415                 error "wrong max-inherit of subdir $sub_max_inherit"
28416
28417         # check specified --max-inherit and warning message
28418         stack_trap "rm -f $tmpfile"
28419         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28420                 error "failed to set default LMV"
28421         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28422         (( max_inherit == -1 )) ||
28423                 error "wrong max_inherit value $max_inherit"
28424
28425         # check the warning messages
28426         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28427                 error "failed to detect warning string"
28428         fi
28429 }
28430 run_test 413e "check default max-inherit value"
28431
28432 test_fs_dmv_inherit()
28433 {
28434         local testdir=$DIR/$tdir
28435
28436         local count
28437         local inherit
28438         local inherit_rr
28439
28440         for i in 1 2; do
28441                 mkdir $testdir || error "mkdir $testdir failed"
28442                 count=$($LFS getdirstripe -D -c $testdir)
28443                 (( count == 1 )) ||
28444                         error "$testdir default LMV count mismatch $count != 1"
28445                 inherit=$($LFS getdirstripe -D -X $testdir)
28446                 (( inherit == 3 - i )) ||
28447                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28448                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28449                 (( inherit_rr == 3 - i )) ||
28450                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28451                 testdir=$testdir/sub
28452         done
28453
28454         mkdir $testdir || error "mkdir $testdir failed"
28455         count=$($LFS getdirstripe -D -c $testdir)
28456         (( count == 0 )) ||
28457                 error "$testdir default LMV count not zero: $count"
28458 }
28459
28460 test_413f() {
28461         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28462
28463         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28464                 skip "Need server version at least 2.14.55"
28465
28466         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28467                 error "dump $DIR default LMV failed"
28468         stack_trap "setfattr --restore=$TMP/dmv.ea"
28469
28470         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28471                 error "set $DIR default LMV failed"
28472
28473         test_fs_dmv_inherit
28474 }
28475 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28476
28477 test_413g() {
28478         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28479
28480         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28481         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28482                 error "dump $DIR default LMV failed"
28483         stack_trap "setfattr --restore=$TMP/dmv.ea"
28484
28485         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28486                 error "set $DIR default LMV failed"
28487
28488         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28489                 error "mount $MOUNT2 failed"
28490         stack_trap "umount_client $MOUNT2"
28491
28492         local saved_DIR=$DIR
28493
28494         export DIR=$MOUNT2
28495
28496         stack_trap "export DIR=$saved_DIR"
28497
28498         # first check filesystem-wide default LMV inheritance
28499         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28500
28501         # then check subdirs are spread to all MDTs
28502         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28503
28504         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28505
28506         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28507 }
28508 run_test 413g "enforce ROOT default LMV on subdir mount"
28509
28510 test_413h() {
28511         (( MDSCOUNT >= 2 )) ||
28512                 skip "We need at least 2 MDTs for this test"
28513
28514         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28515                 skip "Need server version at least 2.15.50.6"
28516
28517         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28518
28519         stack_trap "$LCTL set_param \
28520                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28521         $LCTL set_param lmv.*.qos_maxage=1
28522
28523         local depth=5
28524         local rr_depth=4
28525         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28526         local count=$((MDSCOUNT * 20))
28527
28528         generate_uneven_mdts 50
28529
28530         mkdir -p $dir || error "mkdir $dir failed"
28531         stack_trap "rm -rf $dir"
28532         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28533                 --max-inherit-rr=$rr_depth $dir
28534
28535         for ((d=0; d < depth + 2; d++)); do
28536                 log "dir=$dir:"
28537                 for ((sub=0; sub < count; sub++)); do
28538                         mkdir $dir/d$sub
28539                 done
28540                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28541                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28542                 # subdirs within $rr_depth should be created round-robin
28543                 if (( d < rr_depth )); then
28544                         (( ${num[0]} != count )) ||
28545                                 error "all objects created on MDT ${num[1]}"
28546                 fi
28547
28548                 dir=$dir/d0
28549         done
28550 }
28551 run_test 413h "don't stick to parent for round-robin dirs"
28552
28553 test_413i() {
28554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28555
28556         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28557                 skip "Need server version at least 2.14.55"
28558
28559         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28560                 error "dump $DIR default LMV failed"
28561         stack_trap "setfattr --restore=$TMP/dmv.ea"
28562
28563         local testdir=$DIR/$tdir
28564         local def_max_rr=1
28565         local def_max=3
28566         local count
28567
28568         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28569                 --max-inherit-rr=$def_max_rr $DIR ||
28570                 error "set $DIR default LMV failed"
28571
28572         for i in $(seq 2 3); do
28573                 def_max=$((def_max - 1))
28574                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28575
28576                 mkdir $testdir
28577                 # RR is decremented and keeps zeroed once exhausted
28578                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28579                 (( count == def_max_rr )) ||
28580                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28581
28582                 # max-inherit is decremented
28583                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28584                 (( count == def_max )) ||
28585                         error_noexit "$testdir: max-inherit $count != $def_max"
28586
28587                 testdir=$testdir/d$i
28588         done
28589
28590         # d3 is the last inherited from ROOT, no inheritance anymore
28591         # i.e. no the default layout anymore
28592         mkdir -p $testdir/d4/d5
28593         count=$($LFS getdirstripe -D --max-inherit $testdir)
28594         (( count == -1 )) ||
28595                 error_noexit "$testdir: max-inherit $count != -1"
28596
28597         local p_count=$($LFS getdirstripe -i $testdir)
28598
28599         for i in $(seq 4 5); do
28600                 testdir=$testdir/d$i
28601
28602                 # the root default layout is not applied once exhausted
28603                 count=$($LFS getdirstripe -i $testdir)
28604                 (( count == p_count )) ||
28605                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28606         done
28607
28608         $LFS setdirstripe -i 0 $DIR/d2
28609         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28610         (( count == -1 )) ||
28611                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28612 }
28613 run_test 413i "check default layout inheritance"
28614
28615 test_413j()
28616 {
28617         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28618
28619         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28620         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28621                 error "setdirstripe $tdir failed"
28622
28623         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28624                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28625
28626         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28627         # setfattr dmv calls setdirstripe -D
28628         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28629                 error "setfattr sub failed"
28630         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28631                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28632
28633         [ $value == $value2 ] || error "dmv mismatch"
28634
28635         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28636
28637         # do not allow remove dmv by setfattr -x
28638         do_nodes $(comma_list $(mdts_nodes)) \
28639                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28640         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28641         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28642
28643         # allow remove dmv by setfattr -x
28644         do_nodes $(comma_list $(mdts_nodes)) \
28645                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28646         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28647         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28648         do_nodes $(comma_list $(mdts_nodes)) \
28649                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28650 }
28651 run_test 413j "set default LMV by setxattr"
28652
28653 test_413z() {
28654         local pids=""
28655         local subdir
28656         local pid
28657
28658         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28659                 unlinkmany $subdir/f. $TEST413_COUNT &
28660                 pids="$pids $!"
28661         done
28662
28663         for pid in $pids; do
28664                 wait $pid
28665         done
28666
28667         true
28668 }
28669 run_test 413z "413 test cleanup"
28670
28671 test_414() {
28672 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28673         $LCTL set_param fail_loc=0x80000521
28674         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28675         rm -f $DIR/$tfile
28676 }
28677 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28678
28679 test_415() {
28680         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28681         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28682                 skip "Need server version at least 2.11.52"
28683
28684         # LU-11102
28685         local total=500
28686         local max=120
28687
28688         # this test may be slow on ZFS
28689         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28690
28691         # though this test is designed for striped directory, let's test normal
28692         # directory too since lock is always saved as CoS lock.
28693         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28694         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28695         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28696         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28697         wait_delete_completed_mds
28698
28699         # run a loop without concurrent touch to measure rename duration.
28700         # only for test debug/robustness, NOT part of COS functional test.
28701         local start_time=$SECONDS
28702         for ((i = 0; i < total; i++)); do
28703                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28704                         > /dev/null
28705         done
28706         local baseline=$((SECONDS - start_time))
28707         echo "rename $total files without 'touch' took $baseline sec"
28708
28709         (
28710                 while true; do
28711                         touch $DIR/$tdir
28712                 done
28713         ) &
28714         local setattr_pid=$!
28715
28716         # rename files back to original name so unlinkmany works
28717         start_time=$SECONDS
28718         for ((i = 0; i < total; i++)); do
28719                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28720                         > /dev/null
28721         done
28722         local duration=$((SECONDS - start_time))
28723
28724         kill -9 $setattr_pid
28725
28726         echo "rename $total files with 'touch' took $duration sec"
28727         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28728         (( duration <= max )) ||
28729                 error_not_in_vm "rename took $duration > $max sec"
28730 }
28731 run_test 415 "lock revoke is not missing"
28732
28733 test_416() {
28734         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28735                 skip "Need server version at least 2.11.55"
28736
28737         # define OBD_FAIL_OSD_TXN_START    0x19a
28738         do_facet mds1 lctl set_param fail_loc=0x19a
28739
28740         lfs mkdir -c $MDSCOUNT $DIR/$tdir
28741
28742         true
28743 }
28744 run_test 416 "transaction start failure won't cause system hung"
28745
28746 cleanup_417() {
28747         trap 0
28748         do_nodes $(comma_list $(mdts_nodes)) \
28749                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
28750         do_nodes $(comma_list $(mdts_nodes)) \
28751                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
28752         do_nodes $(comma_list $(mdts_nodes)) \
28753                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
28754 }
28755
28756 test_417() {
28757         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28758         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
28759                 skip "Need MDS version at least 2.11.56"
28760
28761         trap cleanup_417 RETURN EXIT
28762
28763         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
28764         do_nodes $(comma_list $(mdts_nodes)) \
28765                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
28766         $LFS migrate -m 0 $DIR/$tdir.1 &&
28767                 error "migrate dir $tdir.1 should fail"
28768
28769         do_nodes $(comma_list $(mdts_nodes)) \
28770                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
28771         $LFS mkdir -i 1 $DIR/$tdir.2 &&
28772                 error "create remote dir $tdir.2 should fail"
28773
28774         do_nodes $(comma_list $(mdts_nodes)) \
28775                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
28776         $LFS mkdir -c 2 $DIR/$tdir.3 &&
28777                 error "create striped dir $tdir.3 should fail"
28778         true
28779 }
28780 run_test 417 "disable remote dir, striped dir and dir migration"
28781
28782 # Checks that the outputs of df [-i] and lfs df [-i] match
28783 #
28784 # usage: check_lfs_df <blocks | inodes> <mountpoint>
28785 check_lfs_df() {
28786         local dir=$2
28787         local inodes
28788         local df_out
28789         local lfs_df_out
28790         local count
28791         local passed=false
28792
28793         # blocks or inodes
28794         [ "$1" == "blocks" ] && inodes= || inodes="-i"
28795
28796         for count in {1..100}; do
28797                 do_nodes "$CLIENTS" \
28798                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
28799                 sync; sleep 0.2
28800
28801                 # read the lines of interest
28802                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
28803                         error "df $inodes $dir | tail -n +2 failed"
28804                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
28805                         error "lfs df $inodes $dir | grep summary: failed"
28806
28807                 # skip first substrings of each output as they are different
28808                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
28809                 # compare the two outputs
28810                 passed=true
28811                 #  skip "available" on MDT until LU-13997 is fixed.
28812                 #for i in {1..5}; do
28813                 for i in 1 2 4 5; do
28814                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
28815                 done
28816                 $passed && break
28817         done
28818
28819         if ! $passed; then
28820                 df -P $inodes $dir
28821                 echo
28822                 lfs df $inodes $dir
28823                 error "df and lfs df $1 output mismatch: "      \
28824                       "df ${inodes}: ${df_out[*]}, "            \
28825                       "lfs df ${inodes}: ${lfs_df_out[*]}"
28826         fi
28827 }
28828
28829 test_418() {
28830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28831
28832         local dir=$DIR/$tdir
28833         local numfiles=$((RANDOM % 4096 + 2))
28834         local numblocks=$((RANDOM % 256 + 1))
28835
28836         wait_delete_completed
28837         test_mkdir $dir
28838
28839         # check block output
28840         check_lfs_df blocks $dir
28841         # check inode output
28842         check_lfs_df inodes $dir
28843
28844         # create a single file and retest
28845         echo "Creating a single file and testing"
28846         createmany -o $dir/$tfile- 1 &>/dev/null ||
28847                 error "creating 1 file in $dir failed"
28848         check_lfs_df blocks $dir
28849         check_lfs_df inodes $dir
28850
28851         # create a random number of files
28852         echo "Creating $((numfiles - 1)) files and testing"
28853         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
28854                 error "creating $((numfiles - 1)) files in $dir failed"
28855
28856         # write a random number of blocks to the first test file
28857         echo "Writing $numblocks 4K blocks and testing"
28858         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
28859                 count=$numblocks &>/dev/null ||
28860                 error "dd to $dir/${tfile}-0 failed"
28861
28862         # retest
28863         check_lfs_df blocks $dir
28864         check_lfs_df inodes $dir
28865
28866         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
28867                 error "unlinking $numfiles files in $dir failed"
28868 }
28869 run_test 418 "df and lfs df outputs match"
28870
28871 test_419()
28872 {
28873         local dir=$DIR/$tdir
28874
28875         mkdir -p $dir
28876         touch $dir/file
28877
28878         cancel_lru_locks mdc
28879
28880         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
28881         $LCTL set_param fail_loc=0x1410
28882         cat $dir/file
28883         $LCTL set_param fail_loc=0
28884         rm -rf $dir
28885 }
28886 run_test 419 "Verify open file by name doesn't crash kernel"
28887
28888 test_420()
28889 {
28890         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
28891                 skip "Need MDS version at least 2.12.53"
28892
28893         local SAVE_UMASK=$(umask)
28894         local dir=$DIR/$tdir
28895         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
28896
28897         mkdir -p $dir
28898         umask 0000
28899         mkdir -m03777 $dir/testdir
28900         ls -dn $dir/testdir
28901         # Need to remove trailing '.' when SELinux is enabled
28902         local dirperms=$(ls -dn $dir/testdir |
28903                          awk '{ sub(/\.$/, "", $1); print $1}')
28904         [ $dirperms == "drwxrwsrwt" ] ||
28905                 error "incorrect perms on $dir/testdir"
28906
28907         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
28908                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
28909         ls -n $dir/testdir/testfile
28910         local fileperms=$(ls -n $dir/testdir/testfile |
28911                           awk '{ sub(/\.$/, "", $1); print $1}')
28912         [ $fileperms == "-rwxr-xr-x" ] ||
28913                 error "incorrect perms on $dir/testdir/testfile"
28914
28915         umask $SAVE_UMASK
28916 }
28917 run_test 420 "clear SGID bit on non-directories for non-members"
28918
28919 test_421a() {
28920         local cnt
28921         local fid1
28922         local fid2
28923
28924         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28925                 skip "Need MDS version at least 2.12.54"
28926
28927         test_mkdir $DIR/$tdir
28928         createmany -o $DIR/$tdir/f 3
28929         cnt=$(ls -1 $DIR/$tdir | wc -l)
28930         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28931
28932         fid1=$(lfs path2fid $DIR/$tdir/f1)
28933         fid2=$(lfs path2fid $DIR/$tdir/f2)
28934         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
28935
28936         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
28937         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
28938
28939         cnt=$(ls -1 $DIR/$tdir | wc -l)
28940         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28941
28942         rm -f $DIR/$tdir/f3 || error "can't remove f3"
28943         createmany -o $DIR/$tdir/f 3
28944         cnt=$(ls -1 $DIR/$tdir | wc -l)
28945         [ $cnt != 3 ] && error "unexpected #files: $cnt"
28946
28947         fid1=$(lfs path2fid $DIR/$tdir/f1)
28948         fid2=$(lfs path2fid $DIR/$tdir/f2)
28949         echo "remove using fsname $FSNAME"
28950         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
28951
28952         cnt=$(ls -1 $DIR/$tdir | wc -l)
28953         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
28954 }
28955 run_test 421a "simple rm by fid"
28956
28957 test_421b() {
28958         local cnt
28959         local FID1
28960         local FID2
28961
28962         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28963                 skip "Need MDS version at least 2.12.54"
28964
28965         test_mkdir $DIR/$tdir
28966         createmany -o $DIR/$tdir/f 3
28967         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
28968         MULTIPID=$!
28969
28970         FID1=$(lfs path2fid $DIR/$tdir/f1)
28971         FID2=$(lfs path2fid $DIR/$tdir/f2)
28972         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
28973
28974         kill -USR1 $MULTIPID
28975         wait
28976
28977         cnt=$(ls $DIR/$tdir | wc -l)
28978         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
28979 }
28980 run_test 421b "rm by fid on open file"
28981
28982 test_421c() {
28983         local cnt
28984         local FIDS
28985
28986         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
28987                 skip "Need MDS version at least 2.12.54"
28988
28989         test_mkdir $DIR/$tdir
28990         createmany -o $DIR/$tdir/f 3
28991         touch $DIR/$tdir/$tfile
28992         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
28993         cnt=$(ls -1 $DIR/$tdir | wc -l)
28994         [ $cnt != 184 ] && error "unexpected #files: $cnt"
28995
28996         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
28997         $LFS rmfid $DIR $FID1 || error "rmfid failed"
28998
28999         cnt=$(ls $DIR/$tdir | wc -l)
29000         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29001 }
29002 run_test 421c "rm by fid against hardlinked files"
29003
29004 test_421d() {
29005         local cnt
29006         local FIDS
29007
29008         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29009                 skip "Need MDS version at least 2.12.54"
29010
29011         test_mkdir $DIR/$tdir
29012         createmany -o $DIR/$tdir/f 4097
29013         cnt=$(ls -1 $DIR/$tdir | wc -l)
29014         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29015
29016         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29017         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29018
29019         cnt=$(ls $DIR/$tdir | wc -l)
29020         rm -rf $DIR/$tdir
29021         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29022 }
29023 run_test 421d "rmfid en masse"
29024
29025 test_421e() {
29026         local cnt
29027         local FID
29028
29029         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29030         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29031                 skip "Need MDS version at least 2.12.54"
29032
29033         mkdir -p $DIR/$tdir
29034         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29035         createmany -o $DIR/$tdir/striped_dir/f 512
29036         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29037         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29038
29039         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29040                 sed "s/[/][^:]*://g")
29041         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29042
29043         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29044         rm -rf $DIR/$tdir
29045         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29046 }
29047 run_test 421e "rmfid in DNE"
29048
29049 test_421f() {
29050         local cnt
29051         local FID
29052
29053         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29054                 skip "Need MDS version at least 2.12.54"
29055
29056         test_mkdir $DIR/$tdir
29057         touch $DIR/$tdir/f
29058         cnt=$(ls -1 $DIR/$tdir | wc -l)
29059         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29060
29061         FID=$(lfs path2fid $DIR/$tdir/f)
29062         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29063         # rmfid should fail
29064         cnt=$(ls -1 $DIR/$tdir | wc -l)
29065         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29066
29067         chmod a+rw $DIR/$tdir
29068         ls -la $DIR/$tdir
29069         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29070         # rmfid should fail
29071         cnt=$(ls -1 $DIR/$tdir | wc -l)
29072         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29073
29074         rm -f $DIR/$tdir/f
29075         $RUNAS touch $DIR/$tdir/f
29076         FID=$(lfs path2fid $DIR/$tdir/f)
29077         echo "rmfid as root"
29078         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29079         cnt=$(ls -1 $DIR/$tdir | wc -l)
29080         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29081
29082         rm -f $DIR/$tdir/f
29083         $RUNAS touch $DIR/$tdir/f
29084         cnt=$(ls -1 $DIR/$tdir | wc -l)
29085         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29086         FID=$(lfs path2fid $DIR/$tdir/f)
29087         # rmfid w/o user_fid2path mount option should fail
29088         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29089         cnt=$(ls -1 $DIR/$tdir | wc -l)
29090         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29091
29092         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29093         stack_trap "rmdir $tmpdir"
29094         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29095                 error "failed to mount client'"
29096         stack_trap "umount_client $tmpdir"
29097
29098         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29099         # rmfid should succeed
29100         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29101         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29102
29103         # rmfid shouldn't allow to remove files due to dir's permission
29104         chmod a+rwx $tmpdir/$tdir
29105         touch $tmpdir/$tdir/f
29106         ls -la $tmpdir/$tdir
29107         FID=$(lfs path2fid $tmpdir/$tdir/f)
29108         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29109         return 0
29110 }
29111 run_test 421f "rmfid checks permissions"
29112
29113 test_421g() {
29114         local cnt
29115         local FIDS
29116
29117         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29118         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29119                 skip "Need MDS version at least 2.12.54"
29120
29121         mkdir -p $DIR/$tdir
29122         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29123         createmany -o $DIR/$tdir/striped_dir/f 512
29124         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29125         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29126
29127         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29128                 sed "s/[/][^:]*://g")
29129
29130         rm -f $DIR/$tdir/striped_dir/f1*
29131         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29132         removed=$((512 - cnt))
29133
29134         # few files have been just removed, so we expect
29135         # rmfid to fail on their fids
29136         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29137         [ $removed != $errors ] && error "$errors != $removed"
29138
29139         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29140         rm -rf $DIR/$tdir
29141         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29142 }
29143 run_test 421g "rmfid to return errors properly"
29144
29145 test_421h() {
29146         local mount_other
29147         local mount_ret
29148         local rmfid_ret
29149         local old_fid
29150         local fidA
29151         local fidB
29152         local fidC
29153         local fidD
29154
29155         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29156                 skip "Need MDS version at least 2.15.53"
29157
29158         test_mkdir $DIR/$tdir
29159         test_mkdir $DIR/$tdir/subdir
29160         touch $DIR/$tdir/subdir/file0
29161         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29162         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29163         rm -f $DIR/$tdir/subdir/file0
29164         touch $DIR/$tdir/subdir/fileA
29165         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29166         echo File $DIR/$tdir/subdir/fileA FID $fidA
29167         touch $DIR/$tdir/subdir/fileB
29168         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29169         echo File $DIR/$tdir/subdir/fileB FID $fidB
29170         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29171         touch $DIR/$tdir/subdir/fileC
29172         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29173         echo File $DIR/$tdir/subdir/fileC FID $fidC
29174         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29175         touch $DIR/$tdir/fileD
29176         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29177         echo File $DIR/$tdir/fileD FID $fidD
29178
29179         # mount another client mount point with subdirectory mount
29180         export FILESET=/$tdir/subdir
29181         mount_other=${MOUNT}_other
29182         mount_client $mount_other ${MOUNT_OPTS}
29183         mount_ret=$?
29184         export FILESET=""
29185         (( mount_ret == 0 )) || error "mount $mount_other failed"
29186
29187         echo Removing FIDs:
29188         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29189         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29190         rmfid_ret=$?
29191
29192         umount_client $mount_other || error "umount $mount_other failed"
29193
29194         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29195
29196         # fileA should have been deleted
29197         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29198
29199         # fileB should have been deleted
29200         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29201
29202         # fileC should not have been deleted, fid also exists outside of fileset
29203         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29204
29205         # fileD should not have been deleted, it exists outside of fileset
29206         stat $DIR/$tdir/fileD || error "fileD deleted"
29207 }
29208 run_test 421h "rmfid with fileset mount"
29209
29210 test_422() {
29211         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29212         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29213         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29214         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29215         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29216
29217         local amc=$(at_max_get client)
29218         local amo=$(at_max_get mds1)
29219         local timeout=`lctl get_param -n timeout`
29220
29221         at_max_set 0 client
29222         at_max_set 0 mds1
29223
29224 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29225         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29226                         fail_val=$(((2*timeout + 10)*1000))
29227         touch $DIR/$tdir/d3/file &
29228         sleep 2
29229 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29230         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29231                         fail_val=$((2*timeout + 5))
29232         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29233         local pid=$!
29234         sleep 1
29235         kill -9 $pid
29236         sleep $((2 * timeout))
29237         echo kill $pid
29238         kill -9 $pid
29239         lctl mark touch
29240         touch $DIR/$tdir/d2/file3
29241         touch $DIR/$tdir/d2/file4
29242         touch $DIR/$tdir/d2/file5
29243
29244         wait
29245         at_max_set $amc client
29246         at_max_set $amo mds1
29247
29248         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29249         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29250                 error "Watchdog is always throttled"
29251 }
29252 run_test 422 "kill a process with RPC in progress"
29253
29254 stat_test() {
29255     df -h $MOUNT &
29256     df -h $MOUNT &
29257     df -h $MOUNT &
29258     df -h $MOUNT &
29259     df -h $MOUNT &
29260     df -h $MOUNT &
29261 }
29262
29263 test_423() {
29264     local _stats
29265     # ensure statfs cache is expired
29266     sleep 2;
29267
29268     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29269     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29270
29271     return 0
29272 }
29273 run_test 423 "statfs should return a right data"
29274
29275 test_424() {
29276 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29277         $LCTL set_param fail_loc=0x80000522
29278         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29279         rm -f $DIR/$tfile
29280 }
29281 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29282
29283 test_425() {
29284         test_mkdir -c -1 $DIR/$tdir
29285         $LFS setstripe -c -1 $DIR/$tdir
29286
29287         lru_resize_disable "" 100
29288         stack_trap "lru_resize_enable" EXIT
29289
29290         sleep 5
29291
29292         for i in $(seq $((MDSCOUNT * 125))); do
29293                 local t=$DIR/$tdir/$tfile_$i
29294
29295                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29296                         error_noexit "Create file $t"
29297         done
29298         stack_trap "rm -rf $DIR/$tdir" EXIT
29299
29300         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29301                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29302                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29303
29304                 [ $lock_count -le $lru_size ] ||
29305                         error "osc lock count $lock_count > lru size $lru_size"
29306         done
29307
29308         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29309                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29310                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29311
29312                 [ $lock_count -le $lru_size ] ||
29313                         error "mdc lock count $lock_count > lru size $lru_size"
29314         done
29315 }
29316 run_test 425 "lock count should not exceed lru size"
29317
29318 test_426() {
29319         splice-test -r $DIR/$tfile
29320         splice-test -rd $DIR/$tfile
29321         splice-test $DIR/$tfile
29322         splice-test -d $DIR/$tfile
29323 }
29324 run_test 426 "splice test on Lustre"
29325
29326 test_427() {
29327         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29328         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29329                 skip "Need MDS version at least 2.12.4"
29330         local log
29331
29332         mkdir $DIR/$tdir
29333         mkdir $DIR/$tdir/1
29334         mkdir $DIR/$tdir/2
29335         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29336         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29337
29338         $LFS getdirstripe $DIR/$tdir/1/dir
29339
29340         #first setfattr for creating updatelog
29341         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29342
29343 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29344         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29345         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29346         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29347
29348         sleep 2
29349         fail mds2
29350         wait_recovery_complete mds2 $((2*TIMEOUT))
29351
29352         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29353         echo $log | grep "get update log failed" &&
29354                 error "update log corruption is detected" || true
29355 }
29356 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29357
29358 test_428() {
29359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29360         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29361                               awk '/^max_cached_mb/ { print $2 }')
29362         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29363
29364         $LCTL set_param -n llite.*.max_cached_mb=64
29365
29366         mkdir $DIR/$tdir
29367         $LFS setstripe -c 1 $DIR/$tdir
29368         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29369         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29370         #test write
29371         for f in $(seq 4); do
29372                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29373         done
29374         wait
29375
29376         cancel_lru_locks osc
29377         # Test read
29378         for f in $(seq 4); do
29379                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29380         done
29381         wait
29382 }
29383 run_test 428 "large block size IO should not hang"
29384
29385 test_429() { # LU-7915 / LU-10948
29386         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29387         local testfile=$DIR/$tfile
29388         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29389         local new_flag=1
29390         local first_rpc
29391         local second_rpc
29392         local third_rpc
29393
29394         $LCTL get_param $ll_opencache_threshold_count ||
29395                 skip "client does not have opencache parameter"
29396
29397         set_opencache $new_flag
29398         stack_trap "restore_opencache"
29399         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29400                 error "enable opencache failed"
29401         touch $testfile
29402         # drop MDC DLM locks
29403         cancel_lru_locks mdc
29404         # clear MDC RPC stats counters
29405         $LCTL set_param $mdc_rpcstats=clear
29406
29407         # According to the current implementation, we need to run 3 times
29408         # open & close file to verify if opencache is enabled correctly.
29409         # 1st, RPCs are sent for lookup/open and open handle is released on
29410         #      close finally.
29411         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29412         #      so open handle won't be released thereafter.
29413         # 3rd, No RPC is sent out.
29414         $MULTIOP $testfile oc || error "multiop failed"
29415         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29416         echo "1st: $first_rpc RPCs in flight"
29417
29418         $MULTIOP $testfile oc || error "multiop failed"
29419         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29420         echo "2nd: $second_rpc RPCs in flight"
29421
29422         $MULTIOP $testfile oc || error "multiop failed"
29423         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29424         echo "3rd: $third_rpc RPCs in flight"
29425
29426         #verify no MDC RPC is sent
29427         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29428 }
29429 run_test 429 "verify if opencache flag on client side does work"
29430
29431 lseek_test_430() {
29432         local offset
29433         local file=$1
29434
29435         # data at [200K, 400K)
29436         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29437                 error "256K->512K dd fails"
29438         # data at [2M, 3M)
29439         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29440                 error "2M->3M dd fails"
29441         # data at [4M, 5M)
29442         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29443                 error "4M->5M dd fails"
29444         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29445         # start at first component hole #1
29446         printf "Seeking hole from 1000 ... "
29447         offset=$(lseek_test -l 1000 $file)
29448         echo $offset
29449         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29450         printf "Seeking data from 1000 ... "
29451         offset=$(lseek_test -d 1000 $file)
29452         echo $offset
29453         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29454
29455         # start at first component data block
29456         printf "Seeking hole from 300000 ... "
29457         offset=$(lseek_test -l 300000 $file)
29458         echo $offset
29459         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29460         printf "Seeking data from 300000 ... "
29461         offset=$(lseek_test -d 300000 $file)
29462         echo $offset
29463         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29464
29465         # start at the first component but beyond end of object size
29466         printf "Seeking hole from 1000000 ... "
29467         offset=$(lseek_test -l 1000000 $file)
29468         echo $offset
29469         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29470         printf "Seeking data from 1000000 ... "
29471         offset=$(lseek_test -d 1000000 $file)
29472         echo $offset
29473         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29474
29475         # start at second component stripe 2 (empty file)
29476         printf "Seeking hole from 1500000 ... "
29477         offset=$(lseek_test -l 1500000 $file)
29478         echo $offset
29479         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29480         printf "Seeking data from 1500000 ... "
29481         offset=$(lseek_test -d 1500000 $file)
29482         echo $offset
29483         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29484
29485         # start at second component stripe 1 (all data)
29486         printf "Seeking hole from 3000000 ... "
29487         offset=$(lseek_test -l 3000000 $file)
29488         echo $offset
29489         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29490         printf "Seeking data from 3000000 ... "
29491         offset=$(lseek_test -d 3000000 $file)
29492         echo $offset
29493         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29494
29495         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29496                 error "2nd dd fails"
29497         echo "Add data block at 640K...1280K"
29498
29499         # start at before new data block, in hole
29500         printf "Seeking hole from 600000 ... "
29501         offset=$(lseek_test -l 600000 $file)
29502         echo $offset
29503         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29504         printf "Seeking data from 600000 ... "
29505         offset=$(lseek_test -d 600000 $file)
29506         echo $offset
29507         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29508
29509         # start at the first component new data block
29510         printf "Seeking hole from 1000000 ... "
29511         offset=$(lseek_test -l 1000000 $file)
29512         echo $offset
29513         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29514         printf "Seeking data from 1000000 ... "
29515         offset=$(lseek_test -d 1000000 $file)
29516         echo $offset
29517         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29518
29519         # start at second component stripe 2, new data
29520         printf "Seeking hole from 1200000 ... "
29521         offset=$(lseek_test -l 1200000 $file)
29522         echo $offset
29523         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29524         printf "Seeking data from 1200000 ... "
29525         offset=$(lseek_test -d 1200000 $file)
29526         echo $offset
29527         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29528
29529         # start beyond file end
29530         printf "Using offset > filesize ... "
29531         lseek_test -l 4000000 $file && error "lseek should fail"
29532         printf "Using offset > filesize ... "
29533         lseek_test -d 4000000 $file && error "lseek should fail"
29534
29535         printf "Done\n\n"
29536 }
29537
29538 test_430a() {
29539         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29540                 skip "MDT does not support SEEK_HOLE"
29541
29542         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29543                 skip "OST does not support SEEK_HOLE"
29544
29545         local file=$DIR/$tdir/$tfile
29546
29547         mkdir -p $DIR/$tdir
29548
29549         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29550         # OST stripe #1 will have continuous data at [1M, 3M)
29551         # OST stripe #2 is empty
29552         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29553         lseek_test_430 $file
29554         rm $file
29555         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29556         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29557         lseek_test_430 $file
29558         rm $file
29559         $LFS setstripe -c2 -S 512K $file
29560         echo "Two stripes, stripe size 512K"
29561         lseek_test_430 $file
29562         rm $file
29563         # FLR with stale mirror
29564         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29565                        -N -c2 -S 1M $file
29566         echo "Mirrored file:"
29567         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29568         echo "Plain 2 stripes 1M"
29569         lseek_test_430 $file
29570         rm $file
29571 }
29572 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29573
29574 test_430b() {
29575         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29576                 skip "OST does not support SEEK_HOLE"
29577
29578         local offset
29579         local file=$DIR/$tdir/$tfile
29580
29581         mkdir -p $DIR/$tdir
29582         # Empty layout lseek should fail
29583         $MCREATE $file
29584         # seek from 0
29585         printf "Seeking hole from 0 ... "
29586         lseek_test -l 0 $file && error "lseek should fail"
29587         printf "Seeking data from 0 ... "
29588         lseek_test -d 0 $file && error "lseek should fail"
29589         rm $file
29590
29591         # 1M-hole file
29592         $LFS setstripe -E 1M -c2 -E eof $file
29593         $TRUNCATE $file 1048576
29594         printf "Seeking hole from 1000000 ... "
29595         offset=$(lseek_test -l 1000000 $file)
29596         echo $offset
29597         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29598         printf "Seeking data from 1000000 ... "
29599         lseek_test -d 1000000 $file && error "lseek should fail"
29600         rm $file
29601
29602         # full component followed by non-inited one
29603         $LFS setstripe -E 1M -c2 -E eof $file
29604         dd if=/dev/urandom of=$file bs=1M count=1
29605         printf "Seeking hole from 1000000 ... "
29606         offset=$(lseek_test -l 1000000 $file)
29607         echo $offset
29608         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29609         printf "Seeking hole from 1048576 ... "
29610         lseek_test -l 1048576 $file && error "lseek should fail"
29611         # init second component and truncate back
29612         echo "123" >> $file
29613         $TRUNCATE $file 1048576
29614         printf "Seeking hole from 1000000 ... "
29615         offset=$(lseek_test -l 1000000 $file)
29616         echo $offset
29617         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29618         printf "Seeking hole from 1048576 ... "
29619         lseek_test -l 1048576 $file && error "lseek should fail"
29620         # boundary checks for big values
29621         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29622         offset=$(lseek_test -d 0 $file.10g)
29623         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29624         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29625         offset=$(lseek_test -d 0 $file.100g)
29626         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29627         return 0
29628 }
29629 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29630
29631 test_430c() {
29632         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29633                 skip "OST does not support SEEK_HOLE"
29634
29635         local file=$DIR/$tdir/$tfile
29636         local start
29637
29638         mkdir -p $DIR/$tdir
29639         stack_trap "rm -f $file $file.tmp"
29640         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29641
29642         # cp version 8.33+ prefers lseek over fiemap
29643         local ver=$(cp --version | awk '{ print $4; exit; }')
29644
29645         echo "cp $ver installed"
29646         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29647                 start=$SECONDS
29648                 time cp -v $file $file.tmp || error "cp $file failed"
29649                 (( SECONDS - start < 5 )) || {
29650                         strace cp $file $file.tmp |&
29651                                 grep -E "open|read|seek|FIEMAP" |
29652                                 grep -A 100 $file
29653                         error "cp: too long runtime $((SECONDS - start))"
29654                 }
29655         else
29656                 echo "cp test skipped due to $ver < 8.33"
29657         fi
29658
29659         # tar version 1.29+ supports SEEK_HOLE/DATA
29660         ver=$(tar --version | awk '{ print $4; exit; }')
29661         echo "tar $ver installed"
29662         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29663                 start=$SECONDS
29664                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29665                 (( SECONDS - start < 5 )) || {
29666                         strace tar cf $file.tmp --sparse $file |&
29667                                 grep -E "open|read|seek|FIEMAP" |
29668                                 grep -A 100 $file
29669                         error "tar: too long runtime $((SECONDS - start))"
29670                 }
29671         else
29672                 echo "tar test skipped due to $ver < 1.29"
29673         fi
29674 }
29675 run_test 430c "lseek: external tools check"
29676
29677 test_431() { # LU-14187
29678         local file=$DIR/$tdir/$tfile
29679
29680         mkdir -p $DIR/$tdir
29681         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29682         dd if=/dev/urandom of=$file bs=4k count=1
29683         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29684         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29685         #define OBD_FAIL_OST_RESTART_IO 0x251
29686         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29687         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29688         cp $file $file.0
29689         cancel_lru_locks
29690         sync_all_data
29691         echo 3 > /proc/sys/vm/drop_caches
29692         diff  $file $file.0 || error "data diff"
29693 }
29694 run_test 431 "Restart transaction for IO"
29695
29696 cleanup_test_432() {
29697         do_facet mgs $LCTL nodemap_activate 0
29698         wait_nm_sync active
29699 }
29700
29701 test_432() {
29702         local tmpdir=$TMP/dir432
29703
29704         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29705                 skip "Need MDS version at least 2.14.52"
29706
29707         stack_trap cleanup_test_432 EXIT
29708         mkdir $DIR/$tdir
29709         mkdir $tmpdir
29710
29711         do_facet mgs $LCTL nodemap_activate 1
29712         wait_nm_sync active
29713         do_facet mgs $LCTL nodemap_modify --name default \
29714                 --property admin --value 1
29715         do_facet mgs $LCTL nodemap_modify --name default \
29716                 --property trusted --value 1
29717         cancel_lru_locks mdc
29718         wait_nm_sync default admin_nodemap
29719         wait_nm_sync default trusted_nodemap
29720
29721         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29722                grep -ci "Operation not permitted") -ne 0 ]; then
29723                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29724         fi
29725 }
29726 run_test 432 "mv dir from outside Lustre"
29727
29728 test_433() {
29729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29730
29731         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29732                 skip "inode cache not supported"
29733
29734         $LCTL set_param llite.*.inode_cache=0
29735         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29736
29737         local count=256
29738         local before
29739         local after
29740
29741         cancel_lru_locks mdc
29742         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29743         createmany -m $DIR/$tdir/f $count
29744         createmany -d $DIR/$tdir/d $count
29745         ls -l $DIR/$tdir > /dev/null
29746         stack_trap "rm -rf $DIR/$tdir"
29747
29748         before=$(num_objects)
29749         cancel_lru_locks mdc
29750         after=$(num_objects)
29751
29752         # sometimes even @before is less than 2 * count
29753         while (( before - after < count )); do
29754                 sleep 1
29755                 after=$(num_objects)
29756                 wait=$((wait + 1))
29757                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
29758                 if (( wait > 60 )); then
29759                         error "inode slab grew from $before to $after"
29760                 fi
29761         done
29762
29763         echo "lustre_inode_cache $before objs before lock cancel, $after after"
29764 }
29765 run_test 433 "ldlm lock cancel releases dentries and inodes"
29766
29767 test_434() {
29768         local file
29769         local getxattr_count
29770         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
29771         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29772
29773         [[ $(getenforce) == "Disabled" ]] ||
29774                 skip "lsm selinux module have to be disabled for this test"
29775
29776         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
29777                 error "fail to create $DIR/$tdir/ on MDT0000"
29778
29779         touch $DIR/$tdir/$tfile-{001..100}
29780
29781         # disable the xattr cache
29782         save_lustre_params client "llite.*.xattr_cache" > $p
29783         lctl set_param llite.*.xattr_cache=0
29784         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
29785
29786         # clear clients mdc stats
29787         clear_stats $mdc_stat_param ||
29788                 error "fail to clear stats on mdc MDT0000"
29789
29790         for file in $DIR/$tdir/$tfile-{001..100}; do
29791                 getfattr -n security.selinux $file |&
29792                         grep -q "Operation not supported" ||
29793                         error "getxattr on security.selinux should return EOPNOTSUPP"
29794         done
29795
29796         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
29797         (( getxattr_count < 100 )) ||
29798                 error "client sent $getxattr_count getxattr RPCs to the MDS"
29799 }
29800 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
29801
29802 test_440() {
29803         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
29804                 source $LUSTRE/scripts/bash-completion/lustre
29805         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
29806                 source /usr/share/bash-completion/completions/lustre
29807         else
29808                 skip "bash completion scripts not found"
29809         fi
29810
29811         local lctl_completions
29812         local lfs_completions
29813
29814         lctl_completions=$(_lustre_cmds lctl)
29815         if [[ ! $lctl_completions =~ "get_param" ]]; then
29816                 error "lctl bash completion failed"
29817         fi
29818
29819         lfs_completions=$(_lustre_cmds lfs)
29820         if [[ ! $lfs_completions =~ "setstripe" ]]; then
29821                 error "lfs bash completion failed"
29822         fi
29823 }
29824 run_test 440 "bash completion for lfs, lctl"
29825
29826 prep_801() {
29827         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
29828         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
29829                 skip "Need server version at least 2.9.55"
29830
29831         start_full_debug_logging
29832 }
29833
29834 post_801() {
29835         stop_full_debug_logging
29836 }
29837
29838 barrier_stat() {
29839         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29840                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29841                            awk '/The barrier for/ { print $7 }')
29842                 echo $st
29843         else
29844                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
29845                 echo \'$st\'
29846         fi
29847 }
29848
29849 barrier_expired() {
29850         local expired
29851
29852         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
29853                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
29854                           awk '/will be expired/ { print $7 }')
29855         else
29856                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
29857         fi
29858
29859         echo $expired
29860 }
29861
29862 test_801a() {
29863         prep_801
29864
29865         echo "Start barrier_freeze at: $(date)"
29866         #define OBD_FAIL_BARRIER_DELAY          0x2202
29867         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29868         # Do not reduce barrier time - See LU-11873
29869         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
29870
29871         sleep 2
29872         local b_status=$(barrier_stat)
29873         echo "Got barrier status at: $(date)"
29874         [ "$b_status" = "'freezing_p1'" ] ||
29875                 error "(1) unexpected barrier status $b_status"
29876
29877         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29878         wait
29879         b_status=$(barrier_stat)
29880         [ "$b_status" = "'frozen'" ] ||
29881                 error "(2) unexpected barrier status $b_status"
29882
29883         local expired=$(barrier_expired)
29884         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
29885         sleep $((expired + 3))
29886
29887         b_status=$(barrier_stat)
29888         [ "$b_status" = "'expired'" ] ||
29889                 error "(3) unexpected barrier status $b_status"
29890
29891         # Do not reduce barrier time - See LU-11873
29892         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
29893                 error "(4) fail to freeze barrier"
29894
29895         b_status=$(barrier_stat)
29896         [ "$b_status" = "'frozen'" ] ||
29897                 error "(5) unexpected barrier status $b_status"
29898
29899         echo "Start barrier_thaw at: $(date)"
29900         #define OBD_FAIL_BARRIER_DELAY          0x2202
29901         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
29902         do_facet mgs $LCTL barrier_thaw $FSNAME &
29903
29904         sleep 2
29905         b_status=$(barrier_stat)
29906         echo "Got barrier status at: $(date)"
29907         [ "$b_status" = "'thawing'" ] ||
29908                 error "(6) unexpected barrier status $b_status"
29909
29910         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
29911         wait
29912         b_status=$(barrier_stat)
29913         [ "$b_status" = "'thawed'" ] ||
29914                 error "(7) unexpected barrier status $b_status"
29915
29916         #define OBD_FAIL_BARRIER_FAILURE        0x2203
29917         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
29918         do_facet mgs $LCTL barrier_freeze $FSNAME
29919
29920         b_status=$(barrier_stat)
29921         [ "$b_status" = "'failed'" ] ||
29922                 error "(8) unexpected barrier status $b_status"
29923
29924         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
29925         do_facet mgs $LCTL barrier_thaw $FSNAME
29926
29927         post_801
29928 }
29929 run_test 801a "write barrier user interfaces and stat machine"
29930
29931 test_801b() {
29932         prep_801
29933
29934         mkdir $DIR/$tdir || error "(1) fail to mkdir"
29935         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
29936         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
29937         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
29938         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
29939
29940         cancel_lru_locks mdc
29941
29942         # 180 seconds should be long enough
29943         do_facet mgs $LCTL barrier_freeze $FSNAME 180
29944
29945         local b_status=$(barrier_stat)
29946         [ "$b_status" = "'frozen'" ] ||
29947                 error "(6) unexpected barrier status $b_status"
29948
29949         mkdir $DIR/$tdir/d0/d10 &
29950         mkdir_pid=$!
29951
29952         touch $DIR/$tdir/d1/f13 &
29953         touch_pid=$!
29954
29955         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
29956         ln_pid=$!
29957
29958         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
29959         mv_pid=$!
29960
29961         rm -f $DIR/$tdir/d4/f12 &
29962         rm_pid=$!
29963
29964         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
29965
29966         # To guarantee taht the 'stat' is not blocked
29967         b_status=$(barrier_stat)
29968         [ "$b_status" = "'frozen'" ] ||
29969                 error "(8) unexpected barrier status $b_status"
29970
29971         # let above commands to run at background
29972         sleep 5
29973
29974         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
29975         ps -p $touch_pid || error "(10) touch should be blocked"
29976         ps -p $ln_pid || error "(11) link should be blocked"
29977         ps -p $mv_pid || error "(12) rename should be blocked"
29978         ps -p $rm_pid || error "(13) unlink should be blocked"
29979
29980         b_status=$(barrier_stat)
29981         [ "$b_status" = "'frozen'" ] ||
29982                 error "(14) unexpected barrier status $b_status"
29983
29984         do_facet mgs $LCTL barrier_thaw $FSNAME
29985         b_status=$(barrier_stat)
29986         [ "$b_status" = "'thawed'" ] ||
29987                 error "(15) unexpected barrier status $b_status"
29988
29989         wait $mkdir_pid || error "(16) mkdir should succeed"
29990         wait $touch_pid || error "(17) touch should succeed"
29991         wait $ln_pid || error "(18) link should succeed"
29992         wait $mv_pid || error "(19) rename should succeed"
29993         wait $rm_pid || error "(20) unlink should succeed"
29994
29995         post_801
29996 }
29997 run_test 801b "modification will be blocked by write barrier"
29998
29999 test_801c() {
30000         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30001
30002         prep_801
30003
30004         stop mds2 || error "(1) Fail to stop mds2"
30005
30006         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30007
30008         local b_status=$(barrier_stat)
30009         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30010                 do_facet mgs $LCTL barrier_thaw $FSNAME
30011                 error "(2) unexpected barrier status $b_status"
30012         }
30013
30014         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30015                 error "(3) Fail to rescan barrier bitmap"
30016
30017         # Do not reduce barrier time - See LU-11873
30018         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30019
30020         b_status=$(barrier_stat)
30021         [ "$b_status" = "'frozen'" ] ||
30022                 error "(4) unexpected barrier status $b_status"
30023
30024         do_facet mgs $LCTL barrier_thaw $FSNAME
30025         b_status=$(barrier_stat)
30026         [ "$b_status" = "'thawed'" ] ||
30027                 error "(5) unexpected barrier status $b_status"
30028
30029         local devname=$(mdsdevname 2)
30030
30031         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30032
30033         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30034                 error "(7) Fail to rescan barrier bitmap"
30035
30036         post_801
30037 }
30038 run_test 801c "rescan barrier bitmap"
30039
30040 test_802b() {
30041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30042         remote_mds_nodsh && skip "remote MDS with nodsh"
30043
30044         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30045                 skip "readonly option not available"
30046
30047         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30048
30049         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30050                 error "(2) Fail to copy"
30051
30052         # write back all cached data before setting MDT to readonly
30053         cancel_lru_locks
30054         sync_all_data
30055
30056         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30057         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30058
30059         echo "Modify should be refused"
30060         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30061
30062         echo "Read should be allowed"
30063         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30064                 error "(7) Read should succeed under ro mode"
30065
30066         # disable readonly
30067         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30068 }
30069 run_test 802b "be able to set MDTs to readonly"
30070
30071 test_803a() {
30072         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30073         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30074                 skip "MDS needs to be newer than 2.10.54"
30075
30076         mkdir_on_mdt0 $DIR/$tdir
30077         # Create some objects on all MDTs to trigger related logs objects
30078         for idx in $(seq $MDSCOUNT); do
30079                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30080                         $DIR/$tdir/dir${idx} ||
30081                         error "Fail to create $DIR/$tdir/dir${idx}"
30082         done
30083
30084         wait_delete_completed # ensure old test cleanups are finished
30085         sleep 3
30086         echo "before create:"
30087         $LFS df -i $MOUNT
30088         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30089
30090         for i in {1..10}; do
30091                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30092                         error "Fail to create $DIR/$tdir/foo$i"
30093         done
30094
30095         # sync ZFS-on-MDS to refresh statfs data
30096         wait_zfs_commit mds1
30097         sleep 3
30098         echo "after create:"
30099         $LFS df -i $MOUNT
30100         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30101
30102         # allow for an llog to be cleaned up during the test
30103         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30104                 error "before ($before_used) + 10 > after ($after_used)"
30105
30106         for i in {1..10}; do
30107                 rm -rf $DIR/$tdir/foo$i ||
30108                         error "Fail to remove $DIR/$tdir/foo$i"
30109         done
30110
30111         # sync ZFS-on-MDS to refresh statfs data
30112         wait_zfs_commit mds1
30113         wait_delete_completed
30114         sleep 3 # avoid MDT return cached statfs
30115         echo "after unlink:"
30116         $LFS df -i $MOUNT
30117         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30118
30119         # allow for an llog to be created during the test
30120         [ $after_used -le $((before_used + 1)) ] ||
30121                 error "after ($after_used) > before ($before_used) + 1"
30122 }
30123 run_test 803a "verify agent object for remote object"
30124
30125 test_803b() {
30126         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30127         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30128                 skip "MDS needs to be newer than 2.13.56"
30129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30130
30131         for i in $(seq 0 $((MDSCOUNT - 1))); do
30132                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30133         done
30134
30135         local before=0
30136         local after=0
30137
30138         local tmp
30139
30140         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30141         for i in $(seq 0 $((MDSCOUNT - 1))); do
30142                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30143                         awk '/getattr/ { print $2 }')
30144                 before=$((before + tmp))
30145         done
30146         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30147         for i in $(seq 0 $((MDSCOUNT - 1))); do
30148                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30149                         awk '/getattr/ { print $2 }')
30150                 after=$((after + tmp))
30151         done
30152
30153         [ $before -eq $after ] || error "getattr count $before != $after"
30154 }
30155 run_test 803b "remote object can getattr from cache"
30156
30157 test_804() {
30158         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30159         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30160                 skip "MDS needs to be newer than 2.10.54"
30161         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30162
30163         mkdir -p $DIR/$tdir
30164         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30165                 error "Fail to create $DIR/$tdir/dir0"
30166
30167         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30168         local dev=$(mdsdevname 2)
30169
30170         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30171                 grep ${fid} || error "NOT found agent entry for dir0"
30172
30173         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30174                 error "Fail to create $DIR/$tdir/dir1"
30175
30176         touch $DIR/$tdir/dir1/foo0 ||
30177                 error "Fail to create $DIR/$tdir/dir1/foo0"
30178         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30179         local rc=0
30180
30181         for idx in $(seq $MDSCOUNT); do
30182                 dev=$(mdsdevname $idx)
30183                 do_facet mds${idx} \
30184                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30185                         grep ${fid} && rc=$idx
30186         done
30187
30188         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30189                 error "Fail to rename foo0 to foo1"
30190         if [ $rc -eq 0 ]; then
30191                 for idx in $(seq $MDSCOUNT); do
30192                         dev=$(mdsdevname $idx)
30193                         do_facet mds${idx} \
30194                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30195                         grep ${fid} && rc=$idx
30196                 done
30197         fi
30198
30199         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30200                 error "Fail to rename foo1 to foo2"
30201         if [ $rc -eq 0 ]; then
30202                 for idx in $(seq $MDSCOUNT); do
30203                         dev=$(mdsdevname $idx)
30204                         do_facet mds${idx} \
30205                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30206                         grep ${fid} && rc=$idx
30207                 done
30208         fi
30209
30210         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30211
30212         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30213                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30214         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30215                 error "Fail to rename foo2 to foo0"
30216         unlink $DIR/$tdir/dir1/foo0 ||
30217                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30218         rm -rf $DIR/$tdir/dir0 ||
30219                 error "Fail to rm $DIR/$tdir/dir0"
30220
30221         for idx in $(seq $MDSCOUNT); do
30222                 rc=0
30223
30224                 stop mds${idx}
30225                 dev=$(mdsdevname $idx)
30226                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30227                         rc=$?
30228                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30229                         error "mount mds$idx failed"
30230                 df $MOUNT > /dev/null 2>&1
30231
30232                 # e2fsck should not return error
30233                 [ $rc -eq 0 ] ||
30234                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30235         done
30236 }
30237 run_test 804 "verify agent entry for remote entry"
30238
30239 cleanup_805() {
30240         do_facet $SINGLEMDS zfs set quota=$old $fsset
30241         unlinkmany $DIR/$tdir/f- 1000000
30242         trap 0
30243 }
30244
30245 test_805() {
30246         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30247         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30248         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30249                 skip "netfree not implemented before 0.7"
30250         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30251                 skip "Need MDS version at least 2.10.57"
30252
30253         local fsset
30254         local freekb
30255         local usedkb
30256         local old
30257         local quota
30258         local pref="osd-zfs.$FSNAME-MDT0000."
30259
30260         # limit available space on MDS dataset to meet nospace issue
30261         # quickly. then ZFS 0.7.2 can use reserved space if asked
30262         # properly (using netfree flag in osd_declare_destroy()
30263         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30264         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30265                 gawk '{print $3}')
30266         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30267         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30268         let "usedkb=usedkb-freekb"
30269         let "freekb=freekb/2"
30270         if let "freekb > 5000"; then
30271                 let "freekb=5000"
30272         fi
30273         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30274         trap cleanup_805 EXIT
30275         mkdir_on_mdt0 $DIR/$tdir
30276         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30277                 error "Can't set PFL layout"
30278         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30279         rm -rf $DIR/$tdir || error "not able to remove"
30280         do_facet $SINGLEMDS zfs set quota=$old $fsset
30281         trap 0
30282 }
30283 run_test 805 "ZFS can remove from full fs"
30284
30285 # Size-on-MDS test
30286 check_lsom_data()
30287 {
30288         local file=$1
30289         local expect=$(stat -c %s $file)
30290
30291         check_lsom_size $1 $expect
30292
30293         local blocks=$($LFS getsom -b $file)
30294         expect=$(stat -c %b $file)
30295         [[ $blocks == $expect ]] ||
30296                 error "$file expected blocks: $expect, got: $blocks"
30297 }
30298
30299 check_lsom_size()
30300 {
30301         local size
30302         local expect=$2
30303
30304         cancel_lru_locks mdc
30305
30306         size=$($LFS getsom -s $1)
30307         [[ $size == $expect ]] ||
30308                 error "$file expected size: $expect, got: $size"
30309 }
30310
30311 test_806() {
30312         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30313                 skip "Need MDS version at least 2.11.52"
30314
30315         local bs=1048576
30316
30317         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30318
30319         disable_opencache
30320         stack_trap "restore_opencache"
30321
30322         # single-threaded write
30323         echo "Test SOM for single-threaded write"
30324         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30325                 error "write $tfile failed"
30326         check_lsom_size $DIR/$tfile $bs
30327
30328         local num=32
30329         local size=$(($num * $bs))
30330         local offset=0
30331         local i
30332
30333         echo "Test SOM for single client multi-threaded($num) write"
30334         $TRUNCATE $DIR/$tfile 0
30335         for ((i = 0; i < $num; i++)); do
30336                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30337                 local pids[$i]=$!
30338                 offset=$((offset + $bs))
30339         done
30340         for (( i=0; i < $num; i++ )); do
30341                 wait ${pids[$i]}
30342         done
30343         check_lsom_size $DIR/$tfile $size
30344
30345         $TRUNCATE $DIR/$tfile 0
30346         for ((i = 0; i < $num; i++)); do
30347                 offset=$((offset - $bs))
30348                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30349                 local pids[$i]=$!
30350         done
30351         for (( i=0; i < $num; i++ )); do
30352                 wait ${pids[$i]}
30353         done
30354         check_lsom_size $DIR/$tfile $size
30355
30356         # multi-client writes
30357         num=$(get_node_count ${CLIENTS//,/ })
30358         size=$(($num * $bs))
30359         offset=0
30360         i=0
30361
30362         echo "Test SOM for multi-client ($num) writes"
30363         $TRUNCATE $DIR/$tfile 0
30364         for client in ${CLIENTS//,/ }; do
30365                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30366                 local pids[$i]=$!
30367                 i=$((i + 1))
30368                 offset=$((offset + $bs))
30369         done
30370         for (( i=0; i < $num; i++ )); do
30371                 wait ${pids[$i]}
30372         done
30373         check_lsom_size $DIR/$tfile $offset
30374
30375         i=0
30376         $TRUNCATE $DIR/$tfile 0
30377         for client in ${CLIENTS//,/ }; do
30378                 offset=$((offset - $bs))
30379                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30380                 local pids[$i]=$!
30381                 i=$((i + 1))
30382         done
30383         for (( i=0; i < $num; i++ )); do
30384                 wait ${pids[$i]}
30385         done
30386         check_lsom_size $DIR/$tfile $size
30387
30388         # verify SOM blocks count
30389         echo "Verify SOM block count"
30390         $TRUNCATE $DIR/$tfile 0
30391         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30392                 error "failed to write file $tfile with fdatasync and fstat"
30393         check_lsom_data $DIR/$tfile
30394
30395         $TRUNCATE $DIR/$tfile 0
30396         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30397                 error "failed to write file $tfile with fdatasync"
30398         check_lsom_data $DIR/$tfile
30399
30400         $TRUNCATE $DIR/$tfile 0
30401         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30402                 error "failed to write file $tfile with sync IO"
30403         check_lsom_data $DIR/$tfile
30404
30405         # verify truncate
30406         echo "Test SOM for truncate"
30407         # use ftruncate to sync blocks on close request
30408         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30409         check_lsom_size $DIR/$tfile 16384
30410         check_lsom_data $DIR/$tfile
30411
30412         $TRUNCATE $DIR/$tfile 1234
30413         check_lsom_size $DIR/$tfile 1234
30414         # sync blocks on the MDT
30415         $MULTIOP $DIR/$tfile oc
30416         check_lsom_data $DIR/$tfile
30417 }
30418 run_test 806 "Verify Lazy Size on MDS"
30419
30420 test_807() {
30421         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30422         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30423                 skip "Need MDS version at least 2.11.52"
30424
30425         # Registration step
30426         changelog_register || error "changelog_register failed"
30427         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30428         changelog_users $SINGLEMDS | grep -q $cl_user ||
30429                 error "User $cl_user not found in changelog_users"
30430
30431         rm -rf $DIR/$tdir || error "rm $tdir failed"
30432         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30433         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30434         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30435         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30436                 error "truncate $tdir/trunc failed"
30437
30438         local bs=1048576
30439         echo "Test SOM for single-threaded write with fsync"
30440         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30441                 error "write $tfile failed"
30442         sync;sync;sync
30443
30444         # multi-client wirtes
30445         local num=$(get_node_count ${CLIENTS//,/ })
30446         local offset=0
30447         local i=0
30448
30449         echo "Test SOM for multi-client ($num) writes"
30450         touch $DIR/$tfile || error "touch $tfile failed"
30451         $TRUNCATE $DIR/$tfile 0
30452         for client in ${CLIENTS//,/ }; do
30453                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30454                 local pids[$i]=$!
30455                 i=$((i + 1))
30456                 offset=$((offset + $bs))
30457         done
30458         for (( i=0; i < $num; i++ )); do
30459                 wait ${pids[$i]}
30460         done
30461
30462         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30463         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30464         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30465         check_lsom_data $DIR/$tdir/trunc
30466         check_lsom_data $DIR/$tdir/single_dd
30467         check_lsom_data $DIR/$tfile
30468
30469         rm -rf $DIR/$tdir
30470         # Deregistration step
30471         changelog_deregister || error "changelog_deregister failed"
30472 }
30473 run_test 807 "verify LSOM syncing tool"
30474
30475 check_som_nologged()
30476 {
30477         local lines=$($LFS changelog $FSNAME-MDT0000 |
30478                 grep 'x=trusted.som' | wc -l)
30479         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30480 }
30481
30482 test_808() {
30483         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30484                 skip "Need MDS version at least 2.11.55"
30485
30486         # Registration step
30487         changelog_register || error "changelog_register failed"
30488
30489         touch $DIR/$tfile || error "touch $tfile failed"
30490         check_som_nologged
30491
30492         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30493                 error "write $tfile failed"
30494         check_som_nologged
30495
30496         $TRUNCATE $DIR/$tfile 1234
30497         check_som_nologged
30498
30499         $TRUNCATE $DIR/$tfile 1048576
30500         check_som_nologged
30501
30502         # Deregistration step
30503         changelog_deregister || error "changelog_deregister failed"
30504 }
30505 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30506
30507 check_som_nodata()
30508 {
30509         $LFS getsom $1
30510         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30511 }
30512
30513 test_809() {
30514         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30515                 skip "Need MDS version at least 2.11.56"
30516
30517         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30518                 error "failed to create DoM-only file $DIR/$tfile"
30519         touch $DIR/$tfile || error "touch $tfile failed"
30520         check_som_nodata $DIR/$tfile
30521
30522         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30523                 error "write $tfile failed"
30524         check_som_nodata $DIR/$tfile
30525
30526         $TRUNCATE $DIR/$tfile 1234
30527         check_som_nodata $DIR/$tfile
30528
30529         $TRUNCATE $DIR/$tfile 4097
30530         check_som_nodata $DIR/$file
30531 }
30532 run_test 809 "Verify no SOM xattr store for DoM-only files"
30533
30534 test_810() {
30535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30536         $GSS && skip_env "could not run with gss"
30537         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30538                 skip "OST < 2.12.58 doesn't align checksum"
30539
30540         set_checksums 1
30541         stack_trap "set_checksums $ORIG_CSUM" EXIT
30542         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30543
30544         local csum
30545         local before
30546         local after
30547         for csum in $CKSUM_TYPES; do
30548                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30549                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30550                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30551                         eval set -- $i
30552                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30553                         before=$(md5sum $DIR/$tfile)
30554                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30555                         after=$(md5sum $DIR/$tfile)
30556                         [ "$before" == "$after" ] ||
30557                                 error "$csum: $before != $after bs=$1 seek=$2"
30558                 done
30559         done
30560 }
30561 run_test 810 "partial page writes on ZFS (LU-11663)"
30562
30563 test_812a() {
30564         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30565                 skip "OST < 2.12.51 doesn't support this fail_loc"
30566
30567         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30568         # ensure ost1 is connected
30569         stat $DIR/$tfile >/dev/null || error "can't stat"
30570         wait_osc_import_state client ost1 FULL
30571         # no locks, no reqs to let the connection idle
30572         cancel_lru_locks osc
30573
30574         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30575 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30576         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30577         wait_osc_import_state client ost1 CONNECTING
30578         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30579
30580         stat $DIR/$tfile >/dev/null || error "can't stat file"
30581 }
30582 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30583
30584 test_812b() { # LU-12378
30585         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30586                 skip "OST < 2.12.51 doesn't support this fail_loc"
30587
30588         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30589         # ensure ost1 is connected
30590         stat $DIR/$tfile >/dev/null || error "can't stat"
30591         wait_osc_import_state client ost1 FULL
30592         # no locks, no reqs to let the connection idle
30593         cancel_lru_locks osc
30594
30595         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30596 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30597         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30598         wait_osc_import_state client ost1 CONNECTING
30599         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30600
30601         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30602         wait_osc_import_state client ost1 IDLE
30603 }
30604 run_test 812b "do not drop no resend request for idle connect"
30605
30606 test_812c() {
30607         local old
30608
30609         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30610
30611         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30612         $LFS getstripe $DIR/$tfile
30613         $LCTL set_param osc.*.idle_timeout=10
30614         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30615         # ensure ost1 is connected
30616         stat $DIR/$tfile >/dev/null || error "can't stat"
30617         wait_osc_import_state client ost1 FULL
30618         # no locks, no reqs to let the connection idle
30619         cancel_lru_locks osc
30620
30621 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30622         $LCTL set_param fail_loc=0x80000533
30623         sleep 15
30624         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30625 }
30626 run_test 812c "idle import vs lock enqueue race"
30627
30628 test_813() {
30629         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30630         [ -z "$file_heat_sav" ] && skip "no file heat support"
30631
30632         local readsample
30633         local writesample
30634         local readbyte
30635         local writebyte
30636         local readsample1
30637         local writesample1
30638         local readbyte1
30639         local writebyte1
30640
30641         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30642         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30643
30644         $LCTL set_param -n llite.*.file_heat=1
30645         echo "Turn on file heat"
30646         echo "Period second: $period_second, Decay percentage: $decay_pct"
30647
30648         echo "QQQQ" > $DIR/$tfile
30649         echo "QQQQ" > $DIR/$tfile
30650         echo "QQQQ" > $DIR/$tfile
30651         cat $DIR/$tfile > /dev/null
30652         cat $DIR/$tfile > /dev/null
30653         cat $DIR/$tfile > /dev/null
30654         cat $DIR/$tfile > /dev/null
30655
30656         local out=$($LFS heat_get $DIR/$tfile)
30657
30658         $LFS heat_get $DIR/$tfile
30659         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30660         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30661         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30662         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30663
30664         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30665         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30666         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30667         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30668
30669         sleep $((period_second + 3))
30670         echo "Sleep $((period_second + 3)) seconds..."
30671         # The recursion formula to calculate the heat of the file f is as
30672         # follow:
30673         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30674         # Where Hi is the heat value in the period between time points i*I and
30675         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30676         # to the weight of Ci.
30677         out=$($LFS heat_get $DIR/$tfile)
30678         $LFS heat_get $DIR/$tfile
30679         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30680         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30681         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30682         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30683
30684         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30685                 error "read sample ($readsample) is wrong"
30686         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30687                 error "write sample ($writesample) is wrong"
30688         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30689                 error "read bytes ($readbyte) is wrong"
30690         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30691                 error "write bytes ($writebyte) is wrong"
30692
30693         echo "QQQQ" > $DIR/$tfile
30694         echo "QQQQ" > $DIR/$tfile
30695         echo "QQQQ" > $DIR/$tfile
30696         cat $DIR/$tfile > /dev/null
30697         cat $DIR/$tfile > /dev/null
30698         cat $DIR/$tfile > /dev/null
30699         cat $DIR/$tfile > /dev/null
30700
30701         sleep $((period_second + 3))
30702         echo "Sleep $((period_second + 3)) seconds..."
30703
30704         out=$($LFS heat_get $DIR/$tfile)
30705         $LFS heat_get $DIR/$tfile
30706         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30707         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30708         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30709         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30710
30711         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30712                 4 * $decay_pct) / 100") -eq 1 ] ||
30713                 error "read sample ($readsample1) is wrong"
30714         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30715                 3 * $decay_pct) / 100") -eq 1 ] ||
30716                 error "write sample ($writesample1) is wrong"
30717         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30718                 20 * $decay_pct) / 100") -eq 1 ] ||
30719                 error "read bytes ($readbyte1) is wrong"
30720         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30721                 15 * $decay_pct) / 100") -eq 1 ] ||
30722                 error "write bytes ($writebyte1) is wrong"
30723
30724         echo "Turn off file heat for the file $DIR/$tfile"
30725         $LFS heat_set -o $DIR/$tfile
30726
30727         echo "QQQQ" > $DIR/$tfile
30728         echo "QQQQ" > $DIR/$tfile
30729         echo "QQQQ" > $DIR/$tfile
30730         cat $DIR/$tfile > /dev/null
30731         cat $DIR/$tfile > /dev/null
30732         cat $DIR/$tfile > /dev/null
30733         cat $DIR/$tfile > /dev/null
30734
30735         out=$($LFS heat_get $DIR/$tfile)
30736         $LFS heat_get $DIR/$tfile
30737         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30738         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30739         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30740         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30741
30742         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30743         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30744         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30745         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30746
30747         echo "Trun on file heat for the file $DIR/$tfile"
30748         $LFS heat_set -O $DIR/$tfile
30749
30750         echo "QQQQ" > $DIR/$tfile
30751         echo "QQQQ" > $DIR/$tfile
30752         echo "QQQQ" > $DIR/$tfile
30753         cat $DIR/$tfile > /dev/null
30754         cat $DIR/$tfile > /dev/null
30755         cat $DIR/$tfile > /dev/null
30756         cat $DIR/$tfile > /dev/null
30757
30758         out=$($LFS heat_get $DIR/$tfile)
30759         $LFS heat_get $DIR/$tfile
30760         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30761         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30762         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30763         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30764
30765         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
30766         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
30767         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
30768         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
30769
30770         $LFS heat_set -c $DIR/$tfile
30771         $LCTL set_param -n llite.*.file_heat=0
30772         echo "Turn off file heat support for the Lustre filesystem"
30773
30774         echo "QQQQ" > $DIR/$tfile
30775         echo "QQQQ" > $DIR/$tfile
30776         echo "QQQQ" > $DIR/$tfile
30777         cat $DIR/$tfile > /dev/null
30778         cat $DIR/$tfile > /dev/null
30779         cat $DIR/$tfile > /dev/null
30780         cat $DIR/$tfile > /dev/null
30781
30782         out=$($LFS heat_get $DIR/$tfile)
30783         $LFS heat_get $DIR/$tfile
30784         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30785         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30786         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30787         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30788
30789         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
30790         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
30791         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
30792         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
30793
30794         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
30795         rm -f $DIR/$tfile
30796 }
30797 run_test 813 "File heat verfication"
30798
30799 test_814()
30800 {
30801         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
30802         echo -n y >> $DIR/$tfile
30803         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
30804         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
30805 }
30806 run_test 814 "sparse cp works as expected (LU-12361)"
30807
30808 test_815()
30809 {
30810         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
30811         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
30812 }
30813 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
30814
30815 test_816() {
30816         local ost1_imp=$(get_osc_import_name client ost1)
30817         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
30818                          cut -d'.' -f2)
30819
30820         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30821         # ensure ost1 is connected
30822
30823         stat $DIR/$tfile >/dev/null || error "can't stat"
30824         wait_osc_import_state client ost1 FULL
30825         # no locks, no reqs to let the connection idle
30826         cancel_lru_locks osc
30827         lru_resize_disable osc
30828         local before
30829         local now
30830         before=$($LCTL get_param -n \
30831                  ldlm.namespaces.$imp_name.lru_size)
30832
30833         wait_osc_import_state client ost1 IDLE
30834         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
30835         now=$($LCTL get_param -n \
30836               ldlm.namespaces.$imp_name.lru_size)
30837         [ $before == $now ] || error "lru_size changed $before != $now"
30838 }
30839 run_test 816 "do not reset lru_resize on idle reconnect"
30840
30841 cleanup_817() {
30842         umount $tmpdir
30843         exportfs -u localhost:$DIR/nfsexp
30844         rm -rf $DIR/nfsexp
30845 }
30846
30847 test_817() {
30848         systemctl restart nfs-server.service || skip "failed to restart nfsd"
30849
30850         mkdir -p $DIR/nfsexp
30851         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
30852                 error "failed to export nfs"
30853
30854         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
30855         stack_trap cleanup_817 EXIT
30856
30857         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
30858                 error "failed to mount nfs to $tmpdir"
30859
30860         cp /bin/true $tmpdir
30861         $DIR/nfsexp/true || error "failed to execute 'true' command"
30862 }
30863 run_test 817 "nfsd won't cache write lock for exec file"
30864
30865 test_818() {
30866         test_mkdir -i0 -c1 $DIR/$tdir
30867         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
30868         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
30869         stop $SINGLEMDS
30870
30871         # restore osp-syn threads
30872         stack_trap "fail $SINGLEMDS"
30873
30874         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
30875         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
30876         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
30877                 error "start $SINGLEMDS failed"
30878         rm -rf $DIR/$tdir
30879
30880         local testid=$(echo $TESTNAME | tr '_' ' ')
30881
30882         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
30883                 grep "run LFSCK" || error "run LFSCK is not suggested"
30884 }
30885 run_test 818 "unlink with failed llog"
30886
30887 test_819a() {
30888         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30889         cancel_lru_locks osc
30890         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30891         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30892         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
30893         rm -f $TDIR/$tfile
30894 }
30895 run_test 819a "too big niobuf in read"
30896
30897 test_819b() {
30898         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
30899         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
30900         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
30901         cancel_lru_locks osc
30902         sleep 1
30903         rm -f $TDIR/$tfile
30904 }
30905 run_test 819b "too big niobuf in write"
30906
30907
30908 function test_820_start_ost() {
30909         sleep 5
30910
30911         for num in $(seq $OSTCOUNT); do
30912                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
30913         done
30914 }
30915
30916 test_820() {
30917         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30918
30919         mkdir $DIR/$tdir
30920         umount_client $MOUNT || error "umount failed"
30921         for num in $(seq $OSTCOUNT); do
30922                 stop ost$num
30923         done
30924
30925         # mount client with no active OSTs
30926         # so that the client can't initialize max LOV EA size
30927         # from OSC notifications
30928         mount_client $MOUNT || error "mount failed"
30929         # delay OST starting to keep this 0 max EA size for a while
30930         test_820_start_ost &
30931
30932         # create a directory on MDS2
30933         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
30934                 error "Failed to create directory"
30935         # open intent should update default EA size
30936         # see mdc_update_max_ea_from_body()
30937         # notice this is the very first RPC to MDS2
30938         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
30939         ret=$?
30940         echo $out
30941         # With SSK, this situation can lead to -EPERM being returned.
30942         # In that case, simply retry.
30943         if [ $ret -ne 0 ] && $SHARED_KEY; then
30944                 if echo "$out" | grep -q "not permitted"; then
30945                         cp /etc/services $DIR/$tdir/mds2
30946                         ret=$?
30947                 fi
30948         fi
30949         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
30950 }
30951 run_test 820 "update max EA from open intent"
30952
30953 test_823() {
30954         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30955         local OST_MAX_PRECREATE=20000
30956
30957         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
30958                 skip "Need MDS version at least 2.14.56"
30959
30960         save_lustre_params mds1 \
30961                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
30962         do_facet $SINGLEMDS "$LCTL set_param -n \
30963                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
30964         do_facet $SINGLEMDS "$LCTL set_param -n \
30965                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
30966
30967         stack_trap "restore_lustre_params < $p; rm $p"
30968
30969         do_facet $SINGLEMDS "$LCTL set_param -n \
30970                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
30971
30972         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30973                       osp.$FSNAME-OST0000*MDT0000.create_count")
30974         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
30975                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
30976         local expect_count=$(((($max/2)/256) * 256))
30977
30978         log "setting create_count to 100200:"
30979         log " -result- count: $count with max: $max, expecting: $expect_count"
30980
30981         [[ $count -eq expect_count ]] ||
30982                 error "Create count not set to max precreate."
30983 }
30984 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
30985
30986 test_831() {
30987         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
30988                 skip "Need MDS version 2.14.56"
30989
30990         local sync_changes=$(do_facet $SINGLEMDS \
30991                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
30992
30993         [ "$sync_changes" -gt 100 ] &&
30994                 skip "Sync changes $sync_changes > 100 already"
30995
30996         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30997
30998         $LFS mkdir -i 0 $DIR/$tdir
30999         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31000
31001         save_lustre_params mds1 \
31002                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31003         save_lustre_params mds1 \
31004                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31005
31006         do_facet mds1 "$LCTL set_param -n \
31007                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31008                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31009         stack_trap "restore_lustre_params < $p" EXIT
31010
31011         createmany -o $DIR/$tdir/f- 1000
31012         unlinkmany $DIR/$tdir/f- 1000 &
31013         local UNLINK_PID=$!
31014
31015         while sleep 1; do
31016                 sync_changes=$(do_facet mds1 \
31017                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31018                 # the check in the code is racy, fail the test
31019                 # if the value above the limit by 10.
31020                 [ $sync_changes -gt 110 ] && {
31021                         kill -2 $UNLINK_PID
31022                         wait
31023                         error "osp changes throttling failed, $sync_changes>110"
31024                 }
31025                 kill -0 $UNLINK_PID 2> /dev/null || break
31026         done
31027         wait
31028 }
31029 run_test 831 "throttling unlink/setattr queuing on OSP"
31030
31031 test_832() {
31032         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31033         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31034                 skip "Need MDS version 2.15.52+"
31035         is_rmentry_supported || skip "rm_entry not supported"
31036
31037         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31038         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31039         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31040                 error "mkdir remote_dir failed"
31041         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31042                 error "mkdir striped_dir failed"
31043         touch $DIR/$tdir/file || error "touch file failed"
31044         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31045         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31046 }
31047 run_test 832 "lfs rm_entry"
31048
31049 test_833() {
31050         local file=$DIR/$tfile
31051
31052         stack_trap "rm -f $file" EXIT
31053         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31054
31055         local wpid
31056         local rpid
31057         local rpid2
31058
31059         # Buffered I/O write
31060         (
31061                 while [ ! -e $DIR/sanity.833.lck ]; do
31062                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31063                                 error "failed to write $file"
31064                         sleep 0.$((RANDOM % 4 + 1))
31065                 done
31066         )&
31067         wpid=$!
31068
31069         # Buffered I/O read
31070         (
31071                 while [ ! -e $DIR/sanity.833.lck ]; do
31072                         dd if=$file of=/dev/null bs=1M count=50 ||
31073                                 error "failed to read $file"
31074                         sleep 0.$((RANDOM % 4 + 1))
31075                 done
31076         )&
31077         rpid=$!
31078
31079         # Direct I/O read
31080         (
31081                 while [ ! -e $DIR/sanity.833.lck ]; do
31082                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31083                                 error "failed to read $file in direct I/O mode"
31084                         sleep 0.$((RANDOM % 4 + 1))
31085                 done
31086         )&
31087         rpid2=$!
31088
31089         sleep 30
31090         touch $DIR/sanity.833.lck
31091         wait $wpid || error "$?: buffered write failed"
31092         wait $rpid || error "$?: buffered read failed"
31093         wait $rpid2 || error "$?: direct read failed"
31094 }
31095 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31096
31097 #
31098 # tests that do cleanup/setup should be run at the end
31099 #
31100
31101 test_900() {
31102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31103         local ls
31104
31105         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31106         $LCTL set_param fail_loc=0x903
31107
31108         cancel_lru_locks MGC
31109
31110         FAIL_ON_ERROR=true cleanup
31111         FAIL_ON_ERROR=true setup
31112 }
31113 run_test 900 "umount should not race with any mgc requeue thread"
31114
31115 # LUS-6253/LU-11185
31116 test_901() {
31117         local old
31118         local count
31119         local oldc
31120         local newc
31121         local olds
31122         local news
31123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31124
31125         # some get_param have a bug to handle dot in param name
31126         cancel_lru_locks MGC
31127         old=$(mount -t lustre | wc -l)
31128         # 1 config+sptlrpc
31129         # 2 params
31130         # 3 nodemap
31131         # 4 IR
31132         old=$((old * 4))
31133         oldc=0
31134         count=0
31135         while [ $old -ne $oldc ]; do
31136                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31137                 sleep 1
31138                 ((count++))
31139                 if [ $count -ge $TIMEOUT ]; then
31140                         error "too large timeout"
31141                 fi
31142         done
31143         umount_client $MOUNT || error "umount failed"
31144         mount_client $MOUNT || error "mount failed"
31145         cancel_lru_locks MGC
31146         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31147
31148         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31149
31150         return 0
31151 }
31152 run_test 901 "don't leak a mgc lock on client umount"
31153
31154 # LU-13377
31155 test_902() {
31156         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31157                 skip "client does not have LU-13377 fix"
31158         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31159         $LCTL set_param fail_loc=0x1415
31160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31161         cancel_lru_locks osc
31162         rm -f $DIR/$tfile
31163 }
31164 run_test 902 "test short write doesn't hang lustre"
31165
31166 # LU-14711
31167 test_903() {
31168         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31169         echo "blah" > $DIR/${tfile}-2
31170         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31171         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31172         $LCTL set_param fail_loc=0x417 fail_val=20
31173
31174         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31175         sleep 1 # To start the destroy
31176         wait_destroy_complete 150 || error "Destroy taking too long"
31177         cat $DIR/$tfile > /dev/null || error "Evicted"
31178 }
31179 run_test 903 "Test long page discard does not cause evictions"
31180
31181 test_904() {
31182         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31183         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31184                 grep -q project || skip "skip project quota not supported"
31185
31186         local testfile="$DIR/$tdir/$tfile"
31187         local xattr="trusted.projid"
31188         local projid
31189         local mdts=$(comma_list $(mdts_nodes))
31190         local saved=$(do_facet mds1 $LCTL get_param -n \
31191                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31192
31193         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31194         stack_trap "do_nodes $mdts $LCTL set_param \
31195                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31196
31197         mkdir -p $DIR/$tdir
31198         touch $testfile
31199         #hide projid xattr on server
31200         $LFS project -p 1 $testfile ||
31201                 error "set $testfile project id failed"
31202         getfattr -m - $testfile | grep $xattr &&
31203                 error "do not show trusted.projid when disabled on server"
31204         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31205         #should be hidden when projid is 0
31206         $LFS project -p 0 $testfile ||
31207                 error "set $testfile project id failed"
31208         getfattr -m - $testfile | grep $xattr &&
31209                 error "do not show trusted.projid with project ID 0"
31210
31211         #still can getxattr explicitly
31212         projid=$(getfattr -n $xattr $testfile |
31213                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31214         [ $projid == "0" ] ||
31215                 error "projid expected 0 not $projid"
31216
31217         #set the projid via setxattr
31218         setfattr -n $xattr -v "1000" $testfile ||
31219                 error "setattr failed with $?"
31220         projid=($($LFS project $testfile))
31221         [ ${projid[0]} == "1000" ] ||
31222                 error "projid expected 1000 not $projid"
31223
31224         #check the new projid via getxattr
31225         $LFS project -p 1001 $testfile ||
31226                 error "set $testfile project id failed"
31227         getfattr -m - $testfile | grep $xattr ||
31228                 error "should show trusted.projid when project ID != 0"
31229         projid=$(getfattr -n $xattr $testfile |
31230                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31231         [ $projid == "1001" ] ||
31232                 error "projid expected 1001 not $projid"
31233
31234         #try to set invalid projid
31235         setfattr -n $xattr -v "4294967295" $testfile &&
31236                 error "set invalid projid should fail"
31237
31238         #remove the xattr means setting projid to 0
31239         setfattr -x $xattr $testfile ||
31240                 error "setfattr failed with $?"
31241         projid=($($LFS project $testfile))
31242         [ ${projid[0]} == "0" ] ||
31243                 error "projid expected 0 not $projid"
31244
31245         #should be hidden when parent has inherit flag and same projid
31246         $LFS project -srp 1002 $DIR/$tdir ||
31247                 error "set $tdir project id failed"
31248         getfattr -m - $testfile | grep $xattr &&
31249                 error "do not show trusted.projid with inherit flag"
31250
31251         #still can getxattr explicitly
31252         projid=$(getfattr -n $xattr $testfile |
31253                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31254         [ $projid == "1002" ] ||
31255                 error "projid expected 1002 not $projid"
31256 }
31257 run_test 904 "virtual project ID xattr"
31258
31259 # LU-8582
31260 test_905() {
31261         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31262                 skip "need OST version >= 2.15.50.220 for fail_loc"
31263
31264         remote_ost_nodsh && skip "remote OST with nodsh"
31265         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31266
31267         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31268
31269         #define OBD_FAIL_OST_OPCODE 0x253
31270         # OST_LADVISE = 21
31271         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31272         $LFS ladvise -a willread $DIR/$tfile &&
31273                 error "unexpected success of ladvise with fault injection"
31274         $LFS ladvise -a willread $DIR/$tfile |&
31275                 grep -q "Operation not supported"
31276         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31277 }
31278 run_test 905 "bad or new opcode should not stuck client"
31279
31280 test_906() {
31281         grep -q io_uring_setup /proc/kallsyms ||
31282                 skip "Client OS does not support io_uring I/O engine"
31283         io_uring_probe || skip "kernel does not support io_uring fully"
31284         which fio || skip_env "no fio installed"
31285         fio --enghelp | grep -q io_uring ||
31286                 skip_env "fio does not support io_uring I/O engine"
31287
31288         local file=$DIR/$tfile
31289         local ioengine="io_uring"
31290         local numjobs=2
31291         local size=50M
31292
31293         fio --name=seqwrite --ioengine=$ioengine        \
31294                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31295                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31296                 error "fio seqwrite $file failed"
31297
31298         fio --name=seqread --ioengine=$ioengine \
31299                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31300                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31301                 error "fio seqread $file failed"
31302
31303         rm -f $file || error "rm -f $file failed"
31304 }
31305 run_test 906 "Simple test for io_uring I/O engine via fio"
31306
31307 test_907() {
31308         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31309
31310         # set stripe size to max rpc size
31311         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31312         $LFS getstripe $DIR/$tfile
31313 #define OBD_FAIL_OST_EROFS               0x216
31314         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31315
31316         local bs=$((max_pages * PAGE_SIZE / 16))
31317
31318         # write full one stripe and one block
31319         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31320
31321         rm $DIR/$tfile || error "rm failed"
31322 }
31323 run_test 907 "write rpc error during unlink"
31324
31325 complete_test $SECONDS
31326 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31327 check_and_cleanup_lustre
31328 if [ "$I_MOUNTED" != "yes" ]; then
31329         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31330 fi
31331 exit_status