Whamcloud - gitweb
LU-16250 tests: remove metadata-updates.sh script
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
66 # until the filemap_read() issue is fixed
67 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
68         always_except LU-16101 27J
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
73
74 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
75         #                                               13    (min)"
76         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
80         always_except LU-1941 130b 130c 130d 130e 130f 130g
81         always_except LU-9054 312
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108
109         [ $sles_version -ge $(version_code 15.4.0) ] &&
110                 always_except LU-16101 27J
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         always_except LU-10366 410
120                 fi
121         fi
122 fi
123
124 build_test_filter
125 FAIL_ON_ERROR=false
126
127 cleanup() {
128         echo -n "cln.."
129         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
130         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
131 }
132 setup() {
133         echo -n "mnt.."
134         load_modules
135         setupall || exit 10
136         echo "done"
137 }
138
139 check_swap_layouts_support()
140 {
141         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
142                 skip "Does not support layout lock."
143 }
144
145 check_swap_layout_no_dom()
146 {
147         local FOLDER=$1
148         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
149         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
150 }
151
152 check_and_setup_lustre
153 DIR=${DIR:-$MOUNT}
154 assert_DIR
155
156 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
157
158 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
159 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
160 rm -rf $DIR/[Rdfs][0-9]*
161
162 # $RUNAS_ID may get set incorrectly somewhere else
163 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
164         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
165
166 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
167
168 if [ "${ONLY}" = "MOUNT" ] ; then
169         echo "Lustre is up, please go on"
170         exit
171 fi
172
173 echo "preparing for tests involving mounts"
174 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
175 touch $EXT2_DEV
176 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
177 echo # add a newline after mke2fs.
178
179 umask 077
180
181 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
182 lctl set_param debug=-1 2> /dev/null || true
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         test_mkdir -p $DIR/$tdir
2516         local setcount=$LOV_MAX_STRIPE_COUNT
2517
2518         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2519                 error "setstripe failed"
2520
2521         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2522         [ $count -eq $setcount ] ||
2523                 error "stripe count $count, should be $setcount"
2524
2525         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2526                 error "overstriped should be set in pattern"
2527
2528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2529                 error "dd failed"
2530
2531         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2532 }
2533 run_test 27Cd "test maximum stripe count"
2534
2535 test_27Ce() {
2536         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2537                 skip "server does not support overstriping"
2538         test_mkdir -p $DIR/$tdir
2539
2540         pool_add $TESTNAME || error "Pool creation failed"
2541         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2542
2543         local setcount=8
2544
2545         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2546                 error "setstripe failed"
2547
2548         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2549         [ $count -eq $setcount ] ||
2550                 error "stripe count $count, should be $setcount"
2551
2552         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2553                 error "overstriped should be set in pattern"
2554
2555         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2556                 error "dd failed"
2557
2558         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2559 }
2560 run_test 27Ce "test pool with overstriping"
2561
2562 test_27Cf() {
2563         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2564                 skip "server does not support overstriping"
2565         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2566                 skip_env "too many osts, skipping"
2567
2568         test_mkdir -p $DIR/$tdir
2569
2570         local setcount=$(($OSTCOUNT * 2))
2571         [ $setcount -lt 160 ] || large_xattr_enabled ||
2572                 skip_env "ea_inode feature disabled"
2573
2574         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2575                 error "setstripe failed"
2576
2577         echo 1 > $DIR/$tdir/$tfile
2578
2579         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2580         [ $count -eq $setcount ] ||
2581                 error "stripe count $count, should be $setcount"
2582
2583         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2584                 error "overstriped should be set in pattern"
2585
2586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2587                 error "dd failed"
2588
2589         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2590 }
2591 run_test 27Cf "test default inheritance with overstriping"
2592
2593 test_27D() {
2594         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2595         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2596         remote_mds_nodsh && skip "remote MDS with nodsh"
2597
2598         local POOL=${POOL:-testpool}
2599         local first_ost=0
2600         local last_ost=$(($OSTCOUNT - 1))
2601         local ost_step=1
2602         local ost_list=$(seq $first_ost $ost_step $last_ost)
2603         local ost_range="$first_ost $last_ost $ost_step"
2604
2605         test_mkdir $DIR/$tdir
2606         pool_add $POOL || error "pool_add failed"
2607         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2608
2609         local skip27D
2610         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2611                 skip27D+="-s 29"
2612         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2613                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2614                         skip27D+=" -s 30,31"
2615         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2616           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2617                 skip27D+=" -s 32,33"
2618         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2619                 skip27D+=" -s 34"
2620         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2621                 error "llapi_layout_test failed"
2622
2623         destroy_test_pools || error "destroy test pools failed"
2624 }
2625 run_test 27D "validate llapi_layout API"
2626
2627 # Verify that default_easize is increased from its initial value after
2628 # accessing a widely striped file.
2629 test_27E() {
2630         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2631         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2632                 skip "client does not have LU-3338 fix"
2633
2634         # 72 bytes is the minimum space required to store striping
2635         # information for a file striped across one OST:
2636         # (sizeof(struct lov_user_md_v3) +
2637         #  sizeof(struct lov_user_ost_data_v1))
2638         local min_easize=72
2639         $LCTL set_param -n llite.*.default_easize $min_easize ||
2640                 error "lctl set_param failed"
2641         local easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -eq $min_easize ] ||
2644                 error "failed to set default_easize"
2645
2646         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2647                 error "setstripe failed"
2648         # In order to ensure stat() call actually talks to MDS we need to
2649         # do something drastic to this file to shake off all lock, e.g.
2650         # rename it (kills lookup lock forcing cache cleaning)
2651         mv $DIR/$tfile $DIR/${tfile}-1
2652         ls -l $DIR/${tfile}-1
2653         rm $DIR/${tfile}-1
2654
2655         easize=$($LCTL get_param -n llite.*.default_easize)
2656
2657         [ $easize -gt $min_easize ] ||
2658                 error "default_easize not updated"
2659 }
2660 run_test 27E "check that default extended attribute size properly increases"
2661
2662 test_27F() { # LU-5346/LU-7975
2663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2664         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2665         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2666                 skip "Need MDS version at least 2.8.51"
2667         remote_ost_nodsh && skip "remote OST with nodsh"
2668
2669         test_mkdir $DIR/$tdir
2670         rm -f $DIR/$tdir/f0
2671         $LFS setstripe -c 2 $DIR/$tdir
2672
2673         # stop all OSTs to reproduce situation for LU-7975 ticket
2674         for num in $(seq $OSTCOUNT); do
2675                 stop ost$num
2676         done
2677
2678         # open/create f0 with O_LOV_DELAY_CREATE
2679         # truncate f0 to a non-0 size
2680         # close
2681         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2682
2683         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2684         # open/write it again to force delayed layout creation
2685         cat /etc/hosts > $DIR/$tdir/f0 &
2686         catpid=$!
2687
2688         # restart OSTs
2689         for num in $(seq $OSTCOUNT); do
2690                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2691                         error "ost$num failed to start"
2692         done
2693
2694         wait $catpid || error "cat failed"
2695
2696         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2697         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2698                 error "wrong stripecount"
2699
2700 }
2701 run_test 27F "Client resend delayed layout creation with non-zero size"
2702
2703 test_27G() { #LU-10629
2704         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2705                 skip "Need MDS version at least 2.11.51"
2706         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2707         remote_mds_nodsh && skip "remote MDS with nodsh"
2708         local POOL=${POOL:-testpool}
2709         local ostrange="0 0 1"
2710
2711         test_mkdir $DIR/$tdir
2712         touch $DIR/$tdir/$tfile.nopool
2713         pool_add $POOL || error "pool_add failed"
2714         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2715         $LFS setstripe -p $POOL $DIR/$tdir
2716
2717         local pool=$($LFS getstripe -p $DIR/$tdir)
2718
2719         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2720         touch $DIR/$tdir/$tfile.default
2721         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2722         $LFS find $DIR/$tdir -type f --pool $POOL
2723         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2724         [[ "$found" == "2" ]] ||
2725                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2726
2727         $LFS setstripe -d $DIR/$tdir
2728
2729         pool=$($LFS getstripe -p -d $DIR/$tdir)
2730
2731         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2732 }
2733 run_test 27G "Clear OST pool from stripe"
2734
2735 test_27H() {
2736         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2737                 skip "Need MDS version newer than 2.11.54"
2738         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2739         test_mkdir $DIR/$tdir
2740         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2741         touch $DIR/$tdir/$tfile
2742         $LFS getstripe -c $DIR/$tdir/$tfile
2743         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2744                 error "two-stripe file doesn't have two stripes"
2745
2746         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2747         $LFS getstripe -y $DIR/$tdir/$tfile
2748         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2749              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2750                 error "expected l_ost_idx: [02]$ not matched"
2751
2752         # make sure ost list has been cleared
2753         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2754         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2755                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2756         touch $DIR/$tdir/f3
2757         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2758 }
2759 run_test 27H "Set specific OSTs stripe"
2760
2761 test_27I() {
2762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2764         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2765                 skip "Need MDS version newer than 2.12.52"
2766         local pool=$TESTNAME
2767         local ostrange="1 1 1"
2768
2769         save_layout_restore_at_exit $MOUNT
2770         $LFS setstripe -c 2 -i 0 $MOUNT
2771         pool_add $pool || error "pool_add failed"
2772         pool_add_targets $pool $ostrange ||
2773                 error "pool_add_targets failed"
2774         test_mkdir $DIR/$tdir
2775         $LFS setstripe -p $pool $DIR/$tdir
2776         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2777         $LFS getstripe $DIR/$tdir/$tfile
2778 }
2779 run_test 27I "check that root dir striping does not break parent dir one"
2780
2781 test_27J() {
2782         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2783                 skip "Need MDS version newer than 2.12.51"
2784
2785         test_mkdir $DIR/$tdir
2786         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2787         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2788
2789         # create foreign file (raw way)
2790         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2791                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2792
2793         ! $LFS setstripe --foreign --flags foo \
2794                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2795                         error "creating $tfile with '--flags foo' should fail"
2796
2797         ! $LFS setstripe --foreign --flags 0xffffffff \
2798                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2799                         error "creating $tfile w/ 0xffffffff flags should fail"
2800
2801         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2802                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2803
2804         # verify foreign file (raw way)
2805         parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2807                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2808         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2810         parse_foreign_file -f $DIR/$tdir/$tfile |
2811                 grep "lov_foreign_size: 73" ||
2812                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2813         parse_foreign_file -f $DIR/$tdir/$tfile |
2814                 grep "lov_foreign_type: 1" ||
2815                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_flags: 0x0000DA08" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2819         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2820                 grep "lov_foreign_value: 0x" |
2821                 sed -e 's/lov_foreign_value: 0x//')
2822         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2823         [[ $lov = ${lov2// /} ]] ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2825
2826         # create foreign file (lfs + API)
2827         $LFS setstripe --foreign=none --flags 0xda08 \
2828                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: create failed"
2830
2831         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2832                 grep "lfm_magic:.*0x0BD70BD0" ||
2833                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2834         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2835         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2836                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2837         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2838                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2839         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2840                 grep "lfm_flags:.*0x0000DA08" ||
2841                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2842         $LFS getstripe $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2845
2846         # modify striping should fail
2847         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2848                 error "$DIR/$tdir/$tfile: setstripe should fail"
2849         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2850                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2851
2852         # R/W should fail
2853         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2854         cat $DIR/$tdir/${tfile}2 &&
2855                 error "$DIR/$tdir/${tfile}2: read should fail"
2856         cat /etc/passwd > $DIR/$tdir/$tfile &&
2857                 error "$DIR/$tdir/$tfile: write should fail"
2858         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2859                 error "$DIR/$tdir/${tfile}2: write should fail"
2860
2861         # chmod should work
2862         chmod 222 $DIR/$tdir/$tfile ||
2863                 error "$DIR/$tdir/$tfile: chmod failed"
2864         chmod 222 $DIR/$tdir/${tfile}2 ||
2865                 error "$DIR/$tdir/${tfile}2: chmod failed"
2866
2867         # chown should work
2868         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2869                 error "$DIR/$tdir/$tfile: chown failed"
2870         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2871                 error "$DIR/$tdir/${tfile}2: chown failed"
2872
2873         # rename should work
2874         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2875                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2876         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2877                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2878
2879         #remove foreign file
2880         rm $DIR/$tdir/${tfile}.new ||
2881                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2882         rm $DIR/$tdir/${tfile}2.new ||
2883                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2884 }
2885 run_test 27J "basic ops on file with foreign LOV"
2886
2887 test_27K() {
2888         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2889                 skip "Need MDS version newer than 2.12.49"
2890
2891         test_mkdir $DIR/$tdir
2892         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2893         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2894
2895         # create foreign dir (raw way)
2896         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2897                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2898
2899         ! $LFS setdirstripe --foreign --flags foo \
2900                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2901                         error "creating $tdir with '--flags foo' should fail"
2902
2903         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2904                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2905                         error "creating $tdir w/ 0xffffffff flags should fail"
2906
2907         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2908                 error "create_foreign_dir FAILED"
2909
2910         # verify foreign dir (raw way)
2911         parse_foreign_dir -d $DIR/$tdir/$tdir |
2912                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2913                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2914         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2915                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2916         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2917                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2918         parse_foreign_dir -d $DIR/$tdir/$tdir |
2919                 grep "lmv_foreign_flags: 55813$" ||
2920                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2921         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2922                 grep "lmv_foreign_value: 0x" |
2923                 sed 's/lmv_foreign_value: 0x//')
2924         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2925                 sed 's/ //g')
2926         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2927
2928         # create foreign dir (lfs + API)
2929         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2930                 $DIR/$tdir/${tdir}2 ||
2931                 error "$DIR/$tdir/${tdir}2: create failed"
2932
2933         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2934
2935         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2936                 grep "lfm_magic:.*0x0CD50CD0" ||
2937                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2938         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2939         # - sizeof(lfm_type) - sizeof(lfm_flags)
2940         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2941                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2942         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2943                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2945                 grep "lfm_flags:.*0x0000DA05" ||
2946                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2947         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2950
2951         # file create in dir should fail
2952         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2953         touch $DIR/$tdir/${tdir}2/$tfile &&
2954                 error "$DIR/${tdir}2: file create should fail"
2955
2956         # chmod should work
2957         chmod 777 $DIR/$tdir/$tdir ||
2958                 error "$DIR/$tdir: chmod failed"
2959         chmod 777 $DIR/$tdir/${tdir}2 ||
2960                 error "$DIR/${tdir}2: chmod failed"
2961
2962         # chown should work
2963         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2964                 error "$DIR/$tdir: chown failed"
2965         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2966                 error "$DIR/${tdir}2: chown failed"
2967
2968         # rename should work
2969         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2970                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2971         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2972                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2973
2974         #remove foreign dir
2975         rmdir $DIR/$tdir/${tdir}.new ||
2976                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2977         rmdir $DIR/$tdir/${tdir}2.new ||
2978                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2979 }
2980 run_test 27K "basic ops on dir with foreign LMV"
2981
2982 test_27L() {
2983         remote_mds_nodsh && skip "remote MDS with nodsh"
2984
2985         local POOL=${POOL:-$TESTNAME}
2986
2987         pool_add $POOL || error "pool_add failed"
2988
2989         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2990                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2991                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2992 }
2993 run_test 27L "lfs pool_list gives correct pool name"
2994
2995 test_27M() {
2996         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2997                 skip "Need MDS version >= than 2.12.57"
2998         remote_mds_nodsh && skip "remote MDS with nodsh"
2999         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3000
3001         # Set default striping on directory
3002         local setcount=4
3003         local stripe_opt
3004         local mdts=$(comma_list $(mdts_nodes))
3005
3006         # if we run against a 2.12 server which lacks overstring support
3007         # then the connect_flag will not report overstriping, even if client
3008         # is 2.14+
3009         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3010                 stripe_opt="-C $setcount"
3011         elif (( $OSTCOUNT >= $setcount )); then
3012                 stripe_opt="-c $setcount"
3013         else
3014                 skip "server does not support overstriping"
3015         fi
3016
3017         test_mkdir $DIR/$tdir
3018
3019         # Validate existing append_* params and ensure restore
3020         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3021         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3022         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3023
3024         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3025         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3026         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3027
3028         $LFS setstripe $stripe_opt $DIR/$tdir
3029
3030         echo 1 > $DIR/$tdir/${tfile}.1
3031         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3032         [ $count -eq $setcount ] ||
3033                 error "(1) stripe count $count, should be $setcount"
3034
3035         local appendcount=$orig_count
3036         echo 1 >> $DIR/$tdir/${tfile}.2_append
3037         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3038         [ $count -eq $appendcount ] ||
3039                 error "(2)stripe count $count, should be $appendcount for append"
3040
3041         # Disable O_APPEND striping, verify it works
3042         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3043
3044         # Should now get the default striping, which is 4
3045         setcount=4
3046         echo 1 >> $DIR/$tdir/${tfile}.3_append
3047         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3048         [ $count -eq $setcount ] ||
3049                 error "(3) stripe count $count, should be $setcount"
3050
3051         # Try changing the stripe count for append files
3052         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3053
3054         # Append striping is now 2 (directory default is still 4)
3055         appendcount=2
3056         echo 1 >> $DIR/$tdir/${tfile}.4_append
3057         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3058         [ $count -eq $appendcount ] ||
3059                 error "(4) stripe count $count, should be $appendcount for append"
3060
3061         # Test append stripe count of -1
3062         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3063         appendcount=$OSTCOUNT
3064         echo 1 >> $DIR/$tdir/${tfile}.5
3065         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3066         [ $count -eq $appendcount ] ||
3067                 error "(5) stripe count $count, should be $appendcount for append"
3068
3069         # Set append striping back to default of 1
3070         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3071
3072         # Try a new default striping, PFL + DOM
3073         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3074
3075         # Create normal DOM file, DOM returns stripe count == 0
3076         setcount=0
3077         touch $DIR/$tdir/${tfile}.6
3078         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3079         [ $count -eq $setcount ] ||
3080                 error "(6) stripe count $count, should be $setcount"
3081
3082         # Show
3083         appendcount=1
3084         echo 1 >> $DIR/$tdir/${tfile}.7_append
3085         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3086         [ $count -eq $appendcount ] ||
3087                 error "(7) stripe count $count, should be $appendcount for append"
3088
3089         # Clean up DOM layout
3090         $LFS setstripe -d $DIR/$tdir
3091
3092         save_layout_restore_at_exit $MOUNT
3093         # Now test that append striping works when layout is from root
3094         $LFS setstripe -c 2 $MOUNT
3095         # Make a special directory for this
3096         mkdir $DIR/${tdir}/${tdir}.2
3097
3098         # Verify for normal file
3099         setcount=2
3100         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3101         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3102         [ $count -eq $setcount ] ||
3103                 error "(8) stripe count $count, should be $setcount"
3104
3105         appendcount=1
3106         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3107         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3108         [ $count -eq $appendcount ] ||
3109                 error "(9) stripe count $count, should be $appendcount for append"
3110
3111         # Now test O_APPEND striping with pools
3112         pool_add $TESTNAME || error "pool creation failed"
3113         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3114         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3115
3116         echo 1 >> $DIR/$tdir/${tfile}.10_append
3117
3118         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3119         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3120
3121         # Check that count is still correct
3122         appendcount=1
3123         echo 1 >> $DIR/$tdir/${tfile}.11_append
3124         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3125         [ $count -eq $appendcount ] ||
3126                 error "(11) stripe count $count, should be $appendcount for append"
3127
3128         # Disable O_APPEND stripe count, verify pool works separately
3129         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3130
3131         echo 1 >> $DIR/$tdir/${tfile}.12_append
3132
3133         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3134         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3135
3136         # Remove pool setting, verify it's not applied
3137         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3138
3139         echo 1 >> $DIR/$tdir/${tfile}.13_append
3140
3141         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3142         [ "$pool" = "" ] || error "(13) pool found: $pool"
3143 }
3144 run_test 27M "test O_APPEND striping"
3145
3146 test_27N() {
3147         combined_mgs_mds && skip "needs separate MGS/MDT"
3148
3149         pool_add $TESTNAME || error "pool_add failed"
3150         do_facet mgs "$LCTL pool_list $FSNAME" |
3151                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3152                 error "lctl pool_list on MGS failed"
3153 }
3154 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3155
3156 clean_foreign_symlink() {
3157         trap 0
3158         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3159         for i in $DIR/$tdir/* ; do
3160                 $LFS unlink_foreign $i || true
3161         done
3162 }
3163
3164 test_27O() {
3165         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3166                 skip "Need MDS version newer than 2.12.51"
3167
3168         test_mkdir $DIR/$tdir
3169         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3170         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3171
3172         trap clean_foreign_symlink EXIT
3173
3174         # enable foreign_symlink behaviour
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3176
3177         # foreign symlink LOV format is a partial path by default
3178
3179         # create foreign file (lfs + API)
3180         $LFS setstripe --foreign=symlink --flags 0xda05 \
3181                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3182                 error "$DIR/$tdir/${tfile}: create failed"
3183
3184         $LFS getstripe -v $DIR/$tdir/${tfile} |
3185                 grep "lfm_magic:.*0x0BD70BD0" ||
3186                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3187         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3188                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3189         $LFS getstripe -v $DIR/$tdir/${tfile} |
3190                 grep "lfm_flags:.*0x0000DA05" ||
3191                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3192         $LFS getstripe $DIR/$tdir/${tfile} |
3193                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3194                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3195
3196         # modify striping should fail
3197         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3198                 error "$DIR/$tdir/$tfile: setstripe should fail"
3199
3200         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3201         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3202         cat /etc/passwd > $DIR/$tdir/$tfile &&
3203                 error "$DIR/$tdir/$tfile: write should fail"
3204
3205         # rename should succeed
3206         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/$tfile: rename has failed"
3208
3209         #remove foreign_symlink file should fail
3210         rm $DIR/$tdir/${tfile}.new &&
3211                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3212
3213         #test fake symlink
3214         mkdir /tmp/${uuid1} ||
3215                 error "/tmp/${uuid1}: mkdir has failed"
3216         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3217                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3218         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3219         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3220                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3221         #read should succeed now
3222         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3223                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3224         #write should succeed now
3225         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3226                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3227         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3228                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3229         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3230                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3231
3232         #check that getstripe still works
3233         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3234                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3235
3236         # chmod should still succeed
3237         chmod 644 $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3239
3240         # chown should still succeed
3241         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3242                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3243
3244         # rename should still succeed
3245         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3246                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3247
3248         #remove foreign_symlink file should still fail
3249         rm $DIR/$tdir/${tfile} &&
3250                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3251
3252         #use special ioctl() to unlink foreign_symlink file
3253         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3254                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3255
3256 }
3257 run_test 27O "basic ops on foreign file of symlink type"
3258
3259 test_27P() {
3260         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3261                 skip "Need MDS version newer than 2.12.49"
3262
3263         test_mkdir $DIR/$tdir
3264         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3265         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3266
3267         trap clean_foreign_symlink EXIT
3268
3269         # enable foreign_symlink behaviour
3270         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3271
3272         # foreign symlink LMV format is a partial path by default
3273
3274         # create foreign dir (lfs + API)
3275         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3276                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3277                 error "$DIR/$tdir/${tdir}: create failed"
3278
3279         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3280
3281         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3282                 grep "lfm_magic:.*0x0CD50CD0" ||
3283                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3284         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3285                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3286         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3287                 grep "lfm_flags:.*0x0000DA05" ||
3288                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3289         $LFS getdirstripe $DIR/$tdir/${tdir} |
3290                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3291                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3292
3293         # file create in dir should fail
3294         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3295         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3296
3297         # rename should succeed
3298         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3299                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3300
3301         #remove foreign_symlink dir should fail
3302         rmdir $DIR/$tdir/${tdir}.new &&
3303                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3304
3305         #test fake symlink
3306         mkdir -p /tmp/${uuid1}/${uuid2} ||
3307                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3308         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3309                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3310         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3311         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3312                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3313         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3314                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3315
3316         #check that getstripe fails now that foreign_symlink enabled
3317         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3318                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3319
3320         # file create in dir should work now
3321         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3322                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3323         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3324                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327
3328         # chmod should still succeed
3329         chmod 755 $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3331
3332         # chown should still succeed
3333         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3334                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3335
3336         # rename should still succeed
3337         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3338                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3339
3340         #remove foreign_symlink dir should still fail
3341         rmdir $DIR/$tdir/${tdir} &&
3342                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3343
3344         #use special ioctl() to unlink foreign_symlink file
3345         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3346                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3347
3348         #created file should still exist
3349         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3350                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3351         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3352                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3353 }
3354 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3355
3356 test_27Q() {
3357         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3358         stack_trap "rm -f $TMP/$tfile*"
3359
3360         test_mkdir $DIR/$tdir-1
3361         test_mkdir $DIR/$tdir-2
3362
3363         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3364         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3365
3366         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3367         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3368
3369         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3370         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3371
3372         # Create some bad symlinks and ensure that we don't loop
3373         # forever or something. These should return ELOOP (40) and
3374         # ENOENT (2) but I don't want to test for that because there's
3375         # always some weirdo architecture that needs to ruin
3376         # everything by defining these error numbers differently.
3377
3378         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3379         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3380
3381         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3382         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3383
3384         return 0
3385 }
3386 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3387
3388 test_27R() {
3389         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3390                 skip "need MDS 2.14.55 or later"
3391         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3392
3393         local testdir="$DIR/$tdir"
3394         test_mkdir -p $testdir
3395         stack_trap "rm -rf $testdir"
3396         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3397
3398         local f1="$testdir/f1"
3399         touch $f1 || error "failed to touch $f1"
3400         local count=$($LFS getstripe -c $f1)
3401         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3402
3403         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3404         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3405
3406         local maxcount=$(($OSTCOUNT - 1))
3407         local mdts=$(comma_list $(mdts_nodes))
3408         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3409         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3410
3411         local f2="$testdir/f2"
3412         touch $f2 || error "failed to touch $f2"
3413         local count=$($LFS getstripe -c $f2)
3414         (( $count == $maxcount )) || error "wrong stripe count"
3415 }
3416 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3417
3418 test_27T() {
3419         [ $(facet_host client) == $(facet_host ost1) ] &&
3420                 skip "need ost1 and client on different nodes"
3421
3422 #define OBD_FAIL_OSC_NO_GRANT            0x411
3423         $LCTL set_param fail_loc=0x20000411 fail_val=1
3424 #define OBD_FAIL_OST_ENOSPC              0x215
3425         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3426         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3427         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3428                 error "multiop failed"
3429 }
3430 run_test 27T "no eio on close on partial write due to enosp"
3431
3432 test_27U() {
3433         local dir=$DIR/$tdir
3434         local file=$dir/$tfile
3435         local append_pool=${TESTNAME}-append
3436         local normal_pool=${TESTNAME}-normal
3437         local pool
3438         local stripe_count
3439         local stripe_count2
3440         local mdts=$(comma_list $(mdts_nodes))
3441
3442         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3443                 skip "Need MDS version at least 2.15.51 for append pool feature"
3444
3445         # Validate existing append_* params and ensure restore
3446         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3447         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3448         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3449
3450         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3451         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3452         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3453
3454         pool_add $append_pool || error "pool creation failed"
3455         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3456
3457         pool_add $normal_pool || error "pool creation failed"
3458         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3459
3460         test_mkdir $dir
3461         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3462
3463         echo XXX >> $file.1
3464         $LFS getstripe $file.1
3465
3466         pool=$($LFS getstripe -p $file.1)
3467         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3468
3469         stripe_count2=$($LFS getstripe -c $file.1)
3470         ((stripe_count2 == stripe_count)) ||
3471                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3472
3473         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3474
3475         echo XXX >> $file.2
3476         $LFS getstripe $file.2
3477
3478         pool=$($LFS getstripe -p $file.2)
3479         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3480
3481         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3482
3483         echo XXX >> $file.3
3484         $LFS getstripe $file.3
3485
3486         stripe_count2=$($LFS getstripe -c $file.3)
3487         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3488 }
3489 run_test 27U "append pool and stripe count work with composite default layout"
3490
3491 # createtest also checks that device nodes are created and
3492 # then visible correctly (#2091)
3493 test_28() { # bug 2091
3494         test_mkdir $DIR/d28
3495         $CREATETEST $DIR/d28/ct || error "createtest failed"
3496 }
3497 run_test 28 "create/mknod/mkdir with bad file types ============"
3498
3499 test_29() {
3500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3501
3502         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3503                 disable_opencache
3504                 stack_trap "restore_opencache"
3505         }
3506
3507         sync; sleep 1; sync # flush out any dirty pages from previous tests
3508         cancel_lru_locks
3509         test_mkdir $DIR/d29
3510         touch $DIR/d29/foo
3511         log 'first d29'
3512         ls -l $DIR/d29
3513
3514         declare -i LOCKCOUNTORIG=0
3515         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3516                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3517         done
3518         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3519
3520         declare -i LOCKUNUSEDCOUNTORIG=0
3521         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3522                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3523         done
3524
3525         log 'second d29'
3526         ls -l $DIR/d29
3527         log 'done'
3528
3529         declare -i LOCKCOUNTCURRENT=0
3530         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3531                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3532         done
3533
3534         declare -i LOCKUNUSEDCOUNTCURRENT=0
3535         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3536                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3537         done
3538
3539         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3540                 $LCTL set_param -n ldlm.dump_namespaces ""
3541                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3542                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3543                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3544                 return 2
3545         fi
3546         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3547                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3548                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3549                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3550                 return 3
3551         fi
3552 }
3553 run_test 29 "IT_GETATTR regression  ============================"
3554
3555 test_30a() { # was test_30
3556         cp $(which ls) $DIR || cp /bin/ls $DIR
3557         $DIR/ls / || error "Can't execute binary from lustre"
3558         rm $DIR/ls
3559 }
3560 run_test 30a "execute binary from Lustre (execve) =============="
3561
3562 test_30b() {
3563         cp `which ls` $DIR || cp /bin/ls $DIR
3564         chmod go+rx $DIR/ls
3565         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3566         rm $DIR/ls
3567 }
3568 run_test 30b "execute binary from Lustre as non-root ==========="
3569
3570 test_30c() { # b=22376
3571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3572
3573         cp $(which ls) $DIR || cp /bin/ls $DIR
3574         chmod a-rw $DIR/ls
3575         cancel_lru_locks mdc
3576         cancel_lru_locks osc
3577         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3578         rm -f $DIR/ls
3579 }
3580 run_test 30c "execute binary from Lustre without read perms ===="
3581
3582 test_30d() {
3583         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3584
3585         for i in {1..10}; do
3586                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3587                 local PID=$!
3588                 sleep 1
3589                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3590                 wait $PID || error "executing dd from Lustre failed"
3591                 rm -f $DIR/$tfile
3592         done
3593
3594         rm -f $DIR/dd
3595 }
3596 run_test 30d "execute binary from Lustre while clear locks"
3597
3598 test_31a() {
3599         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3600         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3601 }
3602 run_test 31a "open-unlink file =================================="
3603
3604 test_31b() {
3605         touch $DIR/f31 || error "touch $DIR/f31 failed"
3606         ln $DIR/f31 $DIR/f31b || error "ln failed"
3607         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3608         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3609 }
3610 run_test 31b "unlink file with multiple links while open ======="
3611
3612 test_31c() {
3613         touch $DIR/f31 || error "touch $DIR/f31 failed"
3614         ln $DIR/f31 $DIR/f31c || error "ln failed"
3615         multiop_bg_pause $DIR/f31 O_uc ||
3616                 error "multiop_bg_pause for $DIR/f31 failed"
3617         MULTIPID=$!
3618         $MULTIOP $DIR/f31c Ouc
3619         kill -USR1 $MULTIPID
3620         wait $MULTIPID
3621 }
3622 run_test 31c "open-unlink file with multiple links ============="
3623
3624 test_31d() {
3625         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3626         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3627 }
3628 run_test 31d "remove of open directory ========================="
3629
3630 test_31e() { # bug 2904
3631         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3632 }
3633 run_test 31e "remove of open non-empty directory ==============="
3634
3635 test_31f() { # bug 4554
3636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3637
3638         set -vx
3639         test_mkdir $DIR/d31f
3640         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3641         cp /etc/hosts $DIR/d31f
3642         ls -l $DIR/d31f
3643         $LFS getstripe $DIR/d31f/hosts
3644         multiop_bg_pause $DIR/d31f D_c || return 1
3645         MULTIPID=$!
3646
3647         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3648         test_mkdir $DIR/d31f
3649         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3650         cp /etc/hosts $DIR/d31f
3651         ls -l $DIR/d31f
3652         $LFS getstripe $DIR/d31f/hosts
3653         multiop_bg_pause $DIR/d31f D_c || return 1
3654         MULTIPID2=$!
3655
3656         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3657         wait $MULTIPID || error "first opendir $MULTIPID failed"
3658
3659         sleep 6
3660
3661         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3662         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3663         set +vx
3664 }
3665 run_test 31f "remove of open directory with open-unlink file ==="
3666
3667 test_31g() {
3668         echo "-- cross directory link --"
3669         test_mkdir -c1 $DIR/${tdir}ga
3670         test_mkdir -c1 $DIR/${tdir}gb
3671         touch $DIR/${tdir}ga/f
3672         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3673         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3674         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3675         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3676         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3677 }
3678 run_test 31g "cross directory link==============="
3679
3680 test_31h() {
3681         echo "-- cross directory link --"
3682         test_mkdir -c1 $DIR/${tdir}
3683         test_mkdir -c1 $DIR/${tdir}/dir
3684         touch $DIR/${tdir}/f
3685         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3686         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3687         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3688         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3689         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3690 }
3691 run_test 31h "cross directory link under child==============="
3692
3693 test_31i() {
3694         echo "-- cross directory link --"
3695         test_mkdir -c1 $DIR/$tdir
3696         test_mkdir -c1 $DIR/$tdir/dir
3697         touch $DIR/$tdir/dir/f
3698         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3699         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3700         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3701         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3702         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3703 }
3704 run_test 31i "cross directory link under parent==============="
3705
3706 test_31j() {
3707         test_mkdir -c1 -p $DIR/$tdir
3708         test_mkdir -c1 -p $DIR/$tdir/dir1
3709         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3710         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3711         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3712         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3713         return 0
3714 }
3715 run_test 31j "link for directory==============="
3716
3717 test_31k() {
3718         test_mkdir -c1 -p $DIR/$tdir
3719         touch $DIR/$tdir/s
3720         touch $DIR/$tdir/exist
3721         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3722         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3723         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3724         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3725         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3726         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3727         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3728         return 0
3729 }
3730 run_test 31k "link to file: the same, non-existing, dir==============="
3731
3732 test_31m() {
3733         mkdir $DIR/d31m
3734         touch $DIR/d31m/s
3735         mkdir $DIR/d31m2
3736         touch $DIR/d31m2/exist
3737         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3738         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3739         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3740         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3741         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3742         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3743         return 0
3744 }
3745 run_test 31m "link to file: the same, non-existing, dir==============="
3746
3747 test_31n() {
3748         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3749         nlink=$(stat --format=%h $DIR/$tfile)
3750         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3751         local fd=$(free_fd)
3752         local cmd="exec $fd<$DIR/$tfile"
3753         eval $cmd
3754         cmd="exec $fd<&-"
3755         trap "eval $cmd" EXIT
3756         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3757         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3758         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3759         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3760         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3761         eval $cmd
3762 }
3763 run_test 31n "check link count of unlinked file"
3764
3765 link_one() {
3766         local tempfile=$(mktemp $1_XXXXXX)
3767         mlink $tempfile $1 2> /dev/null &&
3768                 echo "$BASHPID: link $tempfile to $1 succeeded"
3769         munlink $tempfile
3770 }
3771
3772 test_31o() { # LU-2901
3773         test_mkdir $DIR/$tdir
3774         for LOOP in $(seq 100); do
3775                 rm -f $DIR/$tdir/$tfile*
3776                 for THREAD in $(seq 8); do
3777                         link_one $DIR/$tdir/$tfile.$LOOP &
3778                 done
3779                 wait
3780                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3781                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3782                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3783                         break || true
3784         done
3785 }
3786 run_test 31o "duplicate hard links with same filename"
3787
3788 test_31p() {
3789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3790
3791         test_mkdir $DIR/$tdir
3792         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3793         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3794
3795         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3796                 error "open unlink test1 failed"
3797         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3798                 error "open unlink test2 failed"
3799
3800         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3801                 error "test1 still exists"
3802         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3803                 error "test2 still exists"
3804 }
3805 run_test 31p "remove of open striped directory"
3806
3807 test_31q() {
3808         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3809
3810         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3811         index=$($LFS getdirstripe -i $DIR/$tdir)
3812         [ $index -eq 3 ] || error "first stripe index $index != 3"
3813         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3814         [ $index -eq 1 ] || error "second stripe index $index != 1"
3815
3816         # when "-c <stripe_count>" is set, the number of MDTs specified after
3817         # "-i" should equal to the stripe count
3818         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3819 }
3820 run_test 31q "create striped directory on specific MDTs"
3821
3822 #LU-14949
3823 test_31r() {
3824         touch $DIR/$tfile.target
3825         touch $DIR/$tfile.source
3826
3827         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3828         $LCTL set_param fail_loc=0x1419 fail_val=3
3829         cat $DIR/$tfile.target &
3830         CATPID=$!
3831
3832         # Guarantee open is waiting before we get here
3833         sleep 1
3834         mv $DIR/$tfile.source $DIR/$tfile.target
3835
3836         wait $CATPID
3837         RC=$?
3838         if [[ $RC -ne 0 ]]; then
3839                 error "open with cat failed, rc=$RC"
3840         fi
3841 }
3842 run_test 31r "open-rename(replace) race"
3843
3844 cleanup_test32_mount() {
3845         local rc=0
3846         trap 0
3847         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3848         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3849         losetup -d $loopdev || true
3850         rm -rf $DIR/$tdir
3851         return $rc
3852 }
3853
3854 test_32a() {
3855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3856
3857         echo "== more mountpoints and symlinks ================="
3858         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3859         trap cleanup_test32_mount EXIT
3860         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3861         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3862                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3863         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3864                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3865         cleanup_test32_mount
3866 }
3867 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3868
3869 test_32b() {
3870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3871
3872         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3873         trap cleanup_test32_mount EXIT
3874         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3875         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3876                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3877         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3878                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3879         cleanup_test32_mount
3880 }
3881 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3882
3883 test_32c() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3887         trap cleanup_test32_mount EXIT
3888         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3889         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3890                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3891         test_mkdir -p $DIR/$tdir/d2/test_dir
3892         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3893                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3897
3898 test_32d() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         test_mkdir -p $DIR/$tdir/d2/test_dir
3907         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3908                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3909         cleanup_test32_mount
3910 }
3911 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3912
3913 test_32e() {
3914         rm -fr $DIR/$tdir
3915         test_mkdir -p $DIR/$tdir/tmp
3916         local tmp_dir=$DIR/$tdir/tmp
3917         ln -s $DIR/$tdir $tmp_dir/symlink11
3918         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3919         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3920         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3921 }
3922 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3923
3924 test_32f() {
3925         rm -fr $DIR/$tdir
3926         test_mkdir -p $DIR/$tdir/tmp
3927         local tmp_dir=$DIR/$tdir/tmp
3928         ln -s $DIR/$tdir $tmp_dir/symlink11
3929         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3930         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3931         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3932 }
3933 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3934
3935 test_32g() {
3936         local tmp_dir=$DIR/$tdir/tmp
3937         test_mkdir -p $tmp_dir
3938         test_mkdir $DIR/${tdir}2
3939         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3940         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3941         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3942         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3943         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3944         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3945 }
3946 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3947
3948 test_32h() {
3949         rm -fr $DIR/$tdir $DIR/${tdir}2
3950         tmp_dir=$DIR/$tdir/tmp
3951         test_mkdir -p $tmp_dir
3952         test_mkdir $DIR/${tdir}2
3953         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3954         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3955         ls $tmp_dir/symlink12 || error "listing symlink12"
3956         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3957 }
3958 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3959
3960 test_32i() {
3961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3962
3963         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3964         trap cleanup_test32_mount EXIT
3965         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3966         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3967                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3968         touch $DIR/$tdir/test_file
3969         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3970                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3971         cleanup_test32_mount
3972 }
3973 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3974
3975 test_32j() {
3976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3977
3978         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3979         trap cleanup_test32_mount EXIT
3980         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3981         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3982                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3983         touch $DIR/$tdir/test_file
3984         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3985                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3986         cleanup_test32_mount
3987 }
3988 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3989
3990 test_32k() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         rm -fr $DIR/$tdir
3994         trap cleanup_test32_mount EXIT
3995         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3996         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3997                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3998         test_mkdir -p $DIR/$tdir/d2
3999         touch $DIR/$tdir/d2/test_file || error "touch failed"
4000         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4001                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4002         cleanup_test32_mount
4003 }
4004 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4005
4006 test_32l() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         test_mkdir -p $DIR/$tdir/d2
4015         touch $DIR/$tdir/d2/test_file || error "touch failed"
4016         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4017                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4018         cleanup_test32_mount
4019 }
4020 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4021
4022 test_32m() {
4023         rm -fr $DIR/d32m
4024         test_mkdir -p $DIR/d32m/tmp
4025         TMP_DIR=$DIR/d32m/tmp
4026         ln -s $DIR $TMP_DIR/symlink11
4027         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4028         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4029                 error "symlink11 not a link"
4030         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4031                 error "symlink01 not a link"
4032 }
4033 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4034
4035 test_32n() {
4036         rm -fr $DIR/d32n
4037         test_mkdir -p $DIR/d32n/tmp
4038         TMP_DIR=$DIR/d32n/tmp
4039         ln -s $DIR $TMP_DIR/symlink11
4040         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4041         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4042         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4043 }
4044 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4045
4046 test_32o() {
4047         touch $DIR/$tfile
4048         test_mkdir -p $DIR/d32o/tmp
4049         TMP_DIR=$DIR/d32o/tmp
4050         ln -s $DIR/$tfile $TMP_DIR/symlink12
4051         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4052         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4053                 error "symlink12 not a link"
4054         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4055         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4056                 error "$DIR/d32o/tmp/symlink12 not file type"
4057         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4058                 error "$DIR/d32o/symlink02 not file type"
4059 }
4060 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4061
4062 test_32p() {
4063         log 32p_1
4064         rm -fr $DIR/d32p
4065         log 32p_2
4066         rm -f $DIR/$tfile
4067         log 32p_3
4068         touch $DIR/$tfile
4069         log 32p_4
4070         test_mkdir -p $DIR/d32p/tmp
4071         log 32p_5
4072         TMP_DIR=$DIR/d32p/tmp
4073         log 32p_6
4074         ln -s $DIR/$tfile $TMP_DIR/symlink12
4075         log 32p_7
4076         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4077         log 32p_8
4078         cat $DIR/d32p/tmp/symlink12 ||
4079                 error "Can't open $DIR/d32p/tmp/symlink12"
4080         log 32p_9
4081         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4082         log 32p_10
4083 }
4084 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4085
4086 test_32q() {
4087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4088
4089         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4090         trap cleanup_test32_mount EXIT
4091         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4092         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4093         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4094                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4095         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4096         cleanup_test32_mount
4097 }
4098 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4099
4100 test_32r() {
4101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4102
4103         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4104         trap cleanup_test32_mount EXIT
4105         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4106         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4107         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4108                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4109         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4110         cleanup_test32_mount
4111 }
4112 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4113
4114 test_33aa() {
4115         rm -f $DIR/$tfile
4116         touch $DIR/$tfile
4117         chmod 444 $DIR/$tfile
4118         chown $RUNAS_ID $DIR/$tfile
4119         log 33_1
4120         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4121         log 33_2
4122 }
4123 run_test 33aa "write file with mode 444 (should return error)"
4124
4125 test_33a() {
4126         rm -fr $DIR/$tdir
4127         test_mkdir $DIR/$tdir
4128         chown $RUNAS_ID $DIR/$tdir
4129         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4130                 error "$RUNAS create $tdir/$tfile failed"
4131         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4132                 error "open RDWR" || true
4133 }
4134 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4135
4136 test_33b() {
4137         rm -fr $DIR/$tdir
4138         test_mkdir $DIR/$tdir
4139         chown $RUNAS_ID $DIR/$tdir
4140         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4141 }
4142 run_test 33b "test open file with malformed flags (No panic)"
4143
4144 test_33c() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146         remote_ost_nodsh && skip "remote OST with nodsh"
4147
4148         local ostnum
4149         local ostname
4150         local write_bytes
4151         local all_zeros
4152
4153         all_zeros=true
4154         test_mkdir $DIR/$tdir
4155         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4156
4157         sync
4158         for ostnum in $(seq $OSTCOUNT); do
4159                 # test-framework's OST numbering is one-based, while Lustre's
4160                 # is zero-based
4161                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4162                 # check if at least some write_bytes stats are counted
4163                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4164                               obdfilter.$ostname.stats |
4165                               awk '/^write_bytes/ {print $7}' )
4166                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4167                 if (( ${write_bytes:-0} > 0 )); then
4168                         all_zeros=false
4169                         break
4170                 fi
4171         done
4172
4173         $all_zeros || return 0
4174
4175         # Write four bytes
4176         echo foo > $DIR/$tdir/bar
4177         # Really write them
4178         sync
4179
4180         # Total up write_bytes after writing.  We'd better find non-zeros.
4181         for ostnum in $(seq $OSTCOUNT); do
4182                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4183                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4184                               obdfilter/$ostname/stats |
4185                               awk '/^write_bytes/ {print $7}' )
4186                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4187                 if (( ${write_bytes:-0} > 0 )); then
4188                         all_zeros=false
4189                         break
4190                 fi
4191         done
4192
4193         if $all_zeros; then
4194                 for ostnum in $(seq $OSTCOUNT); do
4195                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4196                         echo "Check write_bytes is in obdfilter.*.stats:"
4197                         do_facet ost$ostnum lctl get_param -n \
4198                                 obdfilter.$ostname.stats
4199                 done
4200                 error "OST not keeping write_bytes stats (b=22312)"
4201         fi
4202 }
4203 run_test 33c "test write_bytes stats"
4204
4205 test_33d() {
4206         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4208
4209         local MDTIDX=1
4210         local remote_dir=$DIR/$tdir/remote_dir
4211
4212         test_mkdir $DIR/$tdir
4213         $LFS mkdir -i $MDTIDX $remote_dir ||
4214                 error "create remote directory failed"
4215
4216         touch $remote_dir/$tfile
4217         chmod 444 $remote_dir/$tfile
4218         chown $RUNAS_ID $remote_dir/$tfile
4219
4220         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4221
4222         chown $RUNAS_ID $remote_dir
4223         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4224                                         error "create" || true
4225         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4226                                     error "open RDWR" || true
4227         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4228 }
4229 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4230
4231 test_33e() {
4232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4233
4234         mkdir $DIR/$tdir
4235
4236         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4237         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4238         mkdir $DIR/$tdir/local_dir
4239
4240         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4241         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4242         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4243
4244         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4245                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4246
4247         rmdir $DIR/$tdir/* || error "rmdir failed"
4248
4249         umask 777
4250         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4251         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4252         mkdir $DIR/$tdir/local_dir
4253
4254         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4255         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4256         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4257
4258         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4259                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4260
4261         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4262
4263         umask 000
4264         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4265         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4266         mkdir $DIR/$tdir/local_dir
4267
4268         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4269         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4270         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4271
4272         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4273                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4274 }
4275 run_test 33e "mkdir and striped directory should have same mode"
4276
4277 cleanup_33f() {
4278         trap 0
4279         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4280 }
4281
4282 test_33f() {
4283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4284         remote_mds_nodsh && skip "remote MDS with nodsh"
4285
4286         mkdir $DIR/$tdir
4287         chmod go+rwx $DIR/$tdir
4288         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4289         trap cleanup_33f EXIT
4290
4291         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4292                 error "cannot create striped directory"
4293
4294         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4295                 error "cannot create files in striped directory"
4296
4297         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4298                 error "cannot remove files in striped directory"
4299
4300         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4301                 error "cannot remove striped directory"
4302
4303         cleanup_33f
4304 }
4305 run_test 33f "nonroot user can create, access, and remove a striped directory"
4306
4307 test_33g() {
4308         mkdir -p $DIR/$tdir/dir2
4309
4310         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4311         echo $err
4312         [[ $err =~ "exists" ]] || error "Not exists error"
4313 }
4314 run_test 33g "nonroot user create already existing root created file"
4315
4316 sub_33h() {
4317         local hash_type=$1
4318         local count=250
4319
4320         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4321                 error "lfs mkdir -H $hash_type $tdir failed"
4322         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4323
4324         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4325         local index2
4326         local fname
4327
4328         for fname in $DIR/$tdir/$tfile.bak \
4329                      $DIR/$tdir/$tfile.SAV \
4330                      $DIR/$tdir/$tfile.orig \
4331                      $DIR/$tdir/$tfile~; do
4332                 touch $fname || error "touch $fname failed"
4333                 index2=$($LFS getstripe -m $fname)
4334                 (( $index == $index2 )) ||
4335                         error "$fname MDT index mismatch $index != $index2"
4336         done
4337
4338         local failed=0
4339         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4340         local pattern
4341
4342         for pattern in ${patterns[*]}; do
4343                 echo "pattern $pattern"
4344                 fname=$DIR/$tdir/$pattern
4345                 for (( i = 0; i < $count; i++ )); do
4346                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4347                                 error "mktemp $DIR/$tdir/$pattern failed"
4348                         index2=$($LFS getstripe -m $fname)
4349                         (( $index == $index2 )) && continue
4350
4351                         failed=$((failed + 1))
4352                         echo "$fname MDT index mismatch $index != $index2"
4353                 done
4354         done
4355
4356         echo "$failed/$count MDT index mismatches, expect ~2-4"
4357         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4358
4359         local same=0
4360         local expect
4361
4362         # verify that "crush" is still broken with all files on same MDT,
4363         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4364         [[ "$hash_type" == "crush" ]] && expect=$count ||
4365                 expect=$((count / MDSCOUNT))
4366
4367         # crush2 doesn't put all-numeric suffixes on the same MDT,
4368         # filename like $tfile.12345678 should *not* be considered temp
4369         for pattern in ${patterns[*]}; do
4370                 local base=${pattern%%X*}
4371                 local suff=${pattern#$base}
4372
4373                 echo "pattern $pattern"
4374                 for (( i = 0; i < $count; i++ )); do
4375                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4376                         touch $fname || error "touch $fname failed"
4377                         index2=$($LFS getstripe -m $fname)
4378                         (( $index != $index2 )) && continue
4379
4380                         same=$((same + 1))
4381                 done
4382         done
4383
4384         # the number of "bad" hashes is random, as it depends on the random
4385         # filenames generated by "mktemp".  Allow some margin in the results.
4386         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4387         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4388            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4389                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4390         same=0
4391
4392         # crush2 doesn't put suffixes with special characters on the same MDT
4393         # filename like $tfile.txt.1234 should *not* be considered temp
4394         for pattern in ${patterns[*]}; do
4395                 local base=${pattern%%X*}
4396                 local suff=${pattern#$base}
4397
4398                 pattern=$base...${suff/XXX}
4399                 echo "pattern=$pattern"
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4402                                 error "touch $fname failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index != $index2 )) && continue
4405
4406                         same=$((same + 1))
4407                 done
4408         done
4409
4410         # the number of "bad" hashes is random, as it depends on the random
4411         # filenames generated by "mktemp".  Allow some margin in the results.
4412         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4413         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4414            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4415                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4416 }
4417
4418 test_33h() {
4419         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4420         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4421                 skip "Need MDS version at least 2.13.50"
4422
4423         sub_33h crush
4424 }
4425 run_test 33h "temp file is located on the same MDT as target (crush)"
4426
4427 test_33hh() {
4428         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4429         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4430         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4431                 skip "Need MDS version at least 2.15.0 for crush2"
4432
4433         sub_33h crush2
4434 }
4435 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4436
4437 test_33i()
4438 {
4439         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4440
4441         local FNAME=$(str_repeat 'f' 250)
4442
4443         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4444         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4445
4446         local count
4447         local total
4448
4449         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4450
4451         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4452
4453         lctl --device %$MDC deactivate
4454         stack_trap "lctl --device %$MDC activate"
4455         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4456         total=$(\ls -l $DIR/$tdir | wc -l)
4457         # "ls -l" will list total in the first line
4458         total=$((total - 1))
4459         (( total + count == 1000 )) ||
4460                 error "ls list $total files, $count files on MDT1"
4461 }
4462 run_test 33i "striped directory can be accessed when one MDT is down"
4463
4464 test_33j() {
4465         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4466
4467         mkdir -p $DIR/$tdir/
4468
4469         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4470                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4471
4472         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4473                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4474
4475         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4476                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4477
4478         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4479                 error "-D was not specified, but still failed"
4480 }
4481 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4482
4483 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4484 test_34a() {
4485         rm -f $DIR/f34
4486         $MCREATE $DIR/f34 || error "mcreate failed"
4487         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4488                 error "getstripe failed"
4489         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4490         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4491                 error "getstripe failed"
4492         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4493                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4494 }
4495 run_test 34a "truncate file that has not been opened ==========="
4496
4497 test_34b() {
4498         [ ! -f $DIR/f34 ] && test_34a
4499         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4500                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4501         $OPENFILE -f O_RDONLY $DIR/f34
4502         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4503                 error "getstripe failed"
4504         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4505                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4506 }
4507 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4508
4509 test_34c() {
4510         [ ! -f $DIR/f34 ] && test_34a
4511         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4512                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4513         $OPENFILE -f O_RDWR $DIR/f34
4514         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4515                 error "$LFS getstripe failed"
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4517                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4518 }
4519 run_test 34c "O_RDWR opening file-with-size works =============="
4520
4521 test_34d() {
4522         [ ! -f $DIR/f34 ] && test_34a
4523         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4524                 error "dd failed"
4525         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4526                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4527         rm $DIR/f34
4528 }
4529 run_test 34d "write to sparse file ============================="
4530
4531 test_34e() {
4532         rm -f $DIR/f34e
4533         $MCREATE $DIR/f34e || error "mcreate failed"
4534         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4535         $CHECKSTAT -s 1000 $DIR/f34e ||
4536                 error "Size of $DIR/f34e not equal to 1000 bytes"
4537         $OPENFILE -f O_RDWR $DIR/f34e
4538         $CHECKSTAT -s 1000 $DIR/f34e ||
4539                 error "Size of $DIR/f34e not equal to 1000 bytes"
4540 }
4541 run_test 34e "create objects, some with size and some without =="
4542
4543 test_34f() { # bug 6242, 6243
4544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4545
4546         SIZE34F=48000
4547         rm -f $DIR/f34f
4548         $MCREATE $DIR/f34f || error "mcreate failed"
4549         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4550         dd if=$DIR/f34f of=$TMP/f34f
4551         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4552         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4553         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4554         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4555         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4556 }
4557 run_test 34f "read from a file with no objects until EOF ======="
4558
4559 test_34g() {
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4563                 error "dd failed"
4564         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4565         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4566                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4567         cancel_lru_locks osc
4568         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4569                 error "wrong size after lock cancel"
4570
4571         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4572         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4573                 error "expanding truncate failed"
4574         cancel_lru_locks osc
4575         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4576                 error "wrong expanded size after lock cancel"
4577 }
4578 run_test 34g "truncate long file ==============================="
4579
4580 test_34h() {
4581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4582
4583         local gid=10
4584         local sz=1000
4585
4586         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4587         sync # Flush the cache so that multiop below does not block on cache
4588              # flush when getting the group lock
4589         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4590         MULTIPID=$!
4591
4592         # Since just timed wait is not good enough, let's do a sync write
4593         # that way we are sure enough time for a roundtrip + processing
4594         # passed + 2 seconds of extra margin.
4595         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4596         rm $DIR/${tfile}-1
4597         sleep 2
4598
4599         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4600                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4601                 kill -9 $MULTIPID
4602         fi
4603         wait $MULTIPID
4604         local nsz=`stat -c %s $DIR/$tfile`
4605         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4606 }
4607 run_test 34h "ftruncate file under grouplock should not block"
4608
4609 test_35a() {
4610         cp /bin/sh $DIR/f35a
4611         chmod 444 $DIR/f35a
4612         chown $RUNAS_ID $DIR/f35a
4613         $RUNAS $DIR/f35a && error || true
4614         rm $DIR/f35a
4615 }
4616 run_test 35a "exec file with mode 444 (should return and not leak)"
4617
4618 test_36a() {
4619         rm -f $DIR/f36
4620         utime $DIR/f36 || error "utime failed for MDS"
4621 }
4622 run_test 36a "MDS utime check (mknod, utime)"
4623
4624 test_36b() {
4625         echo "" > $DIR/f36
4626         utime $DIR/f36 || error "utime failed for OST"
4627 }
4628 run_test 36b "OST utime check (open, utime)"
4629
4630 test_36c() {
4631         rm -f $DIR/d36/f36
4632         test_mkdir $DIR/d36
4633         chown $RUNAS_ID $DIR/d36
4634         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4635 }
4636 run_test 36c "non-root MDS utime check (mknod, utime)"
4637
4638 test_36d() {
4639         [ ! -d $DIR/d36 ] && test_36c
4640         echo "" > $DIR/d36/f36
4641         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4642 }
4643 run_test 36d "non-root OST utime check (open, utime)"
4644
4645 test_36e() {
4646         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4647
4648         test_mkdir $DIR/$tdir
4649         touch $DIR/$tdir/$tfile
4650         $RUNAS utime $DIR/$tdir/$tfile &&
4651                 error "utime worked, expected failure" || true
4652 }
4653 run_test 36e "utime on non-owned file (should return error)"
4654
4655 subr_36fh() {
4656         local fl="$1"
4657         local LANG_SAVE=$LANG
4658         local LC_LANG_SAVE=$LC_LANG
4659         export LANG=C LC_LANG=C # for date language
4660
4661         DATESTR="Dec 20  2000"
4662         test_mkdir $DIR/$tdir
4663         lctl set_param fail_loc=$fl
4664         date; date +%s
4665         cp /etc/hosts $DIR/$tdir/$tfile
4666         sync & # write RPC generated with "current" inode timestamp, but delayed
4667         sleep 1
4668         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4669         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4670         cancel_lru_locks $OSC
4671         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4672         date; date +%s
4673         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4674                 echo "BEFORE: $LS_BEFORE" && \
4675                 echo "AFTER : $LS_AFTER" && \
4676                 echo "WANT  : $DATESTR" && \
4677                 error "$DIR/$tdir/$tfile timestamps changed" || true
4678
4679         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4680 }
4681
4682 test_36f() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4686         subr_36fh "0x80000214"
4687 }
4688 run_test 36f "utime on file racing with OST BRW write =========="
4689
4690 test_36g() {
4691         remote_ost_nodsh && skip "remote OST with nodsh"
4692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4693         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4694                 skip "Need MDS version at least 2.12.51"
4695
4696         local fmd_max_age
4697         local fmd
4698         local facet="ost1"
4699         local tgt="obdfilter"
4700
4701         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4702
4703         test_mkdir $DIR/$tdir
4704         fmd_max_age=$(do_facet $facet \
4705                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4706                 head -n 1")
4707
4708         echo "FMD max age: ${fmd_max_age}s"
4709         touch $DIR/$tdir/$tfile
4710         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4711                 gawk '{cnt=cnt+$1}  END{print cnt}')
4712         echo "FMD before: $fmd"
4713         [[ $fmd == 0 ]] &&
4714                 error "FMD wasn't create by touch"
4715         sleep $((fmd_max_age + 12))
4716         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4717                 gawk '{cnt=cnt+$1}  END{print cnt}')
4718         echo "FMD after: $fmd"
4719         [[ $fmd == 0 ]] ||
4720                 error "FMD wasn't expired by ping"
4721 }
4722 run_test 36g "FMD cache expiry ====================="
4723
4724 test_36h() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4728         subr_36fh "0x80000227"
4729 }
4730 run_test 36h "utime on file racing with OST BRW write =========="
4731
4732 test_36i() {
4733         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4734
4735         test_mkdir $DIR/$tdir
4736         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4737
4738         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4739         local new_mtime=$((mtime + 200))
4740
4741         #change Modify time of striped dir
4742         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4743                         error "change mtime failed"
4744
4745         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4746
4747         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4748 }
4749 run_test 36i "change mtime on striped directory"
4750
4751 # test_37 - duplicate with tests 32q 32r
4752
4753 test_38() {
4754         local file=$DIR/$tfile
4755         touch $file
4756         openfile -f O_DIRECTORY $file
4757         local RC=$?
4758         local ENOTDIR=20
4759         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4760         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4761 }
4762 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4763
4764 test_39a() { # was test_39
4765         touch $DIR/$tfile
4766         touch $DIR/${tfile}2
4767 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4768 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4769 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4770         sleep 2
4771         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4772         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4773                 echo "mtime"
4774                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4775                 echo "atime"
4776                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4777                 echo "ctime"
4778                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4779                 error "O_TRUNC didn't change timestamps"
4780         fi
4781 }
4782 run_test 39a "mtime changed on create"
4783
4784 test_39b() {
4785         test_mkdir -c1 $DIR/$tdir
4786         cp -p /etc/passwd $DIR/$tdir/fopen
4787         cp -p /etc/passwd $DIR/$tdir/flink
4788         cp -p /etc/passwd $DIR/$tdir/funlink
4789         cp -p /etc/passwd $DIR/$tdir/frename
4790         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4791
4792         sleep 1
4793         echo "aaaaaa" >> $DIR/$tdir/fopen
4794         echo "aaaaaa" >> $DIR/$tdir/flink
4795         echo "aaaaaa" >> $DIR/$tdir/funlink
4796         echo "aaaaaa" >> $DIR/$tdir/frename
4797
4798         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4799         local link_new=`stat -c %Y $DIR/$tdir/flink`
4800         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4801         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4802
4803         cat $DIR/$tdir/fopen > /dev/null
4804         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4805         rm -f $DIR/$tdir/funlink2
4806         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4807
4808         for (( i=0; i < 2; i++ )) ; do
4809                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4810                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4811                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4812                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4813
4814                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4815                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4816                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4817                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4818
4819                 cancel_lru_locks $OSC
4820                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4821         done
4822 }
4823 run_test 39b "mtime change on open, link, unlink, rename  ======"
4824
4825 # this should be set to past
4826 TEST_39_MTIME=`date -d "1 year ago" +%s`
4827
4828 # bug 11063
4829 test_39c() {
4830         touch $DIR1/$tfile
4831         sleep 2
4832         local mtime0=`stat -c %Y $DIR1/$tfile`
4833
4834         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4835         local mtime1=`stat -c %Y $DIR1/$tfile`
4836         [ "$mtime1" = $TEST_39_MTIME ] || \
4837                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4838
4839         local d1=`date +%s`
4840         echo hello >> $DIR1/$tfile
4841         local d2=`date +%s`
4842         local mtime2=`stat -c %Y $DIR1/$tfile`
4843         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4844                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4845
4846         mv $DIR1/$tfile $DIR1/$tfile-1
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4850                 [ "$mtime2" = "$mtime3" ] || \
4851                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39c "mtime change on rename ==========================="
4858
4859 # bug 21114
4860 test_39d() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         touch $DIR1/$tfile
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4870
4871                 cancel_lru_locks $OSC
4872                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4873         done
4874 }
4875 run_test 39d "create, utime, stat =============================="
4876
4877 # bug 21114
4878 test_39e() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         touch $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4885
4886         for (( i=0; i < 2; i++ )) ; do
4887                 local mtime2=`stat -c %Y $DIR1/$tfile`
4888                 [ $mtime2 = $TEST_39_MTIME ] || \
4889                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4890
4891                 cancel_lru_locks $OSC
4892                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4893         done
4894 }
4895 run_test 39e "create, stat, utime, stat ========================"
4896
4897 # bug 21114
4898 test_39f() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         touch $DIR1/$tfile
4902         mtime1=`stat -c %Y $DIR1/$tfile`
4903
4904         sleep 2
4905         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4906
4907         for (( i=0; i < 2; i++ )) ; do
4908                 local mtime2=`stat -c %Y $DIR1/$tfile`
4909                 [ $mtime2 = $TEST_39_MTIME ] || \
4910                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4911
4912                 cancel_lru_locks $OSC
4913                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4914         done
4915 }
4916 run_test 39f "create, stat, sleep, utime, stat ================="
4917
4918 # bug 11063
4919 test_39g() {
4920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4921
4922         echo hello >> $DIR1/$tfile
4923         local mtime1=`stat -c %Y $DIR1/$tfile`
4924
4925         sleep 2
4926         chmod o+r $DIR1/$tfile
4927
4928         for (( i=0; i < 2; i++ )) ; do
4929                 local mtime2=`stat -c %Y $DIR1/$tfile`
4930                 [ "$mtime1" = "$mtime2" ] || \
4931                         error "lost mtime: $mtime2, should be $mtime1"
4932
4933                 cancel_lru_locks $OSC
4934                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4935         done
4936 }
4937 run_test 39g "write, chmod, stat ==============================="
4938
4939 # bug 11063
4940 test_39h() {
4941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4942
4943         touch $DIR1/$tfile
4944         sleep 1
4945
4946         local d1=`date`
4947         echo hello >> $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949
4950         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4951         local d2=`date`
4952         if [ "$d1" != "$d2" ]; then
4953                 echo "write and touch not within one second"
4954         else
4955                 for (( i=0; i < 2; i++ )) ; do
4956                         local mtime2=`stat -c %Y $DIR1/$tfile`
4957                         [ "$mtime2" = $TEST_39_MTIME ] || \
4958                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4959
4960                         cancel_lru_locks $OSC
4961                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4962                 done
4963         fi
4964 }
4965 run_test 39h "write, utime within one second, stat ============="
4966
4967 test_39i() {
4968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4969
4970         touch $DIR1/$tfile
4971         sleep 1
4972
4973         echo hello >> $DIR1/$tfile
4974         local mtime1=`stat -c %Y $DIR1/$tfile`
4975
4976         mv $DIR1/$tfile $DIR1/$tfile-1
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4980
4981                 [ "$mtime1" = "$mtime2" ] || \
4982                         error "lost mtime: $mtime2, should be $mtime1"
4983
4984                 cancel_lru_locks $OSC
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39i "write, rename, stat =============================="
4989
4990 test_39j() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         start_full_debug_logging
4994         touch $DIR1/$tfile
4995         sleep 1
4996
4997         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4998         lctl set_param fail_loc=0x80000412
4999         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5000                 error "multiop failed"
5001         local multipid=$!
5002         local mtime1=`stat -c %Y $DIR1/$tfile`
5003
5004         mv $DIR1/$tfile $DIR1/$tfile-1
5005
5006         kill -USR1 $multipid
5007         wait $multipid || error "multiop close failed"
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5011                 [ "$mtime1" = "$mtime2" ] ||
5012                         error "mtime is lost on close: $mtime2, " \
5013                               "should be $mtime1"
5014
5015                 cancel_lru_locks
5016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017         done
5018         lctl set_param fail_loc=0
5019         stop_full_debug_logging
5020 }
5021 run_test 39j "write, rename, close, stat ======================="
5022
5023 test_39k() {
5024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5025
5026         touch $DIR1/$tfile
5027         sleep 1
5028
5029         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5030         local multipid=$!
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5034
5035         kill -USR1 $multipid
5036         wait $multipid || error "multiop close failed"
5037
5038         for (( i=0; i < 2; i++ )) ; do
5039                 local mtime2=`stat -c %Y $DIR1/$tfile`
5040
5041                 [ "$mtime2" = $TEST_39_MTIME ] || \
5042                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5043
5044                 cancel_lru_locks
5045                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5046         done
5047 }
5048 run_test 39k "write, utime, close, stat ========================"
5049
5050 # this should be set to future
5051 TEST_39_ATIME=`date -d "1 year" +%s`
5052
5053 test_39l() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055         remote_mds_nodsh && skip "remote MDS with nodsh"
5056
5057         local atime_diff=$(do_facet $SINGLEMDS \
5058                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5059         rm -rf $DIR/$tdir
5060         mkdir_on_mdt0 $DIR/$tdir
5061
5062         # test setting directory atime to future
5063         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5064         local atime=$(stat -c %X $DIR/$tdir)
5065         [ "$atime" = $TEST_39_ATIME ] ||
5066                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5067
5068         # test setting directory atime from future to now
5069         local now=$(date +%s)
5070         touch -a -d @$now $DIR/$tdir
5071
5072         atime=$(stat -c %X $DIR/$tdir)
5073         [ "$atime" -eq "$now"  ] ||
5074                 error "atime is not updated from future: $atime, $now"
5075
5076         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5077         sleep 3
5078
5079         # test setting directory atime when now > dir atime + atime_diff
5080         local d1=$(date +%s)
5081         ls $DIR/$tdir
5082         local d2=$(date +%s)
5083         cancel_lru_locks mdc
5084         atime=$(stat -c %X $DIR/$tdir)
5085         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5086                 error "atime is not updated  : $atime, should be $d2"
5087
5088         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5089         sleep 3
5090
5091         # test not setting directory atime when now < dir atime + atime_diff
5092         ls $DIR/$tdir
5093         cancel_lru_locks mdc
5094         atime=$(stat -c %X $DIR/$tdir)
5095         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5096                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5097
5098         do_facet $SINGLEMDS \
5099                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5100 }
5101 run_test 39l "directory atime update ==========================="
5102
5103 test_39m() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105
5106         touch $DIR1/$tfile
5107         sleep 2
5108         local far_past_mtime=$(date -d "May 29 1953" +%s)
5109         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5110
5111         touch -m -d @$far_past_mtime $DIR1/$tfile
5112         touch -a -d @$far_past_atime $DIR1/$tfile
5113
5114         for (( i=0; i < 2; i++ )) ; do
5115                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5116                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5117                         error "atime or mtime set incorrectly"
5118
5119                 cancel_lru_locks $OSC
5120                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5121         done
5122 }
5123 run_test 39m "test atime and mtime before 1970"
5124
5125 test_39n() { # LU-3832
5126         remote_mds_nodsh && skip "remote MDS with nodsh"
5127
5128         local atime_diff=$(do_facet $SINGLEMDS \
5129                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5130         local atime0
5131         local atime1
5132         local atime2
5133
5134         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5135
5136         rm -rf $DIR/$tfile
5137         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5138         atime0=$(stat -c %X $DIR/$tfile)
5139
5140         sleep 5
5141         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5142         atime1=$(stat -c %X $DIR/$tfile)
5143
5144         sleep 5
5145         cancel_lru_locks mdc
5146         cancel_lru_locks osc
5147         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5148         atime2=$(stat -c %X $DIR/$tfile)
5149
5150         do_facet $SINGLEMDS \
5151                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5152
5153         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5154         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5155 }
5156 run_test 39n "check that O_NOATIME is honored"
5157
5158 test_39o() {
5159         TESTDIR=$DIR/$tdir/$tfile
5160         [ -e $TESTDIR ] && rm -rf $TESTDIR
5161         mkdir -p $TESTDIR
5162         cd $TESTDIR
5163         links1=2
5164         ls
5165         mkdir a b
5166         ls
5167         links2=$(stat -c %h .)
5168         [ $(($links1 + 2)) != $links2 ] &&
5169                 error "wrong links count $(($links1 + 2)) != $links2"
5170         rmdir b
5171         links3=$(stat -c %h .)
5172         [ $(($links1 + 1)) != $links3 ] &&
5173                 error "wrong links count $links1 != $links3"
5174         return 0
5175 }
5176 run_test 39o "directory cached attributes updated after create"
5177
5178 test_39p() {
5179         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5180
5181         local MDTIDX=1
5182         TESTDIR=$DIR/$tdir/$tdir
5183         [ -e $TESTDIR ] && rm -rf $TESTDIR
5184         test_mkdir -p $TESTDIR
5185         cd $TESTDIR
5186         links1=2
5187         ls
5188         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5189         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5190         ls
5191         links2=$(stat -c %h .)
5192         [ $(($links1 + 2)) != $links2 ] &&
5193                 error "wrong links count $(($links1 + 2)) != $links2"
5194         rmdir remote_dir2
5195         links3=$(stat -c %h .)
5196         [ $(($links1 + 1)) != $links3 ] &&
5197                 error "wrong links count $links1 != $links3"
5198         return 0
5199 }
5200 run_test 39p "remote directory cached attributes updated after create ========"
5201
5202 test_39r() {
5203         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5204                 skip "no atime update on old OST"
5205         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5206                 skip_env "ldiskfs only test"
5207         fi
5208
5209         local saved_adiff
5210         saved_adiff=$(do_facet ost1 \
5211                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5212         stack_trap "do_facet ost1 \
5213                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5214
5215         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5216
5217         $LFS setstripe -i 0 $DIR/$tfile
5218         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5219                 error "can't write initial file"
5220         cancel_lru_locks osc
5221
5222         # exceed atime_diff and access file
5223         sleep 10
5224         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5225                 error "can't udpate atime"
5226
5227         local atime_cli=$(stat -c %X $DIR/$tfile)
5228         echo "client atime: $atime_cli"
5229         # allow atime update to be written to device
5230         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5231         sleep 5
5232
5233         local ostdev=$(ostdevname 1)
5234         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5235         local seq=${fid[3]#0x}
5236         local oid=${fid[1]}
5237         local oid_hex
5238
5239         if [ $seq == 0 ]; then
5240                 oid_hex=${fid[1]}
5241         else
5242                 oid_hex=${fid[2]#0x}
5243         fi
5244         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5245         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5246
5247         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5248         local atime_ost=$(do_facet ost1 "$cmd" |&
5249                           awk -F'[: ]' '/atime:/ { print $4 }')
5250         (( atime_cli == atime_ost )) ||
5251                 error "atime on client $atime_cli != ost $atime_ost"
5252 }
5253 run_test 39r "lazy atime update on OST"
5254
5255 test_39q() { # LU-8041
5256         local testdir=$DIR/$tdir
5257         mkdir -p $testdir
5258         multiop_bg_pause $testdir D_c || error "multiop failed"
5259         local multipid=$!
5260         cancel_lru_locks mdc
5261         kill -USR1 $multipid
5262         local atime=$(stat -c %X $testdir)
5263         [ "$atime" -ne 0 ] || error "atime is zero"
5264 }
5265 run_test 39q "close won't zero out atime"
5266
5267 test_39s() {
5268         local atime0
5269         local atime1
5270         local atime2
5271         local atime3
5272         local atime4
5273
5274         umount_client $MOUNT
5275         mount_client $MOUNT relatime
5276
5277         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5278         atime0=$(stat -c %X $DIR/$tfile)
5279
5280         # First read updates atime
5281         sleep 1
5282         cat $DIR/$tfile >/dev/null
5283         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5284
5285         # Next reads do not update atime
5286         sleep 1
5287         cat $DIR/$tfile >/dev/null
5288         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5289
5290         # If mtime is greater than atime, atime is updated
5291         sleep 1
5292         touch -m $DIR/$tfile # (mtime = now)
5293         sleep 1
5294         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5295         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5296
5297         # Next reads do not update atime
5298         sleep 1
5299         cat $DIR/$tfile >/dev/null
5300         atime4=$(stat -c %X $DIR/$tfile)
5301
5302         # Remount the client to clear 'relatime' option
5303         remount_client $MOUNT
5304
5305         (( atime0 < atime1 )) ||
5306                 error "atime $atime0 should be smaller than $atime1"
5307         (( atime1 == atime2 )) ||
5308                 error "atime $atime1 was updated to $atime2"
5309         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5310         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5311 }
5312 run_test 39s "relatime is supported"
5313
5314 test_40() {
5315         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5316         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5317                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5318         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5319                 error "$tfile is not 4096 bytes in size"
5320 }
5321 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5322
5323 test_41() {
5324         # bug 1553
5325         small_write $DIR/f41 18
5326 }
5327 run_test 41 "test small file write + fstat ====================="
5328
5329 count_ost_writes() {
5330         lctl get_param -n ${OSC}.*.stats |
5331                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5332                         END { printf("%0.0f", writes) }'
5333 }
5334
5335 # decent default
5336 WRITEBACK_SAVE=500
5337 DIRTY_RATIO_SAVE=40
5338 MAX_DIRTY_RATIO=50
5339 BG_DIRTY_RATIO_SAVE=10
5340 MAX_BG_DIRTY_RATIO=25
5341
5342 start_writeback() {
5343         trap 0
5344         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5345         # dirty_ratio, dirty_background_ratio
5346         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5347                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5348                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5349                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5350         else
5351                 # if file not here, we are a 2.4 kernel
5352                 kill -CONT `pidof kupdated`
5353         fi
5354 }
5355
5356 stop_writeback() {
5357         # setup the trap first, so someone cannot exit the test at the
5358         # exact wrong time and mess up a machine
5359         trap start_writeback EXIT
5360         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5361         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5362                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5363                 sysctl -w vm.dirty_writeback_centisecs=0
5364                 sysctl -w vm.dirty_writeback_centisecs=0
5365                 # save and increase /proc/sys/vm/dirty_ratio
5366                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5367                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5368                 # save and increase /proc/sys/vm/dirty_background_ratio
5369                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5370                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5371         else
5372                 # if file not here, we are a 2.4 kernel
5373                 kill -STOP `pidof kupdated`
5374         fi
5375 }
5376
5377 # ensure that all stripes have some grant before we test client-side cache
5378 setup_test42() {
5379         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5380                 dd if=/dev/zero of=$i bs=4k count=1
5381                 rm $i
5382         done
5383 }
5384
5385 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5386 # file truncation, and file removal.
5387 test_42a() {
5388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5389
5390         setup_test42
5391         cancel_lru_locks $OSC
5392         stop_writeback
5393         sync; sleep 1; sync # just to be safe
5394         BEFOREWRITES=`count_ost_writes`
5395         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5396         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5397         AFTERWRITES=`count_ost_writes`
5398         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5399                 error "$BEFOREWRITES < $AFTERWRITES"
5400         start_writeback
5401 }
5402 run_test 42a "ensure that we don't flush on close"
5403
5404 test_42b() {
5405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5406
5407         setup_test42
5408         cancel_lru_locks $OSC
5409         stop_writeback
5410         sync
5411         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5412         BEFOREWRITES=$(count_ost_writes)
5413         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5414         AFTERWRITES=$(count_ost_writes)
5415         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5416                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5417         fi
5418         BEFOREWRITES=$(count_ost_writes)
5419         sync || error "sync: $?"
5420         AFTERWRITES=$(count_ost_writes)
5421         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5422                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5423         fi
5424         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5425         start_writeback
5426         return 0
5427 }
5428 run_test 42b "test destroy of file with cached dirty data ======"
5429
5430 # if these tests just want to test the effect of truncation,
5431 # they have to be very careful.  consider:
5432 # - the first open gets a {0,EOF}PR lock
5433 # - the first write conflicts and gets a {0, count-1}PW
5434 # - the rest of the writes are under {count,EOF}PW
5435 # - the open for truncate tries to match a {0,EOF}PR
5436 #   for the filesize and cancels the PWs.
5437 # any number of fixes (don't get {0,EOF} on open, match
5438 # composite locks, do smarter file size management) fix
5439 # this, but for now we want these tests to verify that
5440 # the cancellation with truncate intent works, so we
5441 # start the file with a full-file pw lock to match against
5442 # until the truncate.
5443 trunc_test() {
5444         test=$1
5445         file=$DIR/$test
5446         offset=$2
5447         cancel_lru_locks $OSC
5448         stop_writeback
5449         # prime the file with 0,EOF PW to match
5450         touch $file
5451         $TRUNCATE $file 0
5452         sync; sync
5453         # now the real test..
5454         dd if=/dev/zero of=$file bs=1024 count=100
5455         BEFOREWRITES=`count_ost_writes`
5456         $TRUNCATE $file $offset
5457         cancel_lru_locks $OSC
5458         AFTERWRITES=`count_ost_writes`
5459         start_writeback
5460 }
5461
5462 test_42c() {
5463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5464
5465         trunc_test 42c 1024
5466         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5467                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5468         rm $file
5469 }
5470 run_test 42c "test partial truncate of file with cached dirty data"
5471
5472 test_42d() {
5473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5474
5475         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5476         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5477         $LCTL set_param debug=+cache
5478
5479         trunc_test 42d 0
5480         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5481                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5482         rm $file
5483 }
5484 run_test 42d "test complete truncate of file with cached dirty data"
5485
5486 test_42e() { # bug22074
5487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5488
5489         local TDIR=$DIR/${tdir}e
5490         local pages=16 # hardcoded 16 pages, don't change it.
5491         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5492         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5493         local max_dirty_mb
5494         local warmup_files
5495
5496         test_mkdir $DIR/${tdir}e
5497         $LFS setstripe -c 1 $TDIR
5498         createmany -o $TDIR/f $files
5499
5500         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5501
5502         # we assume that with $OSTCOUNT files, at least one of them will
5503         # be allocated on OST0.
5504         warmup_files=$((OSTCOUNT * max_dirty_mb))
5505         createmany -o $TDIR/w $warmup_files
5506
5507         # write a large amount of data into one file and sync, to get good
5508         # avail_grant number from OST.
5509         for ((i=0; i<$warmup_files; i++)); do
5510                 idx=$($LFS getstripe -i $TDIR/w$i)
5511                 [ $idx -ne 0 ] && continue
5512                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5513                 break
5514         done
5515         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5516         sync
5517         $LCTL get_param $proc_osc0/cur_dirty_bytes
5518         $LCTL get_param $proc_osc0/cur_grant_bytes
5519
5520         # create as much dirty pages as we can while not to trigger the actual
5521         # RPCs directly. but depends on the env, VFS may trigger flush during this
5522         # period, hopefully we are good.
5523         for ((i=0; i<$warmup_files; i++)); do
5524                 idx=$($LFS getstripe -i $TDIR/w$i)
5525                 [ $idx -ne 0 ] && continue
5526                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5527         done
5528         $LCTL get_param $proc_osc0/cur_dirty_bytes
5529         $LCTL get_param $proc_osc0/cur_grant_bytes
5530
5531         # perform the real test
5532         $LCTL set_param $proc_osc0/rpc_stats 0
5533         for ((;i<$files; i++)); do
5534                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5535                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5536         done
5537         sync
5538         $LCTL get_param $proc_osc0/rpc_stats
5539
5540         local percent=0
5541         local have_ppr=false
5542         $LCTL get_param $proc_osc0/rpc_stats |
5543                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5544                         # skip lines until we are at the RPC histogram data
5545                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5546                         $have_ppr || continue
5547
5548                         # we only want the percent stat for < 16 pages
5549                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5550
5551                         percent=$((percent + WPCT))
5552                         if [[ $percent -gt 15 ]]; then
5553                                 error "less than 16-pages write RPCs" \
5554                                       "$percent% > 15%"
5555                                 break
5556                         fi
5557                 done
5558         rm -rf $TDIR
5559 }
5560 run_test 42e "verify sub-RPC writes are not done synchronously"
5561
5562 test_43A() { # was test_43
5563         test_mkdir $DIR/$tdir
5564         cp -p /bin/ls $DIR/$tdir/$tfile
5565         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5566         pid=$!
5567         # give multiop a chance to open
5568         sleep 1
5569
5570         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5571         kill -USR1 $pid
5572         # Wait for multiop to exit
5573         wait $pid
5574 }
5575 run_test 43A "execution of file opened for write should return -ETXTBSY"
5576
5577 test_43a() {
5578         test_mkdir $DIR/$tdir
5579         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5580         $DIR/$tdir/sleep 60 &
5581         SLEEP_PID=$!
5582         # Make sure exec of $tdir/sleep wins race with truncate
5583         sleep 1
5584         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5585         kill $SLEEP_PID
5586 }
5587 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5588
5589 test_43b() {
5590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5591
5592         test_mkdir $DIR/$tdir
5593         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5594         $DIR/$tdir/sleep 60 &
5595         SLEEP_PID=$!
5596         # Make sure exec of $tdir/sleep wins race with truncate
5597         sleep 1
5598         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5599         kill $SLEEP_PID
5600 }
5601 run_test 43b "truncate of file being executed should return -ETXTBSY"
5602
5603 test_43c() {
5604         local testdir="$DIR/$tdir"
5605         test_mkdir $testdir
5606         cp $SHELL $testdir/
5607         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5608                 ( cd $testdir && md5sum -c )
5609 }
5610 run_test 43c "md5sum of copy into lustre"
5611
5612 test_44A() { # was test_44
5613         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5614
5615         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5616         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5617 }
5618 run_test 44A "zero length read from a sparse stripe"
5619
5620 test_44a() {
5621         local nstripe=$($LFS getstripe -c -d $DIR)
5622         [ -z "$nstripe" ] && skip "can't get stripe info"
5623         [[ $nstripe -gt $OSTCOUNT ]] &&
5624                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5625
5626         local stride=$($LFS getstripe -S -d $DIR)
5627         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5628                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5629         fi
5630
5631         OFFSETS="0 $((stride/2)) $((stride-1))"
5632         for offset in $OFFSETS; do
5633                 for i in $(seq 0 $((nstripe-1))); do
5634                         local GLOBALOFFSETS=""
5635                         # size in Bytes
5636                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5637                         local myfn=$DIR/d44a-$size
5638                         echo "--------writing $myfn at $size"
5639                         ll_sparseness_write $myfn $size ||
5640                                 error "ll_sparseness_write"
5641                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5642                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5643                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5644
5645                         for j in $(seq 0 $((nstripe-1))); do
5646                                 # size in Bytes
5647                                 size=$((((j + $nstripe )*$stride + $offset)))
5648                                 ll_sparseness_write $myfn $size ||
5649                                         error "ll_sparseness_write"
5650                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5651                         done
5652                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5653                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5654                         rm -f $myfn
5655                 done
5656         done
5657 }
5658 run_test 44a "test sparse pwrite ==============================="
5659
5660 dirty_osc_total() {
5661         tot=0
5662         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5663                 tot=$(($tot + $d))
5664         done
5665         echo $tot
5666 }
5667 do_dirty_record() {
5668         before=`dirty_osc_total`
5669         echo executing "\"$*\""
5670         eval $*
5671         after=`dirty_osc_total`
5672         echo before $before, after $after
5673 }
5674 test_45() {
5675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5676
5677         f="$DIR/f45"
5678         # Obtain grants from OST if it supports it
5679         echo blah > ${f}_grant
5680         stop_writeback
5681         sync
5682         do_dirty_record "echo blah > $f"
5683         [[ $before -eq $after ]] && error "write wasn't cached"
5684         do_dirty_record "> $f"
5685         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5686         do_dirty_record "echo blah > $f"
5687         [[ $before -eq $after ]] && error "write wasn't cached"
5688         do_dirty_record "sync"
5689         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5690         do_dirty_record "echo blah > $f"
5691         [[ $before -eq $after ]] && error "write wasn't cached"
5692         do_dirty_record "cancel_lru_locks osc"
5693         [[ $before -gt $after ]] ||
5694                 error "lock cancellation didn't lower dirty count"
5695         start_writeback
5696 }
5697 run_test 45 "osc io page accounting ============================"
5698
5699 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5700 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5701 # objects offset and an assert hit when an rpc was built with 1023's mapped
5702 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5703 test_46() {
5704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5705
5706         f="$DIR/f46"
5707         stop_writeback
5708         sync
5709         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5710         sync
5711         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5712         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5713         sync
5714         start_writeback
5715 }
5716 run_test 46 "dirtying a previously written page ================"
5717
5718 # test_47 is removed "Device nodes check" is moved to test_28
5719
5720 test_48a() { # bug 2399
5721         [ "$mds1_FSTYPE" = "zfs" ] &&
5722         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5723                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5724
5725         test_mkdir $DIR/$tdir
5726         cd $DIR/$tdir
5727         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5728         test_mkdir $DIR/$tdir
5729         touch foo || error "'touch foo' failed after recreating cwd"
5730         test_mkdir bar
5731         touch .foo || error "'touch .foo' failed after recreating cwd"
5732         test_mkdir .bar
5733         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5734         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5735         cd . || error "'cd .' failed after recreating cwd"
5736         mkdir . && error "'mkdir .' worked after recreating cwd"
5737         rmdir . && error "'rmdir .' worked after recreating cwd"
5738         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5739         cd .. || error "'cd ..' failed after recreating cwd"
5740 }
5741 run_test 48a "Access renamed working dir (should return errors)="
5742
5743 test_48b() { # bug 2399
5744         rm -rf $DIR/$tdir
5745         test_mkdir $DIR/$tdir
5746         cd $DIR/$tdir
5747         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5748         touch foo && error "'touch foo' worked after removing cwd"
5749         mkdir foo && error "'mkdir foo' worked after removing cwd"
5750         touch .foo && error "'touch .foo' worked after removing cwd"
5751         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5752         ls . > /dev/null && error "'ls .' worked after removing cwd"
5753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5754         mkdir . && error "'mkdir .' worked after removing cwd"
5755         rmdir . && error "'rmdir .' worked after removing cwd"
5756         ln -s . foo && error "'ln -s .' worked after removing cwd"
5757         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5758 }
5759 run_test 48b "Access removed working dir (should return errors)="
5760
5761 test_48c() { # bug 2350
5762         #lctl set_param debug=-1
5763         #set -vx
5764         rm -rf $DIR/$tdir
5765         test_mkdir -p $DIR/$tdir/dir
5766         cd $DIR/$tdir/dir
5767         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5768         $TRACE touch foo && error "touch foo worked after removing cwd"
5769         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5770         touch .foo && error "touch .foo worked after removing cwd"
5771         mkdir .foo && error "mkdir .foo worked after removing cwd"
5772         $TRACE ls . && error "'ls .' worked after removing cwd"
5773         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5774         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5775         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5776         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5777         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5778 }
5779 run_test 48c "Access removed working subdir (should return errors)"
5780
5781 test_48d() { # bug 2350
5782         #lctl set_param debug=-1
5783         #set -vx
5784         rm -rf $DIR/$tdir
5785         test_mkdir -p $DIR/$tdir/dir
5786         cd $DIR/$tdir/dir
5787         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5788         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5789         $TRACE touch foo && error "'touch foo' worked after removing parent"
5790         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5791         touch .foo && error "'touch .foo' worked after removing parent"
5792         mkdir .foo && error "mkdir .foo worked after removing parent"
5793         $TRACE ls . && error "'ls .' worked after removing parent"
5794         $TRACE ls .. && error "'ls ..' worked after removing parent"
5795         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5796         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5797         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5798         true
5799 }
5800 run_test 48d "Access removed parent subdir (should return errors)"
5801
5802 test_48e() { # bug 4134
5803         #lctl set_param debug=-1
5804         #set -vx
5805         rm -rf $DIR/$tdir
5806         test_mkdir -p $DIR/$tdir/dir
5807         cd $DIR/$tdir/dir
5808         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5809         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5810         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5811         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5812         # On a buggy kernel addition of "touch foo" after cd .. will
5813         # produce kernel oops in lookup_hash_it
5814         touch ../foo && error "'cd ..' worked after recreate parent"
5815         cd $DIR
5816         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5817 }
5818 run_test 48e "Access to recreated parent subdir (should return errors)"
5819
5820 test_48f() {
5821         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5822                 skip "need MDS >= 2.13.55"
5823         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5824         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5825                 skip "needs different host for mdt1 mdt2"
5826         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5827
5828         $LFS mkdir -i0 $DIR/$tdir
5829         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5830
5831         for d in sub1 sub2 sub3; do
5832                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5833                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5834                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5835         done
5836
5837         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5838 }
5839 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5840
5841 test_49() { # LU-1030
5842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5843         remote_ost_nodsh && skip "remote OST with nodsh"
5844
5845         # get ost1 size - $FSNAME-OST0000
5846         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5847                 awk '{ print $4 }')
5848         # write 800M at maximum
5849         [[ $ost1_size -lt 2 ]] && ost1_size=2
5850         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5851
5852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5853         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5854         local dd_pid=$!
5855
5856         # change max_pages_per_rpc while writing the file
5857         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5858         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5859         # loop until dd process exits
5860         while ps ax -opid | grep -wq $dd_pid; do
5861                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5862                 sleep $((RANDOM % 5 + 1))
5863         done
5864         # restore original max_pages_per_rpc
5865         $LCTL set_param $osc1_mppc=$orig_mppc
5866         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5867 }
5868 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5869
5870 test_50() {
5871         # bug 1485
5872         test_mkdir $DIR/$tdir
5873         cd $DIR/$tdir
5874         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5875 }
5876 run_test 50 "special situations: /proc symlinks  ==============="
5877
5878 test_51a() {    # was test_51
5879         # bug 1516 - create an empty entry right after ".." then split dir
5880         test_mkdir -c1 $DIR/$tdir
5881         touch $DIR/$tdir/foo
5882         $MCREATE $DIR/$tdir/bar
5883         rm $DIR/$tdir/foo
5884         createmany -m $DIR/$tdir/longfile 201
5885         FNUM=202
5886         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5887                 $MCREATE $DIR/$tdir/longfile$FNUM
5888                 FNUM=$(($FNUM + 1))
5889                 echo -n "+"
5890         done
5891         echo
5892         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5893 }
5894 run_test 51a "special situations: split htree with empty entry =="
5895
5896 cleanup_print_lfs_df () {
5897         trap 0
5898         $LFS df
5899         $LFS df -i
5900 }
5901
5902 test_51b() {
5903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5904
5905         local dir=$DIR/$tdir
5906         local nrdirs=$((65536 + 100))
5907
5908         # cleanup the directory
5909         rm -fr $dir
5910
5911         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5912
5913         $LFS df
5914         $LFS df -i
5915         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5916         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5917         [[ $numfree -lt $nrdirs ]] &&
5918                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5919
5920         # need to check free space for the directories as well
5921         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5922         numfree=$(( blkfree / $(fs_inode_ksize) ))
5923         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5924
5925         trap cleanup_print_lfs_df EXIT
5926
5927         # create files
5928         createmany -d $dir/d $nrdirs || {
5929                 unlinkmany $dir/d $nrdirs
5930                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5931         }
5932
5933         # really created :
5934         nrdirs=$(ls -U $dir | wc -l)
5935
5936         # unlink all but 100 subdirectories, then check it still works
5937         local left=100
5938         local delete=$((nrdirs - left))
5939
5940         $LFS df
5941         $LFS df -i
5942
5943         # for ldiskfs the nlink count should be 1, but this is OSD specific
5944         # and so this is listed for informational purposes only
5945         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5946         unlinkmany -d $dir/d $delete ||
5947                 error "unlink of first $delete subdirs failed"
5948
5949         echo "nlink between: $(stat -c %h $dir)"
5950         local found=$(ls -U $dir | wc -l)
5951         [ $found -ne $left ] &&
5952                 error "can't find subdirs: found only $found, expected $left"
5953
5954         unlinkmany -d $dir/d $delete $left ||
5955                 error "unlink of second $left subdirs failed"
5956         # regardless of whether the backing filesystem tracks nlink accurately
5957         # or not, the nlink count shouldn't be more than "." and ".." here
5958         local after=$(stat -c %h $dir)
5959         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5960                 echo "nlink after: $after"
5961
5962         cleanup_print_lfs_df
5963 }
5964 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5965
5966 test_51d_sub() {
5967         local stripecount=$1
5968         local nfiles=$2
5969
5970         log "create files with stripecount=$stripecount"
5971         $LFS setstripe -C $stripecount $DIR/$tdir
5972         createmany -o $DIR/$tdir/t- $nfiles
5973         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5974         for ((n = 0; n < $OSTCOUNT; n++)); do
5975                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5976                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5977                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5978                             '($1 == '$n') { objs += 1 } \
5979                             END { printf("%0.0f", objs) }')
5980                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5981         done
5982         unlinkmany $DIR/$tdir/t- $nfiles
5983         rm  -f $TMP/$tfile
5984
5985         local nlast
5986         local min=4
5987         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5988
5989         # For some combinations of stripecount and OSTCOUNT current code
5990         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5991         # than others. Rather than skipping this test entirely, check that
5992         # and keep testing to ensure imbalance does not get worse. LU-15282
5993         (( (OSTCOUNT == 6 && stripecount == 4) ||
5994            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5995            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5996         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5997                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5998                         { $LFS df && $LFS df -i &&
5999                         error "stripecount=$stripecount: " \
6000                               "OST $n has fewer objects vs. OST $nlast " \
6001                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6002                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6003                         { $LFS df && $LFS df -i &&
6004                         error "stripecount=$stripecount: " \
6005                               "OST $n has more objects vs. OST $nlast " \
6006                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6007
6008                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6009                         { $LFS df && $LFS df -i &&
6010                         error "stripecount=$stripecount: " \
6011                               "OST $n has fewer #0 objects vs. OST $nlast " \
6012                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6013                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6014                         { $LFS df && $LFS df -i &&
6015                         error "stripecount=$stripecount: " \
6016                               "OST $n has more #0 objects vs. OST $nlast " \
6017                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6018         done
6019 }
6020
6021 test_51d() {
6022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6023         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6024
6025         local stripecount
6026         local per_ost=100
6027         local nfiles=$((per_ost * OSTCOUNT))
6028         local mdts=$(comma_list $(mdts_nodes))
6029         local param="osp.*.create_count"
6030         local qos_old=$(do_facet mds1 \
6031                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6032
6033         do_nodes $mdts \
6034                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6035         stack_trap "do_nodes $mdts \
6036                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6037
6038         test_mkdir $DIR/$tdir
6039         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6040         (( dirstripes > 0 )) || dirstripes=1
6041
6042         # Ensure enough OST objects precreated for tests to pass without
6043         # running out of objects.  This is an LOV r-r OST algorithm test,
6044         # not an OST object precreation test.
6045         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6046         (( old >= nfiles )) ||
6047         {
6048                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6049
6050                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6051                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6052
6053                 # trigger precreation from all MDTs for all OSTs
6054                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6055                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6056                 done
6057         }
6058
6059         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6060                 sleep 8  # allow object precreation to catch up
6061                 test_51d_sub $stripecount $nfiles
6062         done
6063 }
6064 run_test 51d "check LOV round-robin OST object distribution"
6065
6066 test_51e() {
6067         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6068                 skip_env "ldiskfs only test"
6069         fi
6070
6071         test_mkdir -c1 $DIR/$tdir
6072         test_mkdir -c1 $DIR/$tdir/d0
6073
6074         touch $DIR/$tdir/d0/foo
6075         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6076                 error "file exceed 65000 nlink limit!"
6077         unlinkmany $DIR/$tdir/d0/f- 65001
6078         return 0
6079 }
6080 run_test 51e "check file nlink limit"
6081
6082 test_51f() {
6083         test_mkdir $DIR/$tdir
6084
6085         local max=100000
6086         local ulimit_old=$(ulimit -n)
6087         local spare=20 # number of spare fd's for scripts/libraries, etc.
6088         local mdt=$($LFS getstripe -m $DIR/$tdir)
6089         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6090
6091         echo "MDT$mdt numfree=$numfree, max=$max"
6092         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6093         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6094                 while ! ulimit -n $((numfree + spare)); do
6095                         numfree=$((numfree * 3 / 4))
6096                 done
6097                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6098         else
6099                 echo "left ulimit at $ulimit_old"
6100         fi
6101
6102         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6103                 unlinkmany $DIR/$tdir/f $numfree
6104                 error "create+open $numfree files in $DIR/$tdir failed"
6105         }
6106         ulimit -n $ulimit_old
6107
6108         # if createmany exits at 120s there will be fewer than $numfree files
6109         unlinkmany $DIR/$tdir/f $numfree || true
6110 }
6111 run_test 51f "check many open files limit"
6112
6113 test_52a() {
6114         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6115         test_mkdir $DIR/$tdir
6116         touch $DIR/$tdir/foo
6117         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6118         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6119         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6120         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6121         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6122                                         error "link worked"
6123         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6124         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6125         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6126                                                      error "lsattr"
6127         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6128         cp -r $DIR/$tdir $TMP/
6129         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6130 }
6131 run_test 52a "append-only flag test (should return errors)"
6132
6133 test_52b() {
6134         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6135         test_mkdir $DIR/$tdir
6136         touch $DIR/$tdir/foo
6137         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6138         cat test > $DIR/$tdir/foo && error "cat test worked"
6139         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6140         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6141         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6142                                         error "link worked"
6143         echo foo >> $DIR/$tdir/foo && error "echo worked"
6144         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6145         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6146         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6147         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6148                                                         error "lsattr"
6149         chattr -i $DIR/$tdir/foo || error "chattr failed"
6150
6151         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6152 }
6153 run_test 52b "immutable flag test (should return errors) ======="
6154
6155 test_53() {
6156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6157         remote_mds_nodsh && skip "remote MDS with nodsh"
6158         remote_ost_nodsh && skip "remote OST with nodsh"
6159
6160         local param
6161         local param_seq
6162         local ostname
6163         local mds_last
6164         local mds_last_seq
6165         local ost_last
6166         local ost_last_seq
6167         local ost_last_id
6168         local ostnum
6169         local node
6170         local found=false
6171         local support_last_seq=true
6172
6173         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6174                 support_last_seq=false
6175
6176         # only test MDT0000
6177         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6178         local value
6179         for value in $(do_facet $SINGLEMDS \
6180                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6181                 param=$(echo ${value[0]} | cut -d "=" -f1)
6182                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6183
6184                 if $support_last_seq; then
6185                         param_seq=$(echo $param |
6186                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6187                         mds_last_seq=$(do_facet $SINGLEMDS \
6188                                        $LCTL get_param -n $param_seq)
6189                 fi
6190                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6191
6192                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6193                 node=$(facet_active_host ost$((ostnum+1)))
6194                 param="obdfilter.$ostname.last_id"
6195                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6196                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6197                         ost_last_id=$ost_last
6198
6199                         if $support_last_seq; then
6200                                 ost_last_id=$(echo $ost_last |
6201                                               awk -F':' '{print $2}' |
6202                                               sed -e "s/^0x//g")
6203                                 ost_last_seq=$(echo $ost_last |
6204                                                awk -F':' '{print $1}')
6205                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6206                         fi
6207
6208                         if [[ $ost_last_id != $mds_last ]]; then
6209                                 error "$ost_last_id != $mds_last"
6210                         else
6211                                 found=true
6212                                 break
6213                         fi
6214                 done
6215         done
6216         $found || error "can not match last_seq/last_id for $mdtosc"
6217         return 0
6218 }
6219 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6220
6221 test_54a() {
6222         perl -MSocket -e ';' || skip "no Socket perl module installed"
6223
6224         $SOCKETSERVER $DIR/socket ||
6225                 error "$SOCKETSERVER $DIR/socket failed: $?"
6226         $SOCKETCLIENT $DIR/socket ||
6227                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6228         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6229 }
6230 run_test 54a "unix domain socket test =========================="
6231
6232 test_54b() {
6233         f="$DIR/f54b"
6234         mknod $f c 1 3
6235         chmod 0666 $f
6236         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6237 }
6238 run_test 54b "char device works in lustre ======================"
6239
6240 find_loop_dev() {
6241         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6242         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6243         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6244
6245         for i in $(seq 3 7); do
6246                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6247                 LOOPDEV=$LOOPBASE$i
6248                 LOOPNUM=$i
6249                 break
6250         done
6251 }
6252
6253 cleanup_54c() {
6254         local rc=0
6255         loopdev="$DIR/loop54c"
6256
6257         trap 0
6258         $UMOUNT $DIR/$tdir || rc=$?
6259         losetup -d $loopdev || true
6260         losetup -d $LOOPDEV || true
6261         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6262         return $rc
6263 }
6264
6265 test_54c() {
6266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6267
6268         loopdev="$DIR/loop54c"
6269
6270         find_loop_dev
6271         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6272         trap cleanup_54c EXIT
6273         mknod $loopdev b 7 $LOOPNUM
6274         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6275         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6276         losetup $loopdev $DIR/$tfile ||
6277                 error "can't set up $loopdev for $DIR/$tfile"
6278         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6279         test_mkdir $DIR/$tdir
6280         mount -t ext2 $loopdev $DIR/$tdir ||
6281                 error "error mounting $loopdev on $DIR/$tdir"
6282         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6283                 error "dd write"
6284         df $DIR/$tdir
6285         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6286                 error "dd read"
6287         cleanup_54c
6288 }
6289 run_test 54c "block device works in lustre ====================="
6290
6291 test_54d() {
6292         local pipe="$DIR/$tfile.pipe"
6293         local string="aaaaaa"
6294
6295         mknod $pipe p
6296         echo -n "$string" > $pipe &
6297         local result=$(cat $pipe)
6298         [[ "$result" == "$string" ]] || error "$result != $string"
6299 }
6300 run_test 54d "fifo device works in lustre ======================"
6301
6302 test_54e() {
6303         f="$DIR/f54e"
6304         string="aaaaaa"
6305         cp -aL /dev/console $f
6306         echo $string > $f || error "echo $string to $f failed"
6307 }
6308 run_test 54e "console/tty device works in lustre ======================"
6309
6310 test_56a() {
6311         local numfiles=3
6312         local numdirs=2
6313         local dir=$DIR/$tdir
6314
6315         rm -rf $dir
6316         test_mkdir -p $dir/dir
6317         for i in $(seq $numfiles); do
6318                 touch $dir/file$i
6319                 touch $dir/dir/file$i
6320         done
6321
6322         local numcomp=$($LFS getstripe --component-count $dir)
6323
6324         [[ $numcomp == 0 ]] && numcomp=1
6325
6326         # test lfs getstripe with --recursive
6327         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6328
6329         [[ $filenum -eq $((numfiles * 2)) ]] ||
6330                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6331         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6332         [[ $filenum -eq $numfiles ]] ||
6333                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6334         echo "$LFS getstripe showed obdidx or l_ost_idx"
6335
6336         # test lfs getstripe with file instead of dir
6337         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6338         [[ $filenum -eq 1 ]] ||
6339                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6340         echo "$LFS getstripe file1 passed"
6341
6342         #test lfs getstripe with --verbose
6343         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6344         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6345                 error "$LFS getstripe --verbose $dir: "\
6346                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6347         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6348                 error "$LFS getstripe $dir: showed lmm_magic"
6349
6350         #test lfs getstripe with -v prints lmm_fid
6351         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6352         local countfids=$((numdirs + numfiles * numcomp))
6353         [[ $filenum -eq $countfids ]] ||
6354                 error "$LFS getstripe -v $dir: "\
6355                       "got $filenum want $countfids lmm_fid"
6356         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6357                 error "$LFS getstripe $dir: showed lmm_fid by default"
6358         echo "$LFS getstripe --verbose passed"
6359
6360         #check for FID information
6361         local fid1=$($LFS getstripe --fid $dir/file1)
6362         local fid2=$($LFS getstripe --verbose $dir/file1 |
6363                      awk '/lmm_fid: / { print $2; exit; }')
6364         local fid3=$($LFS path2fid $dir/file1)
6365
6366         [ "$fid1" != "$fid2" ] &&
6367                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6368         [ "$fid1" != "$fid3" ] &&
6369                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6370         echo "$LFS getstripe --fid passed"
6371
6372         #test lfs getstripe with --obd
6373         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6374                 error "$LFS getstripe --obd wrong_uuid: should return error"
6375
6376         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6377
6378         local ostidx=1
6379         local obduuid=$(ostuuid_from_index $ostidx)
6380         local found=$($LFS getstripe -r --obd $obduuid $dir |
6381                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6382
6383         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6384         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6385                 ((filenum--))
6386         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6387                 ((filenum--))
6388
6389         [[ $found -eq $filenum ]] ||
6390                 error "$LFS getstripe --obd: found $found expect $filenum"
6391         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6392                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6393                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6394                 error "$LFS getstripe --obd: should not show file on other obd"
6395         echo "$LFS getstripe --obd passed"
6396 }
6397 run_test 56a "check $LFS getstripe"
6398
6399 test_56b() {
6400         local dir=$DIR/$tdir
6401         local numdirs=3
6402
6403         test_mkdir $dir
6404         for i in $(seq $numdirs); do
6405                 test_mkdir $dir/dir$i
6406         done
6407
6408         # test lfs getdirstripe default mode is non-recursion, which is
6409         # different from lfs getstripe
6410         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6411
6412         [[ $dircnt -eq 1 ]] ||
6413                 error "$LFS getdirstripe: found $dircnt, not 1"
6414         dircnt=$($LFS getdirstripe --recursive $dir |
6415                 grep -c lmv_stripe_count)
6416         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6417                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6418 }
6419 run_test 56b "check $LFS getdirstripe"
6420
6421 test_56c() {
6422         remote_ost_nodsh && skip "remote OST with nodsh"
6423
6424         local ost_idx=0
6425         local ost_name=$(ostname_from_index $ost_idx)
6426         local old_status=$(ost_dev_status $ost_idx)
6427         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6428
6429         [[ -z "$old_status" ]] ||
6430                 skip_env "OST $ost_name is in $old_status status"
6431
6432         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6433         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6434                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6435         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6436                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6437                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6438         fi
6439
6440         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6441                 error "$LFS df -v showing inactive devices"
6442         sleep_maxage
6443
6444         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6445
6446         [[ "$new_status" =~ "D" ]] ||
6447                 error "$ost_name status is '$new_status', missing 'D'"
6448         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6449                 [[ "$new_status" =~ "N" ]] ||
6450                         error "$ost_name status is '$new_status', missing 'N'"
6451         fi
6452         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6453                 [[ "$new_status" =~ "f" ]] ||
6454                         error "$ost_name status is '$new_status', missing 'f'"
6455         fi
6456
6457         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6458         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6459                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6460         [[ -z "$p" ]] && restore_lustre_params < $p || true
6461         sleep_maxage
6462
6463         new_status=$(ost_dev_status $ost_idx)
6464         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6465                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6466         # can't check 'f' as devices may actually be on flash
6467 }
6468 run_test 56c "check 'lfs df' showing device status"
6469
6470 test_56d() {
6471         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6472         local osts=$($LFS df -v $MOUNT | grep -c OST)
6473
6474         $LFS df $MOUNT
6475
6476         (( mdts == MDSCOUNT )) ||
6477                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6478         (( osts == OSTCOUNT )) ||
6479                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6480 }
6481 run_test 56d "'lfs df -v' prints only configured devices"
6482
6483 test_56e() {
6484         err_enoent=2 # No such file or directory
6485         err_eopnotsupp=95 # Operation not supported
6486
6487         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6488         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6489
6490         # Check for handling of path not exists
6491         output=$($LFS df $enoent_mnt 2>&1)
6492         ret=$?
6493
6494         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6495         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6496                 error "expect failure $err_enoent, not $ret"
6497
6498         # Check for handling of non-Lustre FS
6499         output=$($LFS df $notsup_mnt)
6500         ret=$?
6501
6502         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6503         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6504                 error "expect success $err_eopnotsupp, not $ret"
6505
6506         # Check for multiple LustreFS argument
6507         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6508         ret=$?
6509
6510         [[ $output -eq 3 && $ret -eq 0 ]] ||
6511                 error "expect success 3, not $output, rc = $ret"
6512
6513         # Check for correct non-Lustre FS handling among multiple
6514         # LustreFS argument
6515         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6516                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6517         ret=$?
6518
6519         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6520                 error "expect success 2, not $output, rc = $ret"
6521 }
6522 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6523
6524 NUMFILES=3
6525 NUMDIRS=3
6526 setup_56() {
6527         local local_tdir="$1"
6528         local local_numfiles="$2"
6529         local local_numdirs="$3"
6530         local dir_params="$4"
6531         local dir_stripe_params="$5"
6532
6533         if [ ! -d "$local_tdir" ] ; then
6534                 test_mkdir -p $dir_stripe_params $local_tdir
6535                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6536                 for i in $(seq $local_numfiles) ; do
6537                         touch $local_tdir/file$i
6538                 done
6539                 for i in $(seq $local_numdirs) ; do
6540                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6541                         for j in $(seq $local_numfiles) ; do
6542                                 touch $local_tdir/dir$i/file$j
6543                         done
6544                 done
6545         fi
6546 }
6547
6548 setup_56_special() {
6549         local local_tdir=$1
6550         local local_numfiles=$2
6551         local local_numdirs=$3
6552
6553         setup_56 $local_tdir $local_numfiles $local_numdirs
6554
6555         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6556                 for i in $(seq $local_numfiles) ; do
6557                         mknod $local_tdir/loop${i}b b 7 $i
6558                         mknod $local_tdir/null${i}c c 1 3
6559                         ln -s $local_tdir/file1 $local_tdir/link${i}
6560                 done
6561                 for i in $(seq $local_numdirs) ; do
6562                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6563                         mknod $local_tdir/dir$i/null${i}c c 1 3
6564                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6565                 done
6566         fi
6567 }
6568
6569 test_56g() {
6570         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6571         local expected=$(($NUMDIRS + 2))
6572
6573         setup_56 $dir $NUMFILES $NUMDIRS
6574
6575         # test lfs find with -name
6576         for i in $(seq $NUMFILES) ; do
6577                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6578
6579                 [ $nums -eq $expected ] ||
6580                         error "lfs find -name '*$i' $dir wrong: "\
6581                               "found $nums, expected $expected"
6582         done
6583 }
6584 run_test 56g "check lfs find -name"
6585
6586 test_56h() {
6587         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6588         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6589
6590         setup_56 $dir $NUMFILES $NUMDIRS
6591
6592         # test lfs find with ! -name
6593         for i in $(seq $NUMFILES) ; do
6594                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6595
6596                 [ $nums -eq $expected ] ||
6597                         error "lfs find ! -name '*$i' $dir wrong: "\
6598                               "found $nums, expected $expected"
6599         done
6600 }
6601 run_test 56h "check lfs find ! -name"
6602
6603 test_56i() {
6604         local dir=$DIR/$tdir
6605
6606         test_mkdir $dir
6607
6608         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6609         local out=$($cmd)
6610
6611         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6612 }
6613 run_test 56i "check 'lfs find -ost UUID' skips directories"
6614
6615 test_56j() {
6616         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6617
6618         setup_56_special $dir $NUMFILES $NUMDIRS
6619
6620         local expected=$((NUMDIRS + 1))
6621         local cmd="$LFS find -type d $dir"
6622         local nums=$($cmd | wc -l)
6623
6624         [ $nums -eq $expected ] ||
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626 }
6627 run_test 56j "check lfs find -type d"
6628
6629 test_56k() {
6630         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6631
6632         setup_56_special $dir $NUMFILES $NUMDIRS
6633
6634         local expected=$(((NUMDIRS + 1) * NUMFILES))
6635         local cmd="$LFS find -type f $dir"
6636         local nums=$($cmd | wc -l)
6637
6638         [ $nums -eq $expected ] ||
6639                 error "'$cmd' wrong: found $nums, expected $expected"
6640 }
6641 run_test 56k "check lfs find -type f"
6642
6643 test_56l() {
6644         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6645
6646         setup_56_special $dir $NUMFILES $NUMDIRS
6647
6648         local expected=$((NUMDIRS + NUMFILES))
6649         local cmd="$LFS find -type b $dir"
6650         local nums=$($cmd | wc -l)
6651
6652         [ $nums -eq $expected ] ||
6653                 error "'$cmd' wrong: found $nums, expected $expected"
6654 }
6655 run_test 56l "check lfs find -type b"
6656
6657 test_56m() {
6658         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6659
6660         setup_56_special $dir $NUMFILES $NUMDIRS
6661
6662         local expected=$((NUMDIRS + NUMFILES))
6663         local cmd="$LFS find -type c $dir"
6664         local nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56m "check lfs find -type c"
6669
6670 test_56n() {
6671         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6672         setup_56_special $dir $NUMFILES $NUMDIRS
6673
6674         local expected=$((NUMDIRS + NUMFILES))
6675         local cmd="$LFS find -type l $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56n "check lfs find -type l"
6682
6683 test_56o() {
6684         local dir=$DIR/$tdir
6685
6686         setup_56 $dir $NUMFILES $NUMDIRS
6687         utime $dir/file1 > /dev/null || error "utime (1)"
6688         utime $dir/file2 > /dev/null || error "utime (2)"
6689         utime $dir/dir1 > /dev/null || error "utime (3)"
6690         utime $dir/dir2 > /dev/null || error "utime (4)"
6691         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6692         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6693
6694         local expected=4
6695         local nums=$($LFS find -mtime +0 $dir | wc -l)
6696
6697         [ $nums -eq $expected ] ||
6698                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6699
6700         expected=12
6701         cmd="$LFS find -mtime 0 $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705 }
6706 run_test 56o "check lfs find -mtime for old files"
6707
6708 test_56ob() {
6709         local dir=$DIR/$tdir
6710         local expected=1
6711         local count=0
6712
6713         # just to make sure there is something that won't be found
6714         test_mkdir $dir
6715         touch $dir/$tfile.now
6716
6717         for age in year week day hour min; do
6718                 count=$((count + 1))
6719
6720                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6721                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6722                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6723
6724                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6725                 local nums=$($cmd | wc -l)
6726                 [ $nums -eq $expected ] ||
6727                         error "'$cmd' wrong: found $nums, expected $expected"
6728
6729                 cmd="$LFS find $dir -atime $count${age:0:1}"
6730                 nums=$($cmd | wc -l)
6731                 [ $nums -eq $expected ] ||
6732                         error "'$cmd' wrong: found $nums, expected $expected"
6733         done
6734
6735         sleep 2
6736         cmd="$LFS find $dir -ctime +1s -type f"
6737         nums=$($cmd | wc -l)
6738         (( $nums == $count * 2 + 1)) ||
6739                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6740 }
6741 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6742
6743 test_newerXY_base() {
6744         local x=$1
6745         local y=$2
6746         local dir=$DIR/$tdir
6747         local ref
6748         local negref
6749
6750         if [ $y == "t" ]; then
6751                 if [ $x == "b" ]; then
6752                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6753                 else
6754                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6755                 fi
6756         else
6757                 ref=$DIR/$tfile.newer.$x$y
6758                 touch $ref || error "touch $ref failed"
6759         fi
6760
6761         echo "before = $ref"
6762         sleep 2
6763         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6764         sleep 2
6765         if [ $y == "t" ]; then
6766                 if [ $x == "b" ]; then
6767                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6768                 else
6769                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6770                 fi
6771         else
6772                 negref=$DIR/$tfile.negnewer.$x$y
6773                 touch $negref || error "touch $negref failed"
6774         fi
6775
6776         echo "after = $negref"
6777         local cmd="$LFS find $dir -newer$x$y $ref"
6778         local nums=$(eval $cmd | wc -l)
6779         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6780
6781         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6782                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6783
6784         cmd="$LFS find $dir ! -newer$x$y $negref"
6785         nums=$(eval $cmd | wc -l)
6786         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6787                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6788
6789         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6790         nums=$(eval $cmd | wc -l)
6791         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6792                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6793
6794         rm -rf $DIR/*
6795 }
6796
6797 test_56oc() {
6798         test_newerXY_base "a" "a"
6799         test_newerXY_base "a" "m"
6800         test_newerXY_base "a" "c"
6801         test_newerXY_base "m" "a"
6802         test_newerXY_base "m" "m"
6803         test_newerXY_base "m" "c"
6804         test_newerXY_base "c" "a"
6805         test_newerXY_base "c" "m"
6806         test_newerXY_base "c" "c"
6807
6808         test_newerXY_base "a" "t"
6809         test_newerXY_base "m" "t"
6810         test_newerXY_base "c" "t"
6811
6812         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6813            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6814                 ! btime_supported && echo "btime unsupported" && return 0
6815
6816         test_newerXY_base "b" "b"
6817         test_newerXY_base "b" "t"
6818 }
6819 run_test 56oc "check lfs find -newerXY work"
6820
6821 btime_supported() {
6822         local dir=$DIR/$tdir
6823         local rc
6824
6825         mkdir -p $dir
6826         touch $dir/$tfile
6827         $LFS find $dir -btime -1d -type f
6828         rc=$?
6829         rm -rf $dir
6830         return $rc
6831 }
6832
6833 test_56od() {
6834         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6835                 ! btime_supported && skip "btime unsupported on MDS"
6836
6837         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6838                 ! btime_supported && skip "btime unsupported on clients"
6839
6840         local dir=$DIR/$tdir
6841         local ref=$DIR/$tfile.ref
6842         local negref=$DIR/$tfile.negref
6843
6844         mkdir $dir || error "mkdir $dir failed"
6845         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6846         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6847         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6848         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6849         touch $ref || error "touch $ref failed"
6850         # sleep 3 seconds at least
6851         sleep 3
6852
6853         local before=$(do_facet mds1 date +%s)
6854         local skew=$(($(date +%s) - before + 1))
6855
6856         if (( skew < 0 && skew > -5 )); then
6857                 sleep $((0 - skew + 1))
6858                 skew=0
6859         fi
6860
6861         # Set the dir stripe params to limit files all on MDT0,
6862         # otherwise we need to calc the max clock skew between
6863         # the client and MDTs.
6864         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6865         sleep 2
6866         touch $negref || error "touch $negref failed"
6867
6868         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6869         local nums=$($cmd | wc -l)
6870         local expected=$(((NUMFILES + 1) * NUMDIRS))
6871
6872         [ $nums -eq $expected ] ||
6873                 error "'$cmd' wrong: found $nums, expected $expected"
6874
6875         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6876         nums=$($cmd | wc -l)
6877         expected=$((NUMFILES + 1))
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880
6881         [ $skew -lt 0 ] && return
6882
6883         local after=$(do_facet mds1 date +%s)
6884         local age=$((after - before + 1 + skew))
6885
6886         cmd="$LFS find $dir -btime -${age}s -type f"
6887         nums=$($cmd | wc -l)
6888         expected=$(((NUMFILES + 1) * NUMDIRS))
6889
6890         echo "Clock skew between client and server: $skew, age:$age"
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         expected=$(($NUMDIRS + 1))
6895         cmd="$LFS find $dir -btime -${age}s -type d"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899         rm -f $ref $negref || error "Failed to remove $ref $negref"
6900 }
6901 run_test 56od "check lfs find -btime with units"
6902
6903 test_56p() {
6904         [ $RUNAS_ID -eq $UID ] &&
6905                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6906
6907         local dir=$DIR/$tdir
6908
6909         setup_56 $dir $NUMFILES $NUMDIRS
6910         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6911
6912         local expected=$NUMFILES
6913         local cmd="$LFS find -uid $RUNAS_ID $dir"
6914         local nums=$($cmd | wc -l)
6915
6916         [ $nums -eq $expected ] ||
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918
6919         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6920         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6921         nums=$($cmd | wc -l)
6922         [ $nums -eq $expected ] ||
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924 }
6925 run_test 56p "check lfs find -uid and ! -uid"
6926
6927 test_56q() {
6928         [ $RUNAS_ID -eq $UID ] &&
6929                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6930
6931         local dir=$DIR/$tdir
6932
6933         setup_56 $dir $NUMFILES $NUMDIRS
6934         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6935
6936         local expected=$NUMFILES
6937         local cmd="$LFS find -gid $RUNAS_GID $dir"
6938         local nums=$($cmd | wc -l)
6939
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6944         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6945         nums=$($cmd | wc -l)
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948 }
6949 run_test 56q "check lfs find -gid and ! -gid"
6950
6951 test_56r() {
6952         local dir=$DIR/$tdir
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS
6955
6956         local expected=12
6957         local cmd="$LFS find -size 0 -type f -lazy $dir"
6958         local nums=$($cmd | wc -l)
6959
6960         [ $nums -eq $expected ] ||
6961                 error "'$cmd' wrong: found $nums, expected $expected"
6962         cmd="$LFS find -size 0 -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         expected=0
6968         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6969         nums=$($cmd | wc -l)
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972         cmd="$LFS find ! -size 0 -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         echo "test" > $dir/$tfile
6978         echo "test2" > $dir/$tfile.2 && sync
6979         expected=1
6980         cmd="$LFS find -size 5 -type f -lazy $dir"
6981         nums=$($cmd | wc -l)
6982         [ $nums -eq $expected ] ||
6983                 error "'$cmd' wrong: found $nums, expected $expected"
6984         cmd="$LFS find -size 5 -type f $dir"
6985         nums=$($cmd | wc -l)
6986         [ $nums -eq $expected ] ||
6987                 error "'$cmd' wrong: found $nums, expected $expected"
6988
6989         expected=1
6990         cmd="$LFS find -size +5 -type f -lazy $dir"
6991         nums=$($cmd | wc -l)
6992         [ $nums -eq $expected ] ||
6993                 error "'$cmd' wrong: found $nums, expected $expected"
6994         cmd="$LFS find -size +5 -type f $dir"
6995         nums=$($cmd | wc -l)
6996         [ $nums -eq $expected ] ||
6997                 error "'$cmd' wrong: found $nums, expected $expected"
6998
6999         expected=2
7000         cmd="$LFS find -size +0 -type f -lazy $dir"
7001         nums=$($cmd | wc -l)
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004         cmd="$LFS find -size +0 -type f $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008
7009         expected=2
7010         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014         cmd="$LFS find ! -size -5 -type f $dir"
7015         nums=$($cmd | wc -l)
7016         [ $nums -eq $expected ] ||
7017                 error "'$cmd' wrong: found $nums, expected $expected"
7018
7019         expected=12
7020         cmd="$LFS find -size -5 -type f -lazy $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024         cmd="$LFS find -size -5 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028 }
7029 run_test 56r "check lfs find -size works"
7030
7031 test_56ra_sub() {
7032         local expected=$1
7033         local glimpses=$2
7034         local cmd="$3"
7035
7036         cancel_lru_locks $OSC
7037
7038         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7039         local nums=$($cmd | wc -l)
7040
7041         [ $nums -eq $expected ] ||
7042                 error "'$cmd' wrong: found $nums, expected $expected"
7043
7044         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7045
7046         if (( rpcs_before + glimpses != rpcs_after )); then
7047                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7048                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7049
7050                 if [[ $glimpses == 0 ]]; then
7051                         error "'$cmd' should not send glimpse RPCs to OST"
7052                 else
7053                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7054                 fi
7055         fi
7056 }
7057
7058 test_56ra() {
7059         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7060                 skip "MDS < 2.12.58 doesn't return LSOM data"
7061         local dir=$DIR/$tdir
7062         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7063
7064         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7065
7066         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7067         $LCTL set_param -n llite.*.statahead_agl=0
7068         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7069
7070         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7071         # open and close all files to ensure LSOM is updated
7072         cancel_lru_locks $OSC
7073         find $dir -type f | xargs cat > /dev/null
7074
7075         #   expect_found  glimpse_rpcs  command_to_run
7076         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7077         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7078         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7079         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7080
7081         echo "test" > $dir/$tfile
7082         echo "test2" > $dir/$tfile.2 && sync
7083         cancel_lru_locks $OSC
7084         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7085
7086         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7087         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7088         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7089         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7090
7091         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7092         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7093         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7094         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7095         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7096         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7097 }
7098 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7099
7100 test_56rb() {
7101         local dir=$DIR/$tdir
7102         local tmp=$TMP/$tfile.log
7103         local mdt_idx;
7104
7105         test_mkdir -p $dir || error "failed to mkdir $dir"
7106         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7107                 error "failed to setstripe $dir/$tfile"
7108         mdt_idx=$($LFS getdirstripe -i $dir)
7109         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7110
7111         stack_trap "rm -f $tmp" EXIT
7112         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7113         ! grep -q obd_uuid $tmp ||
7114                 error "failed to find --size +100K --ost 0 $dir"
7115         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7116         ! grep -q obd_uuid $tmp ||
7117                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7118 }
7119 run_test 56rb "check lfs find --size --ost/--mdt works"
7120
7121 test_56rc() {
7122         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7123         local dir=$DIR/$tdir
7124         local found
7125
7126         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7127         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7128         (( $MDSCOUNT > 2 )) &&
7129                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7130         mkdir $dir/$tdir-{1..10}
7131         touch $dir/$tfile-{1..10}
7132
7133         found=$($LFS find $dir --mdt-count 2 | wc -l)
7134         expect=11
7135         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7136
7137         found=$($LFS find $dir -T +1 | wc -l)
7138         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7139         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7140
7141         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7142         expect=11
7143         (( $found == $expect )) || error "found $found all_char, expect $expect"
7144
7145         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7146         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7147         (( $found == $expect )) || error "found $found all_char, expect $expect"
7148 }
7149 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7150
7151 test_56s() { # LU-611 #LU-9369
7152         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7153
7154         local dir=$DIR/$tdir
7155         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7156
7157         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7158         for i in $(seq $NUMDIRS); do
7159                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7160         done
7161
7162         local expected=$NUMDIRS
7163         local cmd="$LFS find -c $OSTCOUNT $dir"
7164         local nums=$($cmd | wc -l)
7165
7166         [ $nums -eq $expected ] || {
7167                 $LFS getstripe -R $dir
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169         }
7170
7171         expected=$((NUMDIRS + onestripe))
7172         cmd="$LFS find -stripe-count +0 -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] || {
7175                 $LFS getstripe -R $dir
7176                 error "'$cmd' wrong: found $nums, expected $expected"
7177         }
7178
7179         expected=$onestripe
7180         cmd="$LFS find -stripe-count 1 -type f $dir"
7181         nums=$($cmd | wc -l)
7182         [ $nums -eq $expected ] || {
7183                 $LFS getstripe -R $dir
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185         }
7186
7187         cmd="$LFS find -stripe-count -2 -type f $dir"
7188         nums=$($cmd | wc -l)
7189         [ $nums -eq $expected ] || {
7190                 $LFS getstripe -R $dir
7191                 error "'$cmd' wrong: found $nums, expected $expected"
7192         }
7193
7194         expected=0
7195         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] || {
7198                 $LFS getstripe -R $dir
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200         }
7201 }
7202 run_test 56s "check lfs find -stripe-count works"
7203
7204 test_56t() { # LU-611 #LU-9369
7205         local dir=$DIR/$tdir
7206
7207         setup_56 $dir 0 $NUMDIRS
7208         for i in $(seq $NUMDIRS); do
7209                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7210         done
7211
7212         local expected=$NUMDIRS
7213         local cmd="$LFS find -S 8M $dir"
7214         local nums=$($cmd | wc -l)
7215
7216         [ $nums -eq $expected ] || {
7217                 $LFS getstripe -R $dir
7218                 error "'$cmd' wrong: found $nums, expected $expected"
7219         }
7220         rm -rf $dir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7223
7224         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7225
7226         expected=$(((NUMDIRS + 1) * NUMFILES))
7227         cmd="$LFS find -stripe-size 512k -type f $dir"
7228         nums=$($cmd | wc -l)
7229         [ $nums -eq $expected ] ||
7230                 error "'$cmd' wrong: found $nums, expected $expected"
7231
7232         cmd="$LFS find -stripe-size +320k -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] ||
7235                 error "'$cmd' wrong: found $nums, expected $expected"
7236
7237         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7238         cmd="$LFS find -stripe-size +200k -type f $dir"
7239         nums=$($cmd | wc -l)
7240         [ $nums -eq $expected ] ||
7241                 error "'$cmd' wrong: found $nums, expected $expected"
7242
7243         cmd="$LFS find -stripe-size -640k -type f $dir"
7244         nums=$($cmd | wc -l)
7245         [ $nums -eq $expected ] ||
7246                 error "'$cmd' wrong: found $nums, expected $expected"
7247
7248         expected=4
7249         cmd="$LFS find -stripe-size 256k -type f $dir"
7250         nums=$($cmd | wc -l)
7251         [ $nums -eq $expected ] ||
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253
7254         cmd="$LFS find -stripe-size -320k -type f $dir"
7255         nums=$($cmd | wc -l)
7256         [ $nums -eq $expected ] ||
7257                 error "'$cmd' wrong: found $nums, expected $expected"
7258
7259         expected=0
7260         cmd="$LFS find -stripe-size 1024k -type f $dir"
7261         nums=$($cmd | wc -l)
7262         [ $nums -eq $expected ] ||
7263                 error "'$cmd' wrong: found $nums, expected $expected"
7264 }
7265 run_test 56t "check lfs find -stripe-size works"
7266
7267 test_56u() { # LU-611
7268         local dir=$DIR/$tdir
7269
7270         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7271
7272         if [[ $OSTCOUNT -gt 1 ]]; then
7273                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7274                 onestripe=4
7275         else
7276                 onestripe=0
7277         fi
7278
7279         local expected=$(((NUMDIRS + 1) * NUMFILES))
7280         local cmd="$LFS find -stripe-index 0 -type f $dir"
7281         local nums=$($cmd | wc -l)
7282
7283         [ $nums -eq $expected ] ||
7284                 error "'$cmd' wrong: found $nums, expected $expected"
7285
7286         expected=$onestripe
7287         cmd="$LFS find -stripe-index 1 -type f $dir"
7288         nums=$($cmd | wc -l)
7289         [ $nums -eq $expected ] ||
7290                 error "'$cmd' wrong: found $nums, expected $expected"
7291
7292         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         expected=0
7298         # This should produce an error and not return any files
7299         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7300         nums=$($cmd 2>/dev/null | wc -l)
7301         [ $nums -eq $expected ] ||
7302                 error "'$cmd' wrong: found $nums, expected $expected"
7303
7304         if [[ $OSTCOUNT -gt 1 ]]; then
7305                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7306                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7307                 nums=$($cmd | wc -l)
7308                 [ $nums -eq $expected ] ||
7309                         error "'$cmd' wrong: found $nums, expected $expected"
7310         fi
7311 }
7312 run_test 56u "check lfs find -stripe-index works"
7313
7314 test_56v() {
7315         local mdt_idx=0
7316         local dir=$DIR/$tdir
7317
7318         setup_56 $dir $NUMFILES $NUMDIRS
7319
7320         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7321         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7322
7323         for file in $($LFS find -m $UUID $dir); do
7324                 file_midx=$($LFS getstripe -m $file)
7325                 [ $file_midx -eq $mdt_idx ] ||
7326                         error "lfs find -m $UUID != getstripe -m $file_midx"
7327         done
7328 }
7329 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7330
7331 test_56wa() {
7332         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7334
7335         local dir=$DIR/$tdir
7336
7337         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7338
7339         local stripe_size=$($LFS getstripe -S -d $dir) ||
7340                 error "$LFS getstripe -S -d $dir failed"
7341         stripe_size=${stripe_size%% *}
7342
7343         local file_size=$((stripe_size * OSTCOUNT))
7344         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7345         local required_space=$((file_num * file_size))
7346         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7347                            head -n1)
7348         (( free_space >= required_space / 1024 )) ||
7349                 skip_env "need $required_space, have $free_space kbytes"
7350
7351         local dd_bs=65536
7352         local dd_count=$((file_size / dd_bs))
7353
7354         # write data into the files
7355         local i
7356         local j
7357         local file
7358
7359         for ((i = 1; i <= NUMFILES; i++ )); do
7360                 file=$dir/file$i
7361                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7362                         error "write data into $file failed"
7363         done
7364         for ((i = 1; i <= NUMDIRS; i++ )); do
7365                 for ((j = 1; j <= NUMFILES; j++ )); do
7366                         file=$dir/dir$i/file$j
7367                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7368                                 error "write data into $file failed"
7369                 done
7370         done
7371
7372         # $LFS_MIGRATE will fail if hard link migration is unsupported
7373         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7374                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7375                         error "creating links to $dir/dir1/file1 failed"
7376         fi
7377
7378         local expected=-1
7379
7380         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7381
7382         # lfs_migrate file
7383         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7384
7385         echo "$cmd"
7386         eval $cmd || error "$cmd failed"
7387
7388         check_stripe_count $dir/file1 $expected
7389
7390         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7391                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7392                 # OST 1 if it is on OST 0. This file is small enough to
7393                 # be on only one stripe.
7394                 file=$dir/migr_1_ost
7395                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7396                         error "write data into $file failed"
7397                 local obdidx=$($LFS getstripe -i $file)
7398                 local oldmd5=$(md5sum $file)
7399                 local newobdidx=0
7400
7401                 (( obdidx != 0 )) || newobdidx=1
7402                 cmd="$LFS migrate -i $newobdidx $file"
7403                 echo $cmd
7404                 eval $cmd || error "$cmd failed"
7405
7406                 local realobdix=$($LFS getstripe -i $file)
7407                 local newmd5=$(md5sum $file)
7408
7409                 (( $newobdidx == $realobdix )) ||
7410                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7411                 [[ "$oldmd5" == "$newmd5" ]] ||
7412                         error "md5sum differ: $oldmd5, $newmd5"
7413         fi
7414
7415         # lfs_migrate dir
7416         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7417         echo "$cmd"
7418         eval $cmd || error "$cmd failed"
7419
7420         for (( j = 1; j <= NUMFILES; j++ )); do
7421                 check_stripe_count $dir/dir1/file$j $expected
7422         done
7423
7424         # lfs_migrate works with lfs find
7425         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7426              $LFS_MIGRATE -y -c $expected"
7427         echo "$cmd"
7428         eval $cmd || error "$cmd failed"
7429
7430         for (( i = 2; i <= NUMFILES; i++ )); do
7431                 check_stripe_count $dir/file$i $expected
7432         done
7433         for (( i = 2; i <= NUMDIRS; i++ )); do
7434                 for (( j = 1; j <= NUMFILES; j++ )); do
7435                         check_stripe_count $dir/dir$i/file$j $expected
7436                 done
7437         done
7438 }
7439 run_test 56wa "check lfs_migrate -c stripe_count works"
7440
7441 test_56wb() {
7442         local file1=$DIR/$tdir/file1
7443         local create_pool=false
7444         local initial_pool=$($LFS getstripe -p $DIR)
7445         local pool_list=()
7446         local pool=""
7447
7448         echo -n "Creating test dir..."
7449         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7450         echo "done."
7451
7452         echo -n "Creating test file..."
7453         touch $file1 || error "cannot create file"
7454         echo "done."
7455
7456         echo -n "Detecting existing pools..."
7457         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7458
7459         if [ ${#pool_list[@]} -gt 0 ]; then
7460                 echo "${pool_list[@]}"
7461                 for thispool in "${pool_list[@]}"; do
7462                         if [[ -z "$initial_pool" ||
7463                               "$initial_pool" != "$thispool" ]]; then
7464                                 pool="$thispool"
7465                                 echo "Using existing pool '$pool'"
7466                                 break
7467                         fi
7468                 done
7469         else
7470                 echo "none detected."
7471         fi
7472         if [ -z "$pool" ]; then
7473                 pool=${POOL:-testpool}
7474                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7475                 echo -n "Creating pool '$pool'..."
7476                 create_pool=true
7477                 pool_add $pool &> /dev/null ||
7478                         error "pool_add failed"
7479                 echo "done."
7480
7481                 echo -n "Adding target to pool..."
7482                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7483                         error "pool_add_targets failed"
7484                 echo "done."
7485         fi
7486
7487         echo -n "Setting pool using -p option..."
7488         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7489                 error "migrate failed rc = $?"
7490         echo "done."
7491
7492         echo -n "Verifying test file is in pool after migrating..."
7493         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7494                 error "file was not migrated to pool $pool"
7495         echo "done."
7496
7497         echo -n "Removing test file from pool '$pool'..."
7498         # "lfs migrate $file" won't remove the file from the pool
7499         # until some striping information is changed.
7500         $LFS migrate -c 1 $file1 &> /dev/null ||
7501                 error "cannot remove from pool"
7502         [ "$($LFS getstripe -p $file1)" ] &&
7503                 error "pool still set"
7504         echo "done."
7505
7506         echo -n "Setting pool using --pool option..."
7507         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7508                 error "migrate failed rc = $?"
7509         echo "done."
7510
7511         # Clean up
7512         rm -f $file1
7513         if $create_pool; then
7514                 destroy_test_pools 2> /dev/null ||
7515                         error "destroy test pools failed"
7516         fi
7517 }
7518 run_test 56wb "check lfs_migrate pool support"
7519
7520 test_56wc() {
7521         local file1="$DIR/$tdir/$tfile"
7522         local md5
7523         local parent_ssize
7524         local parent_scount
7525         local cur_ssize
7526         local cur_scount
7527         local orig_ssize
7528         local new_scount
7529         local cur_comp
7530
7531         echo -n "Creating test dir..."
7532         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7533         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7534                 error "cannot set stripe by '-S 1M -c 1'"
7535         echo "done"
7536
7537         echo -n "Setting initial stripe for test file..."
7538         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7539                 error "cannot set stripe"
7540         cur_ssize=$($LFS getstripe -S "$file1")
7541         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7542         echo "done."
7543
7544         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7545         stack_trap "rm -f $file1"
7546         md5="$(md5sum $file1)"
7547
7548         # File currently set to -S 512K -c 1
7549
7550         # Ensure -c and -S options are rejected when -R is set
7551         echo -n "Verifying incompatible options are detected..."
7552         $LFS_MIGRATE -R -c 1 "$file1" &&
7553                 error "incompatible -R and -c options not detected"
7554         $LFS_MIGRATE -R -S 1M "$file1" &&
7555                 error "incompatible -R and -S options not detected"
7556         $LFS_MIGRATE -R -p pool "$file1" &&
7557                 error "incompatible -R and -p options not detected"
7558         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7559                 error "incompatible -R and -E options not detected"
7560         $LFS_MIGRATE -R -A "$file1" &&
7561                 error "incompatible -R and -A options not detected"
7562         $LFS_MIGRATE -A -c 1 "$file1" &&
7563                 error "incompatible -A and -c options not detected"
7564         $LFS_MIGRATE -A -S 1M "$file1" &&
7565                 error "incompatible -A and -S options not detected"
7566         $LFS_MIGRATE -A -p pool "$file1" &&
7567                 error "incompatible -A and -p options not detected"
7568         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7569                 error "incompatible -A and -E options not detected"
7570         echo "done."
7571
7572         # Ensure unrecognized options are passed through to 'lfs migrate'
7573         echo -n "Verifying -S option is passed through to lfs migrate..."
7574         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7575         cur_ssize=$($LFS getstripe -S "$file1")
7576         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7577         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7578         echo "done."
7579
7580         # File currently set to -S 1M -c 1
7581
7582         # Ensure long options are supported
7583         echo -n "Verifying long options supported..."
7584         $LFS_MIGRATE --non-block "$file1" ||
7585                 error "long option without argument not supported"
7586         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7587                 error "long option with argument not supported"
7588         cur_ssize=$($LFS getstripe -S "$file1")
7589         (( cur_ssize == 524288 )) ||
7590                 error "migrate --stripe-size $cur_ssize != 524288"
7591         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7592         echo "done."
7593
7594         # File currently set to -S 512K -c 1
7595
7596         if (( OSTCOUNT > 1 )); then
7597                 echo -n "Verifying explicit stripe count can be set..."
7598                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7599                 cur_scount=$($LFS getstripe -c "$file1")
7600                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7601                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7602                         error "file data has changed (3)"
7603                 echo "done."
7604         fi
7605
7606         # File currently set to -S 512K -c 1 or -S 512K -c 2
7607
7608         # Ensure parent striping is used if -R is set, and no stripe
7609         # count or size is specified
7610         echo -n "Setting stripe for parent directory..."
7611         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7612                 error "cannot set stripe '-S 2M -c 1'"
7613         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7614         echo "done."
7615
7616         echo -n "Verifying restripe option uses parent stripe settings..."
7617         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7618         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7619         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7620         cur_ssize=$($LFS getstripe -S "$file1")
7621         (( cur_ssize == parent_ssize )) ||
7622                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7623         cur_scount=$($LFS getstripe -c "$file1")
7624         (( cur_scount == parent_scount )) ||
7625                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7626         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7627         echo "done."
7628
7629         # File currently set to -S 1M -c 1
7630
7631         # Ensure striping is preserved if -R is not set, and no stripe
7632         # count or size is specified
7633         echo -n "Verifying striping size preserved when not specified..."
7634         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7635         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7636                 error "cannot set stripe on parent directory"
7637         $LFS_MIGRATE "$file1" || error "migrate failed"
7638         cur_ssize=$($LFS getstripe -S "$file1")
7639         (( cur_ssize == orig_ssize )) ||
7640                 error "migrate by default $cur_ssize != $orig_ssize"
7641         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7642         echo "done."
7643
7644         # Ensure file name properly detected when final option has no argument
7645         echo -n "Verifying file name properly detected..."
7646         $LFS_MIGRATE "$file1" ||
7647                 error "file name interpreted as option argument"
7648         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7649         echo "done."
7650
7651         # Ensure PFL arguments are passed through properly
7652         echo -n "Verifying PFL options passed through..."
7653         new_scount=$(((OSTCOUNT + 1) / 2))
7654         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7655                 error "migrate PFL arguments failed"
7656         cur_comp=$($LFS getstripe --comp-count $file1)
7657         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7658         cur_scount=$($LFS getstripe --stripe-count $file1)
7659         (( cur_scount == new_scount)) ||
7660                 error "PFL stripe count $cur_scount != $new_scount"
7661         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7662         echo "done."
7663 }
7664 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7665
7666 test_56wd() {
7667         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7668
7669         local file1=$DIR/$tdir/$tfile
7670
7671         echo -n "Creating test dir..."
7672         test_mkdir $DIR/$tdir || error "cannot create dir"
7673         echo "done."
7674
7675         echo -n "Creating test file..."
7676         echo "$tfile" > $file1
7677         echo "done."
7678
7679         # Ensure 'lfs migrate' will fail by using a non-existent option,
7680         # and make sure rsync is not called to recover
7681         echo -n "Make sure --no-rsync option works..."
7682         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7683                 grep -q 'refusing to fall back to rsync' ||
7684                 error "rsync was called with --no-rsync set"
7685         echo "done."
7686
7687         # Ensure rsync is called without trying 'lfs migrate' first
7688         echo -n "Make sure --rsync option works..."
7689         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7690                 grep -q 'falling back to rsync' &&
7691                 error "lfs migrate was called with --rsync set"
7692         echo "done."
7693 }
7694 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7695
7696 test_56we() {
7697         local td=$DIR/$tdir
7698         local tf=$td/$tfile
7699
7700         test_mkdir $td || error "cannot create $td"
7701         touch $tf || error "cannot touch $tf"
7702
7703         echo -n "Make sure --non-direct|-D works..."
7704         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7705                 grep -q "lfs migrate --non-direct" ||
7706                 error "--non-direct option cannot work correctly"
7707         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7708                 grep -q "lfs migrate -D" ||
7709                 error "-D option cannot work correctly"
7710         echo "done."
7711 }
7712 run_test 56we "check lfs_migrate --non-direct|-D support"
7713
7714 test_56x() {
7715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7716         check_swap_layouts_support
7717
7718         local dir=$DIR/$tdir
7719         local ref1=/etc/passwd
7720         local file1=$dir/file1
7721
7722         test_mkdir $dir || error "creating dir $dir"
7723         $LFS setstripe -c 2 $file1
7724         cp $ref1 $file1
7725         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7726         stripe=$($LFS getstripe -c $file1)
7727         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7728         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7729
7730         # clean up
7731         rm -f $file1
7732 }
7733 run_test 56x "lfs migration support"
7734
7735 test_56xa() {
7736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7737         check_swap_layouts_support
7738
7739         local dir=$DIR/$tdir/$testnum
7740
7741         test_mkdir -p $dir
7742
7743         local ref1=/etc/passwd
7744         local file1=$dir/file1
7745
7746         $LFS setstripe -c 2 $file1
7747         cp $ref1 $file1
7748         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7749
7750         local stripe=$($LFS getstripe -c $file1)
7751
7752         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7753         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7754
7755         # clean up
7756         rm -f $file1
7757 }
7758 run_test 56xa "lfs migration --block support"
7759
7760 check_migrate_links() {
7761         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7762         local dir="$1"
7763         local file1="$dir/file1"
7764         local begin="$2"
7765         local count="$3"
7766         local runas="$4"
7767         local total_count=$(($begin + $count - 1))
7768         local symlink_count=10
7769         local uniq_count=10
7770
7771         if [ ! -f "$file1" ]; then
7772                 echo -n "creating initial file..."
7773                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7774                         error "cannot setstripe initial file"
7775                 echo "done"
7776
7777                 echo -n "creating symlinks..."
7778                 for s in $(seq 1 $symlink_count); do
7779                         ln -s "$file1" "$dir/slink$s" ||
7780                                 error "cannot create symlinks"
7781                 done
7782                 echo "done"
7783
7784                 echo -n "creating nonlinked files..."
7785                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7786                         error "cannot create nonlinked files"
7787                 echo "done"
7788         fi
7789
7790         # create hard links
7791         if [ ! -f "$dir/file$total_count" ]; then
7792                 echo -n "creating hard links $begin:$total_count..."
7793                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7794                         /dev/null || error "cannot create hard links"
7795                 echo "done"
7796         fi
7797
7798         echo -n "checking number of hard links listed in xattrs..."
7799         local fid=$($LFS getstripe -F "$file1")
7800         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7801
7802         echo "${#paths[*]}"
7803         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7804                         skip "hard link list has unexpected size, skipping test"
7805         fi
7806         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7807                         error "link names should exceed xattrs size"
7808         fi
7809
7810         echo -n "migrating files..."
7811         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7812         local rc=$?
7813         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7814         echo "done"
7815
7816         # make sure all links have been properly migrated
7817         echo -n "verifying files..."
7818         fid=$($LFS getstripe -F "$file1") ||
7819                 error "cannot get fid for file $file1"
7820         for i in $(seq 2 $total_count); do
7821                 local fid2=$($LFS getstripe -F $dir/file$i)
7822
7823                 [ "$fid2" == "$fid" ] ||
7824                         error "migrated hard link has mismatched FID"
7825         done
7826
7827         # make sure hard links were properly detected, and migration was
7828         # performed only once for the entire link set; nonlinked files should
7829         # also be migrated
7830         local actual=$(grep -c 'done' <<< "$migrate_out")
7831         local expected=$(($uniq_count + 1))
7832
7833         [ "$actual" -eq  "$expected" ] ||
7834                 error "hard links individually migrated ($actual != $expected)"
7835
7836         # make sure the correct number of hard links are present
7837         local hardlinks=$(stat -c '%h' "$file1")
7838
7839         [ $hardlinks -eq $total_count ] ||
7840                 error "num hard links $hardlinks != $total_count"
7841         echo "done"
7842
7843         return 0
7844 }
7845
7846 test_56xb() {
7847         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7848                 skip "Need MDS version at least 2.10.55"
7849
7850         local dir="$DIR/$tdir"
7851
7852         test_mkdir "$dir" || error "cannot create dir $dir"
7853
7854         echo "testing lfs migrate mode when all links fit within xattrs"
7855         check_migrate_links "$dir" 2 99
7856
7857         echo "testing rsync mode when all links fit within xattrs"
7858         check_migrate_links --rsync "$dir" 2 99
7859
7860         echo "testing lfs migrate mode when all links do not fit within xattrs"
7861         check_migrate_links "$dir" 101 100
7862
7863         echo "testing rsync mode when all links do not fit within xattrs"
7864         check_migrate_links --rsync "$dir" 101 100
7865
7866         chown -R $RUNAS_ID $dir
7867         echo "testing non-root lfs migrate mode when not all links are in xattr"
7868         check_migrate_links "$dir" 101 100 "$RUNAS"
7869
7870         # clean up
7871         rm -rf $dir
7872 }
7873 run_test 56xb "lfs migration hard link support"
7874
7875 test_56xc() {
7876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7877
7878         local dir="$DIR/$tdir"
7879
7880         test_mkdir "$dir" || error "cannot create dir $dir"
7881
7882         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7883         echo -n "Setting initial stripe for 20MB test file..."
7884         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7885                 error "cannot setstripe 20MB file"
7886         echo "done"
7887         echo -n "Sizing 20MB test file..."
7888         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7889         echo "done"
7890         echo -n "Verifying small file autostripe count is 1..."
7891         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7892                 error "cannot migrate 20MB file"
7893         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7894                 error "cannot get stripe for $dir/20mb"
7895         [ $stripe_count -eq 1 ] ||
7896                 error "unexpected stripe count $stripe_count for 20MB file"
7897         rm -f "$dir/20mb"
7898         echo "done"
7899
7900         # Test 2: File is small enough to fit within the available space on
7901         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7902         # have at least an additional 1KB for each desired stripe for test 3
7903         echo -n "Setting stripe for 1GB test file..."
7904         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7905         echo "done"
7906         echo -n "Sizing 1GB test file..."
7907         # File size is 1GB + 3KB
7908         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7909         echo "done"
7910
7911         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7912         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7913         if (( avail > 524288 * OSTCOUNT )); then
7914                 echo -n "Migrating 1GB file..."
7915                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7916                         error "cannot migrate 1GB file"
7917                 echo "done"
7918                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7919                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7920                         error "cannot getstripe for 1GB file"
7921                 [ $stripe_count -eq 2 ] ||
7922                         error "unexpected stripe count $stripe_count != 2"
7923                 echo "done"
7924         fi
7925
7926         # Test 3: File is too large to fit within the available space on
7927         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7928         if [ $OSTCOUNT -ge 3 ]; then
7929                 # The required available space is calculated as
7930                 # file size (1GB + 3KB) / OST count (3).
7931                 local kb_per_ost=349526
7932
7933                 echo -n "Migrating 1GB file with limit..."
7934                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7935                         error "cannot migrate 1GB file with limit"
7936                 echo "done"
7937
7938                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7939                 echo -n "Verifying 1GB autostripe count with limited space..."
7940                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7941                         error "unexpected stripe count $stripe_count (min 3)"
7942                 echo "done"
7943         fi
7944
7945         # clean up
7946         rm -rf $dir
7947 }
7948 run_test 56xc "lfs migration autostripe"
7949
7950 test_56xd() {
7951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7952
7953         local dir=$DIR/$tdir
7954         local f_mgrt=$dir/$tfile.mgrt
7955         local f_yaml=$dir/$tfile.yaml
7956         local f_copy=$dir/$tfile.copy
7957         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7958         local layout_copy="-c 2 -S 2M -i 1"
7959         local yamlfile=$dir/yamlfile
7960         local layout_before;
7961         local layout_after;
7962
7963         test_mkdir "$dir" || error "cannot create dir $dir"
7964         $LFS setstripe $layout_yaml $f_yaml ||
7965                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7966         $LFS getstripe --yaml $f_yaml > $yamlfile
7967         $LFS setstripe $layout_copy $f_copy ||
7968                 error "cannot setstripe $f_copy with layout $layout_copy"
7969         touch $f_mgrt
7970         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7971
7972         # 1. test option --yaml
7973         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7974                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7975         layout_before=$(get_layout_param $f_yaml)
7976         layout_after=$(get_layout_param $f_mgrt)
7977         [ "$layout_after" == "$layout_before" ] ||
7978                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7979
7980         # 2. test option --copy
7981         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7982                 error "cannot migrate $f_mgrt with --copy $f_copy"
7983         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
7984         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
7985         [ "$layout_after" == "$layout_before" ] ||
7986                 error "lfs_migrate --copy: $layout_after != $layout_before"
7987 }
7988 run_test 56xd "check lfs_migrate --yaml and --copy support"
7989
7990 test_56xe() {
7991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7992
7993         local dir=$DIR/$tdir
7994         local f_comp=$dir/$tfile
7995         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7996         local layout_before=""
7997         local layout_after=""
7998
7999         test_mkdir "$dir" || error "cannot create dir $dir"
8000         $LFS setstripe $layout $f_comp ||
8001                 error "cannot setstripe $f_comp with layout $layout"
8002         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8003         dd if=/dev/zero of=$f_comp bs=1M count=4
8004
8005         # 1. migrate a comp layout file by lfs_migrate
8006         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8007         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8008         [ "$layout_before" == "$layout_after" ] ||
8009                 error "lfs_migrate: $layout_before != $layout_after"
8010
8011         # 2. migrate a comp layout file by lfs migrate
8012         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8013         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8014         [ "$layout_before" == "$layout_after" ] ||
8015                 error "lfs migrate: $layout_before != $layout_after"
8016 }
8017 run_test 56xe "migrate a composite layout file"
8018
8019 test_56xf() {
8020         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8021
8022         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8023                 skip "Need server version at least 2.13.53"
8024
8025         local dir=$DIR/$tdir
8026         local f_comp=$dir/$tfile
8027         local layout="-E 1M -c1 -E -1 -c2"
8028         local fid_before=""
8029         local fid_after=""
8030
8031         test_mkdir "$dir" || error "cannot create dir $dir"
8032         $LFS setstripe $layout $f_comp ||
8033                 error "cannot setstripe $f_comp with layout $layout"
8034         fid_before=$($LFS getstripe --fid $f_comp)
8035         dd if=/dev/zero of=$f_comp bs=1M count=4
8036
8037         # 1. migrate a comp layout file to a comp layout
8038         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8039         fid_after=$($LFS getstripe --fid $f_comp)
8040         [ "$fid_before" == "$fid_after" ] ||
8041                 error "comp-to-comp migrate: $fid_before != $fid_after"
8042
8043         # 2. migrate a comp layout file to a plain layout
8044         $LFS migrate -c2 $f_comp ||
8045                 error "cannot migrate $f_comp by lfs migrate"
8046         fid_after=$($LFS getstripe --fid $f_comp)
8047         [ "$fid_before" == "$fid_after" ] ||
8048                 error "comp-to-plain migrate: $fid_before != $fid_after"
8049
8050         # 3. migrate a plain layout file to a comp layout
8051         $LFS migrate $layout $f_comp ||
8052                 error "cannot migrate $f_comp by lfs migrate"
8053         fid_after=$($LFS getstripe --fid $f_comp)
8054         [ "$fid_before" == "$fid_after" ] ||
8055                 error "plain-to-comp migrate: $fid_before != $fid_after"
8056 }
8057 run_test 56xf "FID is not lost during migration of a composite layout file"
8058
8059 check_file_ost_range() {
8060         local file="$1"
8061         shift
8062         local range="$*"
8063         local -a file_range
8064         local idx
8065
8066         file_range=($($LFS getstripe -y "$file" |
8067                 awk '/l_ost_idx:/ { print $NF }'))
8068
8069         if [[ "${#file_range[@]}" = 0 ]]; then
8070                 echo "No osts found for $file"
8071                 return 1
8072         fi
8073
8074         for idx in "${file_range[@]}"; do
8075                 [[ " $range " =~ " $idx " ]] ||
8076                         return 1
8077         done
8078
8079         return 0
8080 }
8081
8082 sub_test_56xg() {
8083         local stripe_opt="$1"
8084         local pool="$2"
8085         shift 2
8086         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8087
8088         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8089                 error "Fail to migrate $tfile on $pool"
8090         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8091                 error "$tfile is not in pool $pool"
8092         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8093                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8094 }
8095
8096 test_56xg() {
8097         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8098         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8099         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8100                 skip "Need MDS version newer than 2.14.52"
8101
8102         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8103         local -a pool_ranges=("0 0" "1 1" "0 1")
8104
8105         # init pools
8106         for i in "${!pool_names[@]}"; do
8107                 pool_add ${pool_names[$i]} ||
8108                         error "pool_add failed (pool: ${pool_names[$i]})"
8109                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8110                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8111         done
8112
8113         # init the file to migrate
8114         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8115                 error "Unable to create $tfile on OST1"
8116         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8117                 error "Unable to write on $tfile"
8118
8119         echo "1. migrate $tfile on pool ${pool_names[0]}"
8120         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8121
8122         echo "2. migrate $tfile on pool ${pool_names[2]}"
8123         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8124
8125         echo "3. migrate $tfile on pool ${pool_names[1]}"
8126         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8127
8128         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8129         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8130         echo
8131
8132         # Clean pools
8133         destroy_test_pools ||
8134                 error "pool_destroy failed"
8135 }
8136 run_test 56xg "lfs migrate pool support"
8137
8138 test_56xh() {
8139         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8140
8141         local size_mb=25
8142         local file1=$DIR/$tfile
8143         local tmp1=$TMP/$tfile.tmp
8144
8145         $LFS setstripe -c 2 $file1
8146
8147         stack_trap "rm -f $file1 $tmp1"
8148         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8149                         error "error creating $tmp1"
8150         ls -lsh $tmp1
8151         cp $tmp1 $file1
8152
8153         local start=$SECONDS
8154
8155         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8156                 error "migrate failed rc = $?"
8157
8158         local elapsed=$((SECONDS - start))
8159
8160         # with 1MB/s, elapsed should equal size_mb
8161         (( elapsed >= size_mb * 95 / 100 )) ||
8162                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8163
8164         (( elapsed <= size_mb * 120 / 100 )) ||
8165                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8166
8167         (( elapsed <= size_mb * 150 / 100 )) ||
8168                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8169
8170         stripe=$($LFS getstripe -c $file1)
8171         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8172         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8173
8174         # Clean up file (since it is multiple MB)
8175         rm -f $file1 $tmp1
8176 }
8177 run_test 56xh "lfs migrate bandwidth limitation support"
8178
8179 test_56xi() {
8180         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8181         verify_yaml_available || skip_env "YAML verification not installed"
8182
8183         local size_mb=5
8184         local file1=$DIR/$tfile.1
8185         local file2=$DIR/$tfile.2
8186         local file3=$DIR/$tfile.3
8187         local output_file=$DIR/$tfile.out
8188         local tmp1=$TMP/$tfile.tmp
8189
8190         $LFS setstripe -c 2 $file1
8191         $LFS setstripe -c 2 $file2
8192         $LFS setstripe -c 2 $file3
8193
8194         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8195         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8196                         error "error creating $tmp1"
8197         ls -lsh $tmp1
8198         cp $tmp1 $file1
8199         cp $tmp1 $file2
8200         cp $tmp1 $file3
8201
8202         $LFS migrate --stats --stats-interval=1 \
8203                 -c 1 $file1 $file2 $file3 1> $output_file ||
8204                 error "migrate failed rc = $?"
8205
8206         cat $output_file
8207         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8208
8209         # Clean up file (since it is multiple MB)
8210         rm -f $file1 $file2 $file3 $tmp1 $output_file
8211 }
8212 run_test 56xi "lfs migrate stats support"
8213
8214 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8215         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8216
8217         local file=$DIR/$tfile
8218         local linkdir=$DIR/$tdir
8219
8220         test_mkdir $linkdir || error "fail to create $linkdir"
8221         $LFS setstripe -i 0 -c 1 -S1M $file
8222         dd if=/dev/urandom of=$file bs=1M count=10 ||
8223                 error "fail to create $file"
8224
8225         # Create file links
8226         local cpts
8227         local threads_max
8228         local nlinks
8229
8230         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8231         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8232         (( nlinks = thread_max * 3 / 2 / cpts))
8233
8234         echo "create $nlinks hard links of $file"
8235         createmany -l $file $linkdir/link $nlinks
8236
8237         # Parallel migrates (should not block)
8238         local i
8239         for ((i = 0; i < nlinks; i++)); do
8240                 echo $linkdir/link$i
8241         done | xargs -n1 -P $nlinks $LFS migrate -c2
8242
8243         local stripe_count
8244         stripe_count=$($LFS getstripe -c $file) ||
8245                 error "fail to get stripe count on $file"
8246
8247         ((stripe_count == 2)) ||
8248                 error "fail to migrate $file (stripe_count = $stripe_count)"
8249 }
8250 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8251
8252 test_56y() {
8253         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8254                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8255
8256         local res=""
8257         local dir=$DIR/$tdir
8258         local f1=$dir/file1
8259         local f2=$dir/file2
8260
8261         test_mkdir -p $dir || error "creating dir $dir"
8262         touch $f1 || error "creating std file $f1"
8263         $MULTIOP $f2 H2c || error "creating released file $f2"
8264
8265         # a directory can be raid0, so ask only for files
8266         res=$($LFS find $dir -L raid0 -type f | wc -l)
8267         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8268
8269         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8270         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8271
8272         # only files can be released, so no need to force file search
8273         res=$($LFS find $dir -L released)
8274         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8275
8276         res=$($LFS find $dir -type f \! -L released)
8277         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8278 }
8279 run_test 56y "lfs find -L raid0|released"
8280
8281 test_56z() { # LU-4824
8282         # This checks to make sure 'lfs find' continues after errors
8283         # There are two classes of errors that should be caught:
8284         # - If multiple paths are provided, all should be searched even if one
8285         #   errors out
8286         # - If errors are encountered during the search, it should not terminate
8287         #   early
8288         local dir=$DIR/$tdir
8289         local i
8290
8291         test_mkdir $dir
8292         for i in d{0..9}; do
8293                 test_mkdir $dir/$i
8294                 touch $dir/$i/$tfile
8295         done
8296         $LFS find $DIR/non_existent_dir $dir &&
8297                 error "$LFS find did not return an error"
8298         # Make a directory unsearchable. This should NOT be the last entry in
8299         # directory order.  Arbitrarily pick the 6th entry
8300         chmod 700 $($LFS find $dir -type d | sed '6!d')
8301
8302         $RUNAS $LFS find $DIR/non_existent $dir
8303         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8304
8305         # The user should be able to see 10 directories and 9 files
8306         (( count == 19 )) ||
8307                 error "$LFS find found $count != 19 entries after error"
8308 }
8309 run_test 56z "lfs find should continue after an error"
8310
8311 test_56aa() { # LU-5937
8312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8313
8314         local dir=$DIR/$tdir
8315
8316         mkdir $dir
8317         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8318
8319         createmany -o $dir/striped_dir/${tfile}- 1024
8320         local dirs=$($LFS find --size +8k $dir/)
8321
8322         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8323 }
8324 run_test 56aa "lfs find --size under striped dir"
8325
8326 test_56ab() { # LU-10705
8327         test_mkdir $DIR/$tdir
8328         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8329         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8330         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8331         # Flush writes to ensure valid blocks.  Need to be more thorough for
8332         # ZFS, since blocks are not allocated/returned to client immediately.
8333         sync_all_data
8334         wait_zfs_commit ost1 2
8335         cancel_lru_locks osc
8336         ls -ls $DIR/$tdir
8337
8338         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8339
8340         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8341
8342         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8343         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8344
8345         rm -f $DIR/$tdir/$tfile.[123]
8346 }
8347 run_test 56ab "lfs find --blocks"
8348
8349 # LU-11188
8350 test_56aca() {
8351         local dir="$DIR/$tdir"
8352         local perms=(001 002 003 004 005 006 007
8353                      010 020 030 040 050 060 070
8354                      100 200 300 400 500 600 700
8355                      111 222 333 444 555 666 777)
8356         local perm_minus=(8 8 4 8 4 4 2
8357                           8 8 4 8 4 4 2
8358                           8 8 4 8 4 4 2
8359                           4 4 2 4 2 2 1)
8360         local perm_slash=(8  8 12  8 12 12 14
8361                           8  8 12  8 12 12 14
8362                           8  8 12  8 12 12 14
8363                          16 16 24 16 24 24 28)
8364
8365         test_mkdir "$dir"
8366         for perm in ${perms[*]}; do
8367                 touch "$dir/$tfile.$perm"
8368                 chmod $perm "$dir/$tfile.$perm"
8369         done
8370
8371         for ((i = 0; i < ${#perms[*]}; i++)); do
8372                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8373                 (( $num == 1 )) ||
8374                         error "lfs find -perm ${perms[i]}:"\
8375                               "$num != 1"
8376
8377                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8378                 (( $num == ${perm_minus[i]} )) ||
8379                         error "lfs find -perm -${perms[i]}:"\
8380                               "$num != ${perm_minus[i]}"
8381
8382                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8383                 (( $num == ${perm_slash[i]} )) ||
8384                         error "lfs find -perm /${perms[i]}:"\
8385                               "$num != ${perm_slash[i]}"
8386         done
8387 }
8388 run_test 56aca "check lfs find -perm with octal representation"
8389
8390 test_56acb() {
8391         local dir=$DIR/$tdir
8392         # p is the permission of write and execute for user, group and other
8393         # without the umask. It is used to test +wx.
8394         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8395         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8396         local symbolic=(+t  a+t u+t g+t o+t
8397                         g+s u+s o+s +s o+sr
8398                         o=r,ug+o,u+w
8399                         u+ g+ o+ a+ ugo+
8400                         u- g- o- a- ugo-
8401                         u= g= o= a= ugo=
8402                         o=r,ug+o,u+w u=r,a+u,u+w
8403                         g=r,ugo=g,u+w u+x,+X +X
8404                         u+x,u+X u+X u+x,g+X o+r,+X
8405                         u+x,go+X +wx +rwx)
8406
8407         test_mkdir $dir
8408         for perm in ${perms[*]}; do
8409                 touch "$dir/$tfile.$perm"
8410                 chmod $perm "$dir/$tfile.$perm"
8411         done
8412
8413         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8414                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8415
8416                 (( $num == 1 )) ||
8417                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8418         done
8419 }
8420 run_test 56acb "check lfs find -perm with symbolic representation"
8421
8422 test_56acc() {
8423         local dir=$DIR/$tdir
8424         local tests="17777 787 789 abcd
8425                 ug=uu ug=a ug=gu uo=ou urw
8426                 u+xg+x a=r,u+x,"
8427
8428         test_mkdir $dir
8429         for err in $tests; do
8430                 if $LFS find $dir -perm $err 2>/dev/null; then
8431                         error "lfs find -perm $err: parsing should have failed"
8432                 fi
8433         done
8434 }
8435 run_test 56acc "check parsing error for lfs find -perm"
8436
8437 test_56ba() {
8438         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8439                 skip "Need MDS version at least 2.10.50"
8440
8441         # Create composite files with one component
8442         local dir=$DIR/$tdir
8443
8444         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8445         # Create composite files with three components
8446         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8447         # Create non-composite files
8448         createmany -o $dir/${tfile}- 10
8449
8450         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8451
8452         [[ $nfiles == 10 ]] ||
8453                 error "lfs find -E 1M found $nfiles != 10 files"
8454
8455         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8456         [[ $nfiles == 25 ]] ||
8457                 error "lfs find ! -E 1M found $nfiles != 25 files"
8458
8459         # All files have a component that starts at 0
8460         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8461         [[ $nfiles == 35 ]] ||
8462                 error "lfs find --component-start 0 - $nfiles != 35 files"
8463
8464         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8465         [[ $nfiles == 15 ]] ||
8466                 error "lfs find --component-start 2M - $nfiles != 15 files"
8467
8468         # All files created here have a componenet that does not starts at 2M
8469         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8470         [[ $nfiles == 35 ]] ||
8471                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8472
8473         # Find files with a specified number of components
8474         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8475         [[ $nfiles == 15 ]] ||
8476                 error "lfs find --component-count 3 - $nfiles != 15 files"
8477
8478         # Remember non-composite files have a component count of zero
8479         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8480         [[ $nfiles == 10 ]] ||
8481                 error "lfs find --component-count 0 - $nfiles != 10 files"
8482
8483         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8484         [[ $nfiles == 20 ]] ||
8485                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8486
8487         # All files have a flag called "init"
8488         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8489         [[ $nfiles == 35 ]] ||
8490                 error "lfs find --component-flags init - $nfiles != 35 files"
8491
8492         # Multi-component files will have a component not initialized
8493         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8494         [[ $nfiles == 15 ]] ||
8495                 error "lfs find !--component-flags init - $nfiles != 15 files"
8496
8497         rm -rf $dir
8498
8499 }
8500 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8501
8502 test_56ca() {
8503         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8504                 skip "Need MDS version at least 2.10.57"
8505
8506         local td=$DIR/$tdir
8507         local tf=$td/$tfile
8508         local dir
8509         local nfiles
8510         local cmd
8511         local i
8512         local j
8513
8514         # create mirrored directories and mirrored files
8515         mkdir $td || error "mkdir $td failed"
8516         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8517         createmany -o $tf- 10 || error "create $tf- failed"
8518
8519         for i in $(seq 2); do
8520                 dir=$td/dir$i
8521                 mkdir $dir || error "mkdir $dir failed"
8522                 $LFS mirror create -N$((3 + i)) $dir ||
8523                         error "create mirrored dir $dir failed"
8524                 createmany -o $dir/$tfile- 10 ||
8525                         error "create $dir/$tfile- failed"
8526         done
8527
8528         # change the states of some mirrored files
8529         echo foo > $tf-6
8530         for i in $(seq 2); do
8531                 dir=$td/dir$i
8532                 for j in $(seq 4 9); do
8533                         echo foo > $dir/$tfile-$j
8534                 done
8535         done
8536
8537         # find mirrored files with specific mirror count
8538         cmd="$LFS find --mirror-count 3 --type f $td"
8539         nfiles=$($cmd | wc -l)
8540         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8541
8542         cmd="$LFS find ! --mirror-count 3 --type f $td"
8543         nfiles=$($cmd | wc -l)
8544         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8545
8546         cmd="$LFS find --mirror-count +2 --type f $td"
8547         nfiles=$($cmd | wc -l)
8548         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8549
8550         cmd="$LFS find --mirror-count -6 --type f $td"
8551         nfiles=$($cmd | wc -l)
8552         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8553
8554         # find mirrored files with specific file state
8555         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8556         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8557
8558         cmd="$LFS find --mirror-state=ro --type f $td"
8559         nfiles=$($cmd | wc -l)
8560         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8561
8562         cmd="$LFS find ! --mirror-state=ro --type f $td"
8563         nfiles=$($cmd | wc -l)
8564         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8565
8566         cmd="$LFS find --mirror-state=wp --type f $td"
8567         nfiles=$($cmd | wc -l)
8568         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8569
8570         cmd="$LFS find ! --mirror-state=sp --type f $td"
8571         nfiles=$($cmd | wc -l)
8572         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8573 }
8574 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8575
8576 test_56da() { # LU-14179
8577         local path=$DIR/$tdir
8578
8579         test_mkdir $path
8580         cd $path
8581
8582         local longdir=$(str_repeat 'a' 255)
8583
8584         for i in {1..15}; do
8585                 path=$path/$longdir
8586                 test_mkdir $longdir
8587                 cd $longdir
8588         done
8589
8590         local len=${#path}
8591         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8592
8593         test_mkdir $lastdir
8594         cd $lastdir
8595         # PATH_MAX-1
8596         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8597
8598         # NAME_MAX
8599         touch $(str_repeat 'f' 255)
8600
8601         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8602                 error "lfs find reported an error"
8603
8604         rm -rf $DIR/$tdir
8605 }
8606 run_test 56da "test lfs find with long paths"
8607
8608 test_56ea() { #LU-10378
8609         local path=$DIR/$tdir
8610         local pool=$TESTNAME
8611
8612         # Create ost pool
8613         pool_add $pool || error "pool_add $pool failed"
8614         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8615                 error "adding targets to $pool failed"
8616
8617         # Set default pool on directory before creating file
8618         mkdir $path || error "mkdir $path failed"
8619         $LFS setstripe -p $pool $path ||
8620                 error "set OST pool on $pool failed"
8621         touch $path/$tfile || error "touch $path/$tfile failed"
8622
8623         # Compare basic file attributes from -printf and stat
8624         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8625         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8626
8627         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8628                 error "Attrs from lfs find and stat don't match"
8629
8630         # Compare Lustre attributes from lfs find and lfs getstripe
8631         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8632         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8633         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8634         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8635         local fpool=$($LFS getstripe --pool $path/$tfile)
8636         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8637
8638         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8639                 error "Attrs from lfs find and lfs getstripe don't match"
8640
8641         # Verify behavior for unknown escape/format sequences
8642         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8643
8644         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8645                 error "Escape/format codes don't match"
8646 }
8647 run_test 56ea "test lfs find -printf option"
8648
8649 test_56eb() {
8650         local dir=$DIR/$tdir
8651         local subdir_1=$dir/subdir_1
8652
8653         test_mkdir -p $subdir_1
8654         ln -s subdir_1 $dir/link_1
8655
8656         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8657                 error "symlink is not followed"
8658
8659         $LFS getstripe --no-follow $dir |
8660                 grep "^$dir/link_1 has no stripe info$" ||
8661                 error "symlink should not have stripe info"
8662
8663         touch $dir/testfile
8664         ln -s testfile $dir/file_link_2
8665
8666         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8667                 error "symlink is not followed"
8668
8669         $LFS getstripe --no-follow $dir |
8670                 grep "^$dir/file_link_2 has no stripe info$" ||
8671                 error "symlink should not have stripe info"
8672 }
8673 run_test 56eb "check lfs getstripe on symlink"
8674
8675 test_57a() {
8676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8677         # note test will not do anything if MDS is not local
8678         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8679                 skip_env "ldiskfs only test"
8680         fi
8681         remote_mds_nodsh && skip "remote MDS with nodsh"
8682
8683         local MNTDEV="osd*.*MDT*.mntdev"
8684         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8685         [ -z "$DEV" ] && error "can't access $MNTDEV"
8686         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8687                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8688                         error "can't access $DEV"
8689                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8690                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8691                 rm $TMP/t57a.dump
8692         done
8693 }
8694 run_test 57a "verify MDS filesystem created with large inodes =="
8695
8696 test_57b() {
8697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8698         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8699                 skip_env "ldiskfs only test"
8700         fi
8701         remote_mds_nodsh && skip "remote MDS with nodsh"
8702
8703         local dir=$DIR/$tdir
8704         local filecount=100
8705         local file1=$dir/f1
8706         local fileN=$dir/f$filecount
8707
8708         rm -rf $dir || error "removing $dir"
8709         test_mkdir -c1 $dir
8710         local mdtidx=$($LFS getstripe -m $dir)
8711         local mdtname=MDT$(printf %04x $mdtidx)
8712         local facet=mds$((mdtidx + 1))
8713
8714         echo "mcreating $filecount files"
8715         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8716
8717         # verify that files do not have EAs yet
8718         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8719                 error "$file1 has an EA"
8720         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8721                 error "$fileN has an EA"
8722
8723         sync
8724         sleep 1
8725         df $dir  #make sure we get new statfs data
8726         local mdsfree=$(do_facet $facet \
8727                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8728         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8729         local file
8730
8731         echo "opening files to create objects/EAs"
8732         for file in $(seq -f $dir/f%g 1 $filecount); do
8733                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8734                         error "opening $file"
8735         done
8736
8737         # verify that files have EAs now
8738         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8739         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8740
8741         sleep 1  #make sure we get new statfs data
8742         df $dir
8743         local mdsfree2=$(do_facet $facet \
8744                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8745         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8746
8747         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8748                 if [ "$mdsfree" != "$mdsfree2" ]; then
8749                         error "MDC before $mdcfree != after $mdcfree2"
8750                 else
8751                         echo "MDC before $mdcfree != after $mdcfree2"
8752                         echo "unable to confirm if MDS has large inodes"
8753                 fi
8754         fi
8755         rm -rf $dir
8756 }
8757 run_test 57b "default LOV EAs are stored inside large inodes ==="
8758
8759 test_58() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761         [ -z "$(which wiretest 2>/dev/null)" ] &&
8762                         skip_env "could not find wiretest"
8763
8764         wiretest
8765 }
8766 run_test 58 "verify cross-platform wire constants =============="
8767
8768 test_59() {
8769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8770
8771         echo "touch 130 files"
8772         createmany -o $DIR/f59- 130
8773         echo "rm 130 files"
8774         unlinkmany $DIR/f59- 130
8775         sync
8776         # wait for commitment of removal
8777         wait_delete_completed
8778 }
8779 run_test 59 "verify cancellation of llog records async ========="
8780
8781 TEST60_HEAD="test_60 run $RANDOM"
8782 test_60a() {
8783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8784         remote_mgs_nodsh && skip "remote MGS with nodsh"
8785         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8786                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8787                         skip_env "missing subtest run-llog.sh"
8788
8789         log "$TEST60_HEAD - from kernel mode"
8790         do_facet mgs "$LCTL dk > /dev/null"
8791         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8792         do_facet mgs $LCTL dk > $TMP/$tfile
8793
8794         # LU-6388: test llog_reader
8795         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8796         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8797         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8798                         skip_env "missing llog_reader"
8799         local fstype=$(facet_fstype mgs)
8800         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8801                 skip_env "Only for ldiskfs or zfs type mgs"
8802
8803         local mntpt=$(facet_mntpt mgs)
8804         local mgsdev=$(mgsdevname 1)
8805         local fid_list
8806         local fid
8807         local rec_list
8808         local rec
8809         local rec_type
8810         local obj_file
8811         local path
8812         local seq
8813         local oid
8814         local pass=true
8815
8816         #get fid and record list
8817         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8818                 tail -n 4))
8819         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8820                 tail -n 4))
8821         #remount mgs as ldiskfs or zfs type
8822         stop mgs || error "stop mgs failed"
8823         mount_fstype mgs || error "remount mgs failed"
8824         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8825                 fid=${fid_list[i]}
8826                 rec=${rec_list[i]}
8827                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8828                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8829                 oid=$((16#$oid))
8830
8831                 case $fstype in
8832                         ldiskfs )
8833                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8834                         zfs )
8835                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8836                 esac
8837                 echo "obj_file is $obj_file"
8838                 do_facet mgs $llog_reader $obj_file
8839
8840                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8841                         awk '{ print $3 }' | sed -e "s/^type=//g")
8842                 if [ $rec_type != $rec ]; then
8843                         echo "FAILED test_60a wrong record type $rec_type," \
8844                               "should be $rec"
8845                         pass=false
8846                         break
8847                 fi
8848
8849                 #check obj path if record type is LLOG_LOGID_MAGIC
8850                 if [ "$rec" == "1064553b" ]; then
8851                         path=$(do_facet mgs $llog_reader $obj_file |
8852                                 grep "path=" | awk '{ print $NF }' |
8853                                 sed -e "s/^path=//g")
8854                         if [ $obj_file != $mntpt/$path ]; then
8855                                 echo "FAILED test_60a wrong obj path" \
8856                                       "$montpt/$path, should be $obj_file"
8857                                 pass=false
8858                                 break
8859                         fi
8860                 fi
8861         done
8862         rm -f $TMP/$tfile
8863         #restart mgs before "error", otherwise it will block the next test
8864         stop mgs || error "stop mgs failed"
8865         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8866         $pass || error "test failed, see FAILED test_60a messages for specifics"
8867 }
8868 run_test 60a "llog_test run from kernel module and test llog_reader"
8869
8870 test_60b() { # bug 6411
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         dmesg > $DIR/$tfile
8874         LLOG_COUNT=$(do_facet mgs dmesg |
8875                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8876                           /llog_[a-z]*.c:[0-9]/ {
8877                                 if (marker)
8878                                         from_marker++
8879                                 from_begin++
8880                           }
8881                           END {
8882                                 if (marker)
8883                                         print from_marker
8884                                 else
8885                                         print from_begin
8886                           }")
8887
8888         [[ $LLOG_COUNT -gt 120 ]] &&
8889                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8890 }
8891 run_test 60b "limit repeated messages from CERROR/CWARN"
8892
8893 test_60c() {
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895
8896         echo "create 5000 files"
8897         createmany -o $DIR/f60c- 5000
8898 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8899         lctl set_param fail_loc=0x80000137
8900         unlinkmany $DIR/f60c- 5000
8901         lctl set_param fail_loc=0
8902 }
8903 run_test 60c "unlink file when mds full"
8904
8905 test_60d() {
8906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8907
8908         SAVEPRINTK=$(lctl get_param -n printk)
8909         # verify "lctl mark" is even working"
8910         MESSAGE="test message ID $RANDOM $$"
8911         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8912         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8913
8914         lctl set_param printk=0 || error "set lnet.printk failed"
8915         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8916         MESSAGE="new test message ID $RANDOM $$"
8917         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8918         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8919         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8920
8921         lctl set_param -n printk="$SAVEPRINTK"
8922 }
8923 run_test 60d "test printk console message masking"
8924
8925 test_60e() {
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         remote_mds_nodsh && skip "remote MDS with nodsh"
8928
8929         touch $DIR/$tfile
8930 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8931         do_facet mds1 lctl set_param fail_loc=0x15b
8932         rm $DIR/$tfile
8933 }
8934 run_test 60e "no space while new llog is being created"
8935
8936 test_60f() {
8937         local old_path=$($LCTL get_param -n debug_path)
8938
8939         stack_trap "$LCTL set_param debug_path=$old_path"
8940         stack_trap "rm -f $TMP/$tfile*"
8941         rm -f $TMP/$tfile* 2> /dev/null
8942         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8943         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8944         test_mkdir $DIR/$tdir
8945         # retry in case the open is cached and not released
8946         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8947                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8948                 sleep 0.1
8949         done
8950         ls $TMP/$tfile*
8951         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8952 }
8953 run_test 60f "change debug_path works"
8954
8955 test_60g() {
8956         local pid
8957         local i
8958
8959         test_mkdir -c $MDSCOUNT $DIR/$tdir
8960
8961         (
8962                 local index=0
8963                 while true; do
8964                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8965                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8966                                 2>/dev/null
8967                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8968                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8969                         index=$((index + 1))
8970                 done
8971         ) &
8972
8973         pid=$!
8974
8975         for i in {0..100}; do
8976                 # define OBD_FAIL_OSD_TXN_START    0x19a
8977                 local index=$((i % MDSCOUNT + 1))
8978
8979                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8980                         > /dev/null
8981                 sleep 0.01
8982         done
8983
8984         kill -9 $pid
8985
8986         for i in $(seq $MDSCOUNT); do
8987                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8988         done
8989
8990         mkdir $DIR/$tdir/new || error "mkdir failed"
8991         rmdir $DIR/$tdir/new || error "rmdir failed"
8992
8993         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8994                 -t namespace
8995         for i in $(seq $MDSCOUNT); do
8996                 wait_update_facet mds$i "$LCTL get_param -n \
8997                         mdd.$(facet_svc mds$i).lfsck_namespace |
8998                         awk '/^status/ { print \\\$2 }'" "completed"
8999         done
9000
9001         ls -R $DIR/$tdir
9002         rm -rf $DIR/$tdir || error "rmdir failed"
9003 }
9004 run_test 60g "transaction abort won't cause MDT hung"
9005
9006 test_60h() {
9007         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9008                 skip "Need MDS version at least 2.12.52"
9009         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9010
9011         local f
9012
9013         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9014         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9015         for fail_loc in 0x80000188 0x80000189; do
9016                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9017                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9018                         error "mkdir $dir-$fail_loc failed"
9019                 for i in {0..10}; do
9020                         # create may fail on missing stripe
9021                         echo $i > $DIR/$tdir-$fail_loc/$i
9022                 done
9023                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9024                         error "getdirstripe $tdir-$fail_loc failed"
9025                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9026                         error "migrate $tdir-$fail_loc failed"
9027                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9028                         error "getdirstripe $tdir-$fail_loc failed"
9029                 pushd $DIR/$tdir-$fail_loc
9030                 for f in *; do
9031                         echo $f | cmp $f - || error "$f data mismatch"
9032                 done
9033                 popd
9034                 rm -rf $DIR/$tdir-$fail_loc
9035         done
9036 }
9037 run_test 60h "striped directory with missing stripes can be accessed"
9038
9039 function t60i_load() {
9040         mkdir $DIR/$tdir
9041         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9042         $LCTL set_param fail_loc=0x131c fail_val=1
9043         for ((i=0; i<5000; i++)); do
9044                 touch $DIR/$tdir/f$i
9045         done
9046 }
9047
9048 test_60i() {
9049         changelog_register || error "changelog_register failed"
9050         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9051         changelog_users $SINGLEMDS | grep -q $cl_user ||
9052                 error "User $cl_user not found in changelog_users"
9053         changelog_chmask "ALL"
9054         t60i_load &
9055         local PID=$!
9056         for((i=0; i<100; i++)); do
9057                 changelog_dump >/dev/null ||
9058                         error "can't read changelog"
9059         done
9060         kill $PID
9061         wait $PID
9062         changelog_deregister || error "changelog_deregister failed"
9063         $LCTL set_param fail_loc=0
9064 }
9065 run_test 60i "llog: new record vs reader race"
9066
9067 test_60j() {
9068         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9069                 skip "need MDS version at least 2.15.50"
9070         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9071         remote_mds_nodsh && skip "remote MDS with nodsh"
9072         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9073
9074         changelog_users $SINGLEMDS | grep "^cl" &&
9075                 skip "active changelog user"
9076
9077         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9078
9079         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9080                 skip_env "missing llog_reader"
9081
9082         mkdir_on_mdt0 $DIR/$tdir
9083
9084         local f=$DIR/$tdir/$tfile
9085         local mdt_dev
9086         local tmpfile
9087         local plain
9088
9089         changelog_register || error "cannot register changelog user"
9090
9091         # set changelog_mask to ALL
9092         changelog_chmask "ALL"
9093         changelog_clear
9094
9095         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9096         unlinkmany ${f}- 100 || error "unlinkmany failed"
9097
9098         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9099         mdt_dev=$(facet_device $SINGLEMDS)
9100
9101         do_facet $SINGLEMDS sync
9102         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9103                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9104                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9105
9106         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9107
9108         # if $tmpfile is not on EXT3 filesystem for some reason
9109         [[ ${plain:0:1} == 'O' ]] ||
9110                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9111
9112         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9113                 $mdt_dev; stat -c %s $tmpfile")
9114         echo "Truncate llog from $size to $((size - size % 8192))"
9115         size=$((size - size % 8192))
9116         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9117         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9118                 grep -c 'in bitmap only')
9119         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9120
9121         size=$((size - 9000))
9122         echo "Corrupt llog in the middle at $size"
9123         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9124                 count=333 conv=notrunc
9125         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9126                 grep -c 'next chunk')
9127         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9128 }
9129 run_test 60j "llog_reader reports corruptions"
9130
9131 test_61a() {
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133
9134         f="$DIR/f61"
9135         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9136         cancel_lru_locks osc
9137         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9138         sync
9139 }
9140 run_test 61a "mmap() writes don't make sync hang ================"
9141
9142 test_61b() {
9143         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9144 }
9145 run_test 61b "mmap() of unstriped file is successful"
9146
9147 # bug 2330 - insufficient obd_match error checking causes LBUG
9148 test_62() {
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150
9151         f="$DIR/f62"
9152         echo foo > $f
9153         cancel_lru_locks osc
9154         lctl set_param fail_loc=0x405
9155         cat $f && error "cat succeeded, expect -EIO"
9156         lctl set_param fail_loc=0
9157 }
9158 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9159 # match every page all of the time.
9160 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9161
9162 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9163 # Though this test is irrelevant anymore, it helped to reveal some
9164 # other grant bugs (LU-4482), let's keep it.
9165 test_63a() {   # was test_63
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9169
9170         for i in `seq 10` ; do
9171                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9172                 sleep 5
9173                 kill $!
9174                 sleep 1
9175         done
9176
9177         rm -f $DIR/f63 || true
9178 }
9179 run_test 63a "Verify oig_wait interruption does not crash ======="
9180
9181 # bug 2248 - async write errors didn't return to application on sync
9182 # bug 3677 - async write errors left page locked
9183 test_63b() {
9184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9185
9186         debugsave
9187         lctl set_param debug=-1
9188
9189         # ensure we have a grant to do async writes
9190         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9191         rm $DIR/$tfile
9192
9193         sync    # sync lest earlier test intercept the fail_loc
9194
9195         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9196         lctl set_param fail_loc=0x80000406
9197         $MULTIOP $DIR/$tfile Owy && \
9198                 error "sync didn't return ENOMEM"
9199         sync; sleep 2; sync     # do a real sync this time to flush page
9200         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9201                 error "locked page left in cache after async error" || true
9202         debugrestore
9203 }
9204 run_test 63b "async write errors should be returned to fsync ==="
9205
9206 test_64a () {
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208
9209         lfs df $DIR
9210         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9211 }
9212 run_test 64a "verify filter grant calculations (in kernel) ====="
9213
9214 test_64b () {
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216
9217         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9218 }
9219 run_test 64b "check out-of-space detection on client"
9220
9221 test_64c() {
9222         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9223 }
9224 run_test 64c "verify grant shrink"
9225
9226 import_param() {
9227         local tgt=$1
9228         local param=$2
9229
9230         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9231 }
9232
9233 # this does exactly what osc_request.c:osc_announce_cached() does in
9234 # order to calculate max amount of grants to ask from server
9235 want_grant() {
9236         local tgt=$1
9237
9238         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9239         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9240
9241         ((rpc_in_flight++));
9242         nrpages=$((nrpages * rpc_in_flight))
9243
9244         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9245
9246         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9247
9248         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9249         local undirty=$((nrpages * PAGE_SIZE))
9250
9251         local max_extent_pages
9252         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9253         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9254         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9255         local grant_extent_tax
9256         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9257
9258         undirty=$((undirty + nrextents * grant_extent_tax))
9259
9260         echo $undirty
9261 }
9262
9263 # this is size of unit for grant allocation. It should be equal to
9264 # what tgt_grant.c:tgt_grant_chunk() calculates
9265 grant_chunk() {
9266         local tgt=$1
9267         local max_brw_size
9268         local grant_extent_tax
9269
9270         max_brw_size=$(import_param $tgt max_brw_size)
9271
9272         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9273
9274         echo $(((max_brw_size + grant_extent_tax) * 2))
9275 }
9276
9277 test_64d() {
9278         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9279                 skip "OST < 2.10.55 doesn't limit grants enough"
9280
9281         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9282
9283         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9284                 skip "no grant_param connect flag"
9285
9286         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9287
9288         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9289         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9290
9291
9292         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9293         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9294
9295         $LFS setstripe $DIR/$tfile -i 0 -c 1
9296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9297         ddpid=$!
9298
9299         while kill -0 $ddpid; do
9300                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9301
9302                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9303                         kill $ddpid
9304                         error "cur_grant $cur_grant > $max_cur_granted"
9305                 fi
9306
9307                 sleep 1
9308         done
9309 }
9310 run_test 64d "check grant limit exceed"
9311
9312 check_grants() {
9313         local tgt=$1
9314         local expected=$2
9315         local msg=$3
9316         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9317
9318         ((cur_grants == expected)) ||
9319                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9320 }
9321
9322 round_up_p2() {
9323         echo $((($1 + $2 - 1) & ~($2 - 1)))
9324 }
9325
9326 test_64e() {
9327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9328         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9329                 skip "Need OSS version at least 2.11.56"
9330
9331         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9332         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9333         $LCTL set_param debug=+cache
9334
9335         # Remount client to reset grant
9336         remount_client $MOUNT || error "failed to remount client"
9337         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9338
9339         local init_grants=$(import_param $osc_tgt initial_grant)
9340
9341         check_grants $osc_tgt $init_grants "init grants"
9342
9343         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9344         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9345         local gbs=$(import_param $osc_tgt grant_block_size)
9346
9347         # write random number of bytes from max_brw_size / 4 to max_brw_size
9348         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9349         # align for direct io
9350         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9351         # round to grant consumption unit
9352         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9353
9354         local grants=$((wb_round_up + extent_tax))
9355
9356         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9357
9358         # define OBD_FAIL_TGT_NO_GRANT 0x725
9359         # make the server not grant more back
9360         do_facet ost1 $LCTL set_param fail_loc=0x725
9361         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9362
9363         do_facet ost1 $LCTL set_param fail_loc=0
9364
9365         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9366
9367         rm -f $DIR/$tfile || error "rm failed"
9368
9369         # Remount client to reset grant
9370         remount_client $MOUNT || error "failed to remount client"
9371         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9372
9373         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9374
9375         # define OBD_FAIL_TGT_NO_GRANT 0x725
9376         # make the server not grant more back
9377         do_facet ost1 $LCTL set_param fail_loc=0x725
9378         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9379         do_facet ost1 $LCTL set_param fail_loc=0
9380
9381         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9382 }
9383 run_test 64e "check grant consumption (no grant allocation)"
9384
9385 test_64f() {
9386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9387
9388         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9389         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9390         $LCTL set_param debug=+cache
9391
9392         # Remount client to reset grant
9393         remount_client $MOUNT || error "failed to remount client"
9394         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9395
9396         local init_grants=$(import_param $osc_tgt initial_grant)
9397         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9398         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9399         local gbs=$(import_param $osc_tgt grant_block_size)
9400         local chunk=$(grant_chunk $osc_tgt)
9401
9402         # write random number of bytes from max_brw_size / 4 to max_brw_size
9403         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9404         # align for direct io
9405         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9406         # round to grant consumption unit
9407         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9408
9409         local grants=$((wb_round_up + extent_tax))
9410
9411         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9412         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9413                 error "error writing to $DIR/$tfile"
9414
9415         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9416                 "direct io with grant allocation"
9417
9418         rm -f $DIR/$tfile || error "rm failed"
9419
9420         # Remount client to reset grant
9421         remount_client $MOUNT || error "failed to remount client"
9422         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9423
9424         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9425
9426         local cmd="oO_WRONLY:w${write_bytes}_yc"
9427
9428         $MULTIOP $DIR/$tfile $cmd &
9429         MULTIPID=$!
9430         sleep 1
9431
9432         check_grants $osc_tgt $((init_grants - grants)) \
9433                 "buffered io, not write rpc"
9434
9435         kill -USR1 $MULTIPID
9436         wait
9437
9438         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9439                 "buffered io, one RPC"
9440 }
9441 run_test 64f "check grant consumption (with grant allocation)"
9442
9443 test_64g() {
9444         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9445                 skip "Need MDS version at least 2.14.56"
9446
9447         local mdts=$(comma_list $(mdts_nodes))
9448
9449         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9450                         tr '\n' ' ')
9451         stack_trap "$LCTL set_param $old"
9452
9453         # generate dirty pages and increase dirty granted on MDT
9454         stack_trap "rm -f $DIR/$tfile-*"
9455         for (( i = 0; i < 10; i++)); do
9456                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9457                         error "can't set stripe"
9458                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9459                         error "can't dd"
9460                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9461                         $LFS getstripe $DIR/$tfile-$i
9462                         error "not DoM file"
9463                 }
9464         done
9465
9466         # flush dirty pages
9467         sync
9468
9469         # wait until grant shrink reset grant dirty on MDTs
9470         for ((i = 0; i < 120; i++)); do
9471                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9472                         awk '{sum=sum+$1} END {print sum}')
9473                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9474                 echo "$grant_dirty grants, $vm_dirty pages"
9475                 (( grant_dirty + vm_dirty == 0 )) && break
9476                 (( i == 3 )) && sync &&
9477                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9478                 sleep 1
9479         done
9480
9481         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9482                 awk '{sum=sum+$1} END {print sum}')
9483         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9484 }
9485 run_test 64g "grant shrink on MDT"
9486
9487 test_64h() {
9488         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9489                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9490
9491         local instance=$($LFS getname -i $DIR)
9492         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9493         local num_exps=$(do_facet ost1 \
9494             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9495         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9496         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9498
9499         # 10MiB is for file to be written, max_brw_size * 16 *
9500         # num_exps is space reserve so that tgt_grant_shrink() decided
9501         # to not shrink
9502         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9503         (( avail * 1024 < expect )) &&
9504                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9505
9506         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9507         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9508         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9509         $LCTL set_param osc.*OST0000*.grant_shrink=1
9510         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9511
9512         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9513         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9514
9515         # drop cache so that coming read would do rpc
9516         cancel_lru_locks osc
9517
9518         # shrink interval is set to 10, pause for 7 seconds so that
9519         # grant thread did not wake up yet but coming read entered
9520         # shrink mode for rpc (osc_should_shrink_grant())
9521         sleep 7
9522
9523         declare -a cur_grant_bytes
9524         declare -a tot_granted
9525         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9526         tot_granted[0]=$(do_facet ost1 \
9527             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9528
9529         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9530
9531         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9532         tot_granted[1]=$(do_facet ost1 \
9533             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9534
9535         # grant change should be equal on both sides
9536         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9537                 tot_granted[0] - tot_granted[1])) ||
9538                 error "grant change mismatch, "                                \
9539                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9540                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9541 }
9542 run_test 64h "grant shrink on read"
9543
9544 test_64i() {
9545         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9546                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9547
9548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9549         remote_ost_nodsh && skip "remote OSTs with nodsh"
9550
9551         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9552
9553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9554
9555         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9556         local instance=$($LFS getname -i $DIR)
9557
9558         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9559         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9560
9561         # shrink grants and simulate rpc loss
9562         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9563         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9564         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9565
9566         fail ost1
9567
9568         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9569
9570         local testid=$(echo $TESTNAME | tr '_' ' ')
9571
9572         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9573                 grep "GRANT, real grant" &&
9574                 error "client has more grants then it owns" || true
9575 }
9576 run_test 64i "shrink on reconnect"
9577
9578 # bug 1414 - set/get directories' stripe info
9579 test_65a() {
9580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9581
9582         test_mkdir $DIR/$tdir
9583         touch $DIR/$tdir/f1
9584         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9585 }
9586 run_test 65a "directory with no stripe info"
9587
9588 test_65b() {
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590
9591         test_mkdir $DIR/$tdir
9592         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9593
9594         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9595                                                 error "setstripe"
9596         touch $DIR/$tdir/f2
9597         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9598 }
9599 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9600
9601 test_65c() {
9602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9603         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9604
9605         test_mkdir $DIR/$tdir
9606         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9607
9608         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9609                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9610         touch $DIR/$tdir/f3
9611         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9612 }
9613 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9614
9615 test_65d() {
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617
9618         test_mkdir $DIR/$tdir
9619         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9620         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9621
9622         if [[ $STRIPECOUNT -le 0 ]]; then
9623                 sc=1
9624         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9625                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9626                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9627         else
9628                 sc=$(($STRIPECOUNT - 1))
9629         fi
9630         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9631         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9632         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9633                 error "lverify failed"
9634 }
9635 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9636
9637 test_65e() {
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639
9640         test_mkdir $DIR/$tdir
9641
9642         $LFS setstripe $DIR/$tdir || error "setstripe"
9643         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9644                                         error "no stripe info failed"
9645         touch $DIR/$tdir/f6
9646         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9647 }
9648 run_test 65e "directory setstripe defaults"
9649
9650 test_65f() {
9651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9652
9653         test_mkdir $DIR/${tdir}f
9654         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9655                 error "setstripe succeeded" || true
9656 }
9657 run_test 65f "dir setstripe permission (should return error) ==="
9658
9659 test_65g() {
9660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9661
9662         test_mkdir $DIR/$tdir
9663         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9664
9665         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9666                 error "setstripe -S failed"
9667         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9668         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9669                 error "delete default stripe failed"
9670 }
9671 run_test 65g "directory setstripe -d"
9672
9673 test_65h() {
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675
9676         test_mkdir $DIR/$tdir
9677         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9678
9679         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9680                 error "setstripe -S failed"
9681         test_mkdir $DIR/$tdir/dd1
9682         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9683                 error "stripe info inherit failed"
9684 }
9685 run_test 65h "directory stripe info inherit ===================="
9686
9687 test_65i() {
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689
9690         save_layout_restore_at_exit $MOUNT
9691
9692         # bug6367: set non-default striping on root directory
9693         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9694
9695         # bug12836: getstripe on -1 default directory striping
9696         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9697
9698         # bug12836: getstripe -v on -1 default directory striping
9699         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9700
9701         # bug12836: new find on -1 default directory striping
9702         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9703 }
9704 run_test 65i "various tests to set root directory striping"
9705
9706 test_65j() { # bug6367
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708
9709         sync; sleep 1
9710
9711         # if we aren't already remounting for each test, do so for this test
9712         if [ "$I_MOUNTED" = "yes" ]; then
9713                 cleanup || error "failed to unmount"
9714                 setup
9715         fi
9716
9717         save_layout_restore_at_exit $MOUNT
9718
9719         $LFS setstripe -d $MOUNT || error "setstripe failed"
9720 }
9721 run_test 65j "set default striping on root directory (bug 6367)="
9722
9723 cleanup_65k() {
9724         rm -rf $DIR/$tdir
9725         wait_delete_completed
9726         do_facet $SINGLEMDS "lctl set_param -n \
9727                 osp.$ost*MDT0000.max_create_count=$max_count"
9728         do_facet $SINGLEMDS "lctl set_param -n \
9729                 osp.$ost*MDT0000.create_count=$count"
9730         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9731         echo $INACTIVE_OSC "is Activate"
9732
9733         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9734 }
9735
9736 test_65k() { # bug11679
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9739         remote_mds_nodsh && skip "remote MDS with nodsh"
9740
9741         local disable_precreate=true
9742         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9743                 disable_precreate=false
9744
9745         echo "Check OST status: "
9746         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9747                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9748
9749         for OSC in $MDS_OSCS; do
9750                 echo $OSC "is active"
9751                 do_facet $SINGLEMDS lctl --device %$OSC activate
9752         done
9753
9754         for INACTIVE_OSC in $MDS_OSCS; do
9755                 local ost=$(osc_to_ost $INACTIVE_OSC)
9756                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9757                                lov.*md*.target_obd |
9758                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9759
9760                 mkdir -p $DIR/$tdir
9761                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9762                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9763
9764                 echo "Deactivate: " $INACTIVE_OSC
9765                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9766
9767                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9768                               osp.$ost*MDT0000.create_count")
9769                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9770                                   osp.$ost*MDT0000.max_create_count")
9771                 $disable_precreate &&
9772                         do_facet $SINGLEMDS "lctl set_param -n \
9773                                 osp.$ost*MDT0000.max_create_count=0"
9774
9775                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9776                         [ -f $DIR/$tdir/$idx ] && continue
9777                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9778                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9779                                 { cleanup_65k;
9780                                   error "setstripe $idx should succeed"; }
9781                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9782                 done
9783                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9784                 rmdir $DIR/$tdir
9785
9786                 do_facet $SINGLEMDS "lctl set_param -n \
9787                         osp.$ost*MDT0000.max_create_count=$max_count"
9788                 do_facet $SINGLEMDS "lctl set_param -n \
9789                         osp.$ost*MDT0000.create_count=$count"
9790                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9791                 echo $INACTIVE_OSC "is Activate"
9792
9793                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9794         done
9795 }
9796 run_test 65k "validate manual striping works properly with deactivated OSCs"
9797
9798 test_65l() { # bug 12836
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800
9801         test_mkdir -p $DIR/$tdir/test_dir
9802         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9803         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9804 }
9805 run_test 65l "lfs find on -1 stripe dir ========================"
9806
9807 test_65m() {
9808         local layout=$(save_layout $MOUNT)
9809         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9810                 restore_layout $MOUNT $layout
9811                 error "setstripe should fail by non-root users"
9812         }
9813         true
9814 }
9815 run_test 65m "normal user can't set filesystem default stripe"
9816
9817 test_65n() {
9818         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9819         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9820                 skip "Need MDS version at least 2.12.50"
9821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9822
9823         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9824         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9825         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9826
9827         save_layout_restore_at_exit $MOUNT
9828
9829         # new subdirectory under root directory should not inherit
9830         # the default layout from root
9831         local dir1=$MOUNT/$tdir-1
9832         mkdir $dir1 || error "mkdir $dir1 failed"
9833         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9834                 error "$dir1 shouldn't have LOV EA"
9835
9836         # delete the default layout on root directory
9837         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9838
9839         local dir2=$MOUNT/$tdir-2
9840         mkdir $dir2 || error "mkdir $dir2 failed"
9841         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9842                 error "$dir2 shouldn't have LOV EA"
9843
9844         # set a new striping pattern on root directory
9845         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9846         local new_def_stripe_size=$((def_stripe_size * 2))
9847         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9848                 error "set stripe size on $MOUNT failed"
9849
9850         # new file created in $dir2 should inherit the new stripe size from
9851         # the filesystem default
9852         local file2=$dir2/$tfile-2
9853         touch $file2 || error "touch $file2 failed"
9854
9855         local file2_stripe_size=$($LFS getstripe -S $file2)
9856         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9857         {
9858                 echo "file2_stripe_size: '$file2_stripe_size'"
9859                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9860                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9861         }
9862
9863         local dir3=$MOUNT/$tdir-3
9864         mkdir $dir3 || error "mkdir $dir3 failed"
9865         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9866         # the root layout, which is the actual default layout that will be used
9867         # when new files are created in $dir3.
9868         local dir3_layout=$(get_layout_param $dir3)
9869         local root_dir_layout=$(get_layout_param $MOUNT)
9870         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9871         {
9872                 echo "dir3_layout: '$dir3_layout'"
9873                 echo "root_dir_layout: '$root_dir_layout'"
9874                 error "$dir3 should show the default layout from $MOUNT"
9875         }
9876
9877         # set OST pool on root directory
9878         local pool=$TESTNAME
9879         pool_add $pool || error "add $pool failed"
9880         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9881                 error "add targets to $pool failed"
9882
9883         $LFS setstripe -p $pool $MOUNT ||
9884                 error "set OST pool on $MOUNT failed"
9885
9886         # new file created in $dir3 should inherit the pool from
9887         # the filesystem default
9888         local file3=$dir3/$tfile-3
9889         touch $file3 || error "touch $file3 failed"
9890
9891         local file3_pool=$($LFS getstripe -p $file3)
9892         [[ "$file3_pool" = "$pool" ]] ||
9893                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9894
9895         local dir4=$MOUNT/$tdir-4
9896         mkdir $dir4 || error "mkdir $dir4 failed"
9897         local dir4_layout=$(get_layout_param $dir4)
9898         root_dir_layout=$(get_layout_param $MOUNT)
9899         echo "$LFS getstripe -d $dir4"
9900         $LFS getstripe -d $dir4
9901         echo "$LFS getstripe -d $MOUNT"
9902         $LFS getstripe -d $MOUNT
9903         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9904         {
9905                 echo "dir4_layout: '$dir4_layout'"
9906                 echo "root_dir_layout: '$root_dir_layout'"
9907                 error "$dir4 should show the default layout from $MOUNT"
9908         }
9909
9910         # new file created in $dir4 should inherit the pool from
9911         # the filesystem default
9912         local file4=$dir4/$tfile-4
9913         touch $file4 || error "touch $file4 failed"
9914
9915         local file4_pool=$($LFS getstripe -p $file4)
9916         [[ "$file4_pool" = "$pool" ]] ||
9917                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9918
9919         # new subdirectory under non-root directory should inherit
9920         # the default layout from its parent directory
9921         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9922                 error "set directory layout on $dir4 failed"
9923
9924         local dir5=$dir4/$tdir-5
9925         mkdir $dir5 || error "mkdir $dir5 failed"
9926
9927         dir4_layout=$(get_layout_param $dir4)
9928         local dir5_layout=$(get_layout_param $dir5)
9929         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9930         {
9931                 echo "dir4_layout: '$dir4_layout'"
9932                 echo "dir5_layout: '$dir5_layout'"
9933                 error "$dir5 should inherit the default layout from $dir4"
9934         }
9935
9936         # though subdir under ROOT doesn't inherit default layout, but
9937         # its sub dir/file should be created with default layout.
9938         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9939         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9940                 skip "Need MDS version at least 2.12.59"
9941
9942         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9943         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9944         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9945
9946         if [ $default_lmv_hash == "none" ]; then
9947                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9948         else
9949                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9950                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9951         fi
9952
9953         $LFS setdirstripe -D -c 2 $MOUNT ||
9954                 error "setdirstripe -D -c 2 failed"
9955         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9956         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9957         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9958
9959         # $dir4 layout includes pool
9960         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9961         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9962                 error "pool lost on setstripe"
9963         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9964         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9965                 error "pool lost on compound layout setstripe"
9966 }
9967 run_test 65n "don't inherit default layout from root for new subdirectories"
9968
9969 test_65o() {
9970         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9971                 skip "need MDS version at least 2.14.57"
9972
9973         # set OST pool on root directory
9974         local pool=$TESTNAME
9975
9976         pool_add $pool || error "add $pool failed"
9977         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9978                 error "add targets to $pool failed"
9979
9980         local dir1=$MOUNT/$tdir
9981
9982         mkdir $dir1 || error "mkdir $dir1 failed"
9983
9984         # set a new striping pattern on root directory
9985         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9986
9987         $LFS setstripe -p $pool $dir1 ||
9988                 error "set directory layout on $dir1 failed"
9989
9990         # $dir1 layout includes pool
9991         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9992         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9993                 error "pool lost on setstripe"
9994         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9995         $LFS getstripe $dir1
9996         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9997                 error "pool lost on compound layout setstripe"
9998
9999         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10000                 error "setdirstripe failed on sub-dir with inherited pool"
10001         $LFS getstripe $dir1/dir2
10002         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10003                 error "pool lost on compound layout setdirstripe"
10004
10005         $LFS setstripe -E -1 -c 1 $dir1
10006         $LFS getstripe -d $dir1
10007         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10008                 error "pool lost on setstripe"
10009 }
10010 run_test 65o "pool inheritance for mdt component"
10011
10012 test_65p () { # LU-16152
10013         local src_dir=$DIR/$tdir/src_dir
10014         local dst_dir=$DIR/$tdir/dst_dir
10015         local yaml_file=$DIR/$tdir/layout.yaml
10016         local border
10017
10018         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10019                 skip "Need at least version 2.15.51"
10020
10021         test_mkdir -p $src_dir
10022         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10023                 error "failed to setstripe"
10024         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10025                 error "failed to getstripe"
10026
10027         test_mkdir -p $dst_dir
10028         $LFS setstripe --yaml $yaml_file $dst_dir ||
10029                 error "failed to setstripe with yaml file"
10030         border=$($LFS getstripe -d $dst_dir |
10031                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10032                 error "failed to getstripe"
10033
10034         # 2048M is 0x80000000, or 2147483648
10035         (( $border == 2147483648 )) ||
10036                 error "failed to handle huge number in yaml layout"
10037 }
10038 run_test 65p "setstripe with yaml file and huge number"
10039
10040 # bug 2543 - update blocks count on client
10041 test_66() {
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         local COUNT=${COUNT:-8}
10045         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10046         sync; sync_all_data; sync; sync_all_data
10047         cancel_lru_locks osc
10048         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10049         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10050 }
10051 run_test 66 "update inode blocks count on client ==============="
10052
10053 meminfo() {
10054         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10055 }
10056
10057 swap_used() {
10058         swapon -s | awk '($1 == "'$1'") { print $4 }'
10059 }
10060
10061 # bug5265, obdfilter oa2dentry return -ENOENT
10062 # #define OBD_FAIL_SRV_ENOENT 0x217
10063 test_69() {
10064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10065         remote_ost_nodsh && skip "remote OST with nodsh"
10066
10067         f="$DIR/$tfile"
10068         $LFS setstripe -c 1 -i 0 $f
10069
10070         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10071
10072         do_facet ost1 lctl set_param fail_loc=0x217
10073         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10074         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10075
10076         do_facet ost1 lctl set_param fail_loc=0
10077         $DIRECTIO write $f 0 2 || error "write error"
10078
10079         cancel_lru_locks osc
10080         $DIRECTIO read $f 0 1 || error "read error"
10081
10082         do_facet ost1 lctl set_param fail_loc=0x217
10083         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10084
10085         do_facet ost1 lctl set_param fail_loc=0
10086         rm -f $f
10087 }
10088 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10089
10090 test_71() {
10091         test_mkdir $DIR/$tdir
10092         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10093         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10094 }
10095 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10096
10097 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10099         [ "$RUNAS_ID" = "$UID" ] &&
10100                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10101         # Check that testing environment is properly set up. Skip if not
10102         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10103                 skip_env "User $RUNAS_ID does not exist - skipping"
10104
10105         touch $DIR/$tfile
10106         chmod 777 $DIR/$tfile
10107         chmod ug+s $DIR/$tfile
10108         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10109                 error "$RUNAS dd $DIR/$tfile failed"
10110         # See if we are still setuid/sgid
10111         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10112                 error "S/gid is not dropped on write"
10113         # Now test that MDS is updated too
10114         cancel_lru_locks mdc
10115         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10116                 error "S/gid is not dropped on MDS"
10117         rm -f $DIR/$tfile
10118 }
10119 run_test 72a "Test that remove suid works properly (bug5695) ===="
10120
10121 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10122         local perm
10123
10124         [ "$RUNAS_ID" = "$UID" ] &&
10125                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10126         [ "$RUNAS_ID" -eq 0 ] &&
10127                 skip_env "RUNAS_ID = 0 -- skipping"
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         # Check that testing environment is properly set up. Skip if not
10130         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10131                 skip_env "User $RUNAS_ID does not exist - skipping"
10132
10133         touch $DIR/${tfile}-f{g,u}
10134         test_mkdir $DIR/${tfile}-dg
10135         test_mkdir $DIR/${tfile}-du
10136         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10137         chmod g+s $DIR/${tfile}-{f,d}g
10138         chmod u+s $DIR/${tfile}-{f,d}u
10139         for perm in 777 2777 4777; do
10140                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10141                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10142                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10143                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10144         done
10145         true
10146 }
10147 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10148
10149 # bug 3462 - multiple simultaneous MDC requests
10150 test_73() {
10151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10152
10153         test_mkdir $DIR/d73-1
10154         test_mkdir $DIR/d73-2
10155         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10156         pid1=$!
10157
10158         lctl set_param fail_loc=0x80000129
10159         $MULTIOP $DIR/d73-1/f73-2 Oc &
10160         sleep 1
10161         lctl set_param fail_loc=0
10162
10163         $MULTIOP $DIR/d73-2/f73-3 Oc &
10164         pid3=$!
10165
10166         kill -USR1 $pid1
10167         wait $pid1 || return 1
10168
10169         sleep 25
10170
10171         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10172         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10173         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10174
10175         rm -rf $DIR/d73-*
10176 }
10177 run_test 73 "multiple MDC requests (should not deadlock)"
10178
10179 test_74a() { # bug 6149, 6184
10180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10181
10182         touch $DIR/f74a
10183         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10184         #
10185         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10186         # will spin in a tight reconnection loop
10187         $LCTL set_param fail_loc=0x8000030e
10188         # get any lock that won't be difficult - lookup works.
10189         ls $DIR/f74a
10190         $LCTL set_param fail_loc=0
10191         rm -f $DIR/f74a
10192         true
10193 }
10194 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10195
10196 test_74b() { # bug 13310
10197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10198
10199         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10200         #
10201         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10202         # will spin in a tight reconnection loop
10203         $LCTL set_param fail_loc=0x8000030e
10204         # get a "difficult" lock
10205         touch $DIR/f74b
10206         $LCTL set_param fail_loc=0
10207         rm -f $DIR/f74b
10208         true
10209 }
10210 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10211
10212 test_74c() {
10213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10214
10215         #define OBD_FAIL_LDLM_NEW_LOCK
10216         $LCTL set_param fail_loc=0x319
10217         touch $DIR/$tfile && error "touch successful"
10218         $LCTL set_param fail_loc=0
10219         true
10220 }
10221 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10222
10223 slab_lic=/sys/kernel/slab/lustre_inode_cache
10224 num_objects() {
10225         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10226         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10227                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10228 }
10229
10230 test_76a() { # Now for b=20433, added originally in b=1443
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232
10233         cancel_lru_locks osc
10234         # there may be some slab objects cached per core
10235         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10236         local before=$(num_objects)
10237         local count=$((512 * cpus))
10238         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10239         local margin=$((count / 10))
10240         if [[ -f $slab_lic/aliases ]]; then
10241                 local aliases=$(cat $slab_lic/aliases)
10242                 (( aliases > 0 )) && margin=$((margin * aliases))
10243         fi
10244
10245         echo "before slab objects: $before"
10246         for i in $(seq $count); do
10247                 touch $DIR/$tfile
10248                 rm -f $DIR/$tfile
10249         done
10250         cancel_lru_locks osc
10251         local after=$(num_objects)
10252         echo "created: $count, after slab objects: $after"
10253         # shared slab counts are not very accurate, allow significant margin
10254         # the main goal is that the cache growth is not permanently > $count
10255         while (( after > before + margin )); do
10256                 sleep 1
10257                 after=$(num_objects)
10258                 wait=$((wait + 1))
10259                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10260                 if (( wait > 60 )); then
10261                         error "inode slab grew from $before+$margin to $after"
10262                 fi
10263         done
10264 }
10265 run_test 76a "confirm clients recycle inodes properly ===="
10266
10267 test_76b() {
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10270
10271         local count=512
10272         local before=$(num_objects)
10273
10274         for i in $(seq $count); do
10275                 mkdir $DIR/$tdir
10276                 rmdir $DIR/$tdir
10277         done
10278
10279         local after=$(num_objects)
10280         local wait=0
10281
10282         while (( after > before )); do
10283                 sleep 1
10284                 after=$(num_objects)
10285                 wait=$((wait + 1))
10286                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10287                 if (( wait > 60 )); then
10288                         error "inode slab grew from $before to $after"
10289                 fi
10290         done
10291
10292         echo "slab objects before: $before, after: $after"
10293 }
10294 run_test 76b "confirm clients recycle directory inodes properly ===="
10295
10296 export ORIG_CSUM=""
10297 set_checksums()
10298 {
10299         # Note: in sptlrpc modes which enable its own bulk checksum, the
10300         # original crc32_le bulk checksum will be automatically disabled,
10301         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10302         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10303         # In this case set_checksums() will not be no-op, because sptlrpc
10304         # bulk checksum will be enabled all through the test.
10305
10306         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10307         lctl set_param -n osc.*.checksums $1
10308         return 0
10309 }
10310
10311 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10312                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10313 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10314                              tr -d [] | head -n1)}
10315 set_checksum_type()
10316 {
10317         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10318         rc=$?
10319         log "set checksum type to $1, rc = $rc"
10320         return $rc
10321 }
10322
10323 get_osc_checksum_type()
10324 {
10325         # arugment 1: OST name, like OST0000
10326         ost=$1
10327         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10328                         sed 's/.*\[\(.*\)\].*/\1/g')
10329         rc=$?
10330         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10331         echo $checksum_type
10332 }
10333
10334 F77_TMP=$TMP/f77-temp
10335 F77SZ=8
10336 setup_f77() {
10337         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10338                 error "error writing to $F77_TMP"
10339 }
10340
10341 test_77a() { # bug 10889
10342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10343         $GSS && skip_env "could not run with gss"
10344
10345         [ ! -f $F77_TMP ] && setup_f77
10346         set_checksums 1
10347         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10348         set_checksums 0
10349         rm -f $DIR/$tfile
10350 }
10351 run_test 77a "normal checksum read/write operation"
10352
10353 test_77b() { # bug 10889
10354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10355         $GSS && skip_env "could not run with gss"
10356
10357         [ ! -f $F77_TMP ] && setup_f77
10358         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10359         $LCTL set_param fail_loc=0x80000409
10360         set_checksums 1
10361
10362         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10363                 error "dd error: $?"
10364         $LCTL set_param fail_loc=0
10365
10366         for algo in $CKSUM_TYPES; do
10367                 cancel_lru_locks osc
10368                 set_checksum_type $algo
10369                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10370                 $LCTL set_param fail_loc=0x80000408
10371                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10372                 $LCTL set_param fail_loc=0
10373         done
10374         set_checksums 0
10375         set_checksum_type $ORIG_CSUM_TYPE
10376         rm -f $DIR/$tfile
10377 }
10378 run_test 77b "checksum error on client write, read"
10379
10380 cleanup_77c() {
10381         trap 0
10382         set_checksums 0
10383         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10384         $check_ost &&
10385                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10386         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10387         $check_ost && [ -n "$ost_file_prefix" ] &&
10388                 do_facet ost1 rm -f ${ost_file_prefix}\*
10389 }
10390
10391 test_77c() {
10392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10393         $GSS && skip_env "could not run with gss"
10394         remote_ost_nodsh && skip "remote OST with nodsh"
10395
10396         local bad1
10397         local osc_file_prefix
10398         local osc_file
10399         local check_ost=false
10400         local ost_file_prefix
10401         local ost_file
10402         local orig_cksum
10403         local dump_cksum
10404         local fid
10405
10406         # ensure corruption will occur on first OSS/OST
10407         $LFS setstripe -i 0 $DIR/$tfile
10408
10409         [ ! -f $F77_TMP ] && setup_f77
10410         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10411                 error "dd write error: $?"
10412         fid=$($LFS path2fid $DIR/$tfile)
10413
10414         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10415         then
10416                 check_ost=true
10417                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10418                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10419         else
10420                 echo "OSS do not support bulk pages dump upon error"
10421         fi
10422
10423         osc_file_prefix=$($LCTL get_param -n debug_path)
10424         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10425
10426         trap cleanup_77c EXIT
10427
10428         set_checksums 1
10429         # enable bulk pages dump upon error on Client
10430         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10431         # enable bulk pages dump upon error on OSS
10432         $check_ost &&
10433                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10434
10435         # flush Client cache to allow next read to reach OSS
10436         cancel_lru_locks osc
10437
10438         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10439         $LCTL set_param fail_loc=0x80000408
10440         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10441         $LCTL set_param fail_loc=0
10442
10443         rm -f $DIR/$tfile
10444
10445         # check cksum dump on Client
10446         osc_file=$(ls ${osc_file_prefix}*)
10447         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10448         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10449         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10450         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10451         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10452                      cksum)
10453         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10454         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10455                 error "dump content does not match on Client"
10456
10457         $check_ost || skip "No need to check cksum dump on OSS"
10458
10459         # check cksum dump on OSS
10460         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10461         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10462         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10463         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10464         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10465                 error "dump content does not match on OSS"
10466
10467         cleanup_77c
10468 }
10469 run_test 77c "checksum error on client read with debug"
10470
10471 test_77d() { # bug 10889
10472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10473         $GSS && skip_env "could not run with gss"
10474
10475         stack_trap "rm -f $DIR/$tfile"
10476         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10477         $LCTL set_param fail_loc=0x80000409
10478         set_checksums 1
10479         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10480                 error "direct write: rc=$?"
10481         $LCTL set_param fail_loc=0
10482         set_checksums 0
10483
10484         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10485         $LCTL set_param fail_loc=0x80000408
10486         set_checksums 1
10487         cancel_lru_locks osc
10488         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10489                 error "direct read: rc=$?"
10490         $LCTL set_param fail_loc=0
10491         set_checksums 0
10492 }
10493 run_test 77d "checksum error on OST direct write, read"
10494
10495 test_77f() { # bug 10889
10496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10497         $GSS && skip_env "could not run with gss"
10498
10499         set_checksums 1
10500         stack_trap "rm -f $DIR/$tfile"
10501         for algo in $CKSUM_TYPES; do
10502                 cancel_lru_locks osc
10503                 set_checksum_type $algo
10504                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10505                 $LCTL set_param fail_loc=0x409
10506                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10507                         error "direct write succeeded"
10508                 $LCTL set_param fail_loc=0
10509         done
10510         set_checksum_type $ORIG_CSUM_TYPE
10511         set_checksums 0
10512 }
10513 run_test 77f "repeat checksum error on write (expect error)"
10514
10515 test_77g() { # bug 10889
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517         $GSS && skip_env "could not run with gss"
10518         remote_ost_nodsh && skip "remote OST with nodsh"
10519
10520         [ ! -f $F77_TMP ] && setup_f77
10521
10522         local file=$DIR/$tfile
10523         stack_trap "rm -f $file" EXIT
10524
10525         $LFS setstripe -c 1 -i 0 $file
10526         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10527         do_facet ost1 lctl set_param fail_loc=0x8000021a
10528         set_checksums 1
10529         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10530                 error "write error: rc=$?"
10531         do_facet ost1 lctl set_param fail_loc=0
10532         set_checksums 0
10533
10534         cancel_lru_locks osc
10535         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10536         do_facet ost1 lctl set_param fail_loc=0x8000021b
10537         set_checksums 1
10538         cmp $F77_TMP $file || error "file compare failed"
10539         do_facet ost1 lctl set_param fail_loc=0
10540         set_checksums 0
10541 }
10542 run_test 77g "checksum error on OST write, read"
10543
10544 test_77k() { # LU-10906
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546         $GSS && skip_env "could not run with gss"
10547
10548         local cksum_param="osc.$FSNAME*.checksums"
10549         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10550         local checksum
10551         local i
10552
10553         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10554         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10555         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10556
10557         for i in 0 1; do
10558                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10559                         error "failed to set checksum=$i on MGS"
10560                 wait_update $HOSTNAME "$get_checksum" $i
10561                 #remount
10562                 echo "remount client, checksum should be $i"
10563                 remount_client $MOUNT || error "failed to remount client"
10564                 checksum=$(eval $get_checksum)
10565                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10566         done
10567         # remove persistent param to avoid races with checksum mountopt below
10568         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10569                 error "failed to delete checksum on MGS"
10570
10571         for opt in "checksum" "nochecksum"; do
10572                 #remount with mount option
10573                 echo "remount client with option $opt, checksum should be $i"
10574                 umount_client $MOUNT || error "failed to umount client"
10575                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10576                         error "failed to mount client with option '$opt'"
10577                 checksum=$(eval $get_checksum)
10578                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10579                 i=$((i - 1))
10580         done
10581
10582         remount_client $MOUNT || error "failed to remount client"
10583 }
10584 run_test 77k "enable/disable checksum correctly"
10585
10586 test_77l() {
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588         $GSS && skip_env "could not run with gss"
10589
10590         set_checksums 1
10591         stack_trap "set_checksums $ORIG_CSUM" EXIT
10592         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10593
10594         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10595
10596         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10597         for algo in $CKSUM_TYPES; do
10598                 set_checksum_type $algo || error "fail to set checksum type $algo"
10599                 osc_algo=$(get_osc_checksum_type OST0000)
10600                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10601
10602                 # no locks, no reqs to let the connection idle
10603                 cancel_lru_locks osc
10604                 lru_resize_disable osc
10605                 wait_osc_import_state client ost1 IDLE
10606
10607                 # ensure ost1 is connected
10608                 stat $DIR/$tfile >/dev/null || error "can't stat"
10609                 wait_osc_import_state client ost1 FULL
10610
10611                 osc_algo=$(get_osc_checksum_type OST0000)
10612                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10613         done
10614         return 0
10615 }
10616 run_test 77l "preferred checksum type is remembered after reconnected"
10617
10618 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10619 rm -f $F77_TMP
10620 unset F77_TMP
10621
10622 test_77m() {
10623         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10624                 skip "Need at least version 2.14.52"
10625         local param=checksum_speed
10626
10627         $LCTL get_param $param || error "reading $param failed"
10628
10629         csum_speeds=$($LCTL get_param -n $param)
10630
10631         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10632                 error "known checksum types are missing"
10633 }
10634 run_test 77m "Verify checksum_speed is correctly read"
10635
10636 check_filefrag_77n() {
10637         local nr_ext=0
10638         local starts=()
10639         local ends=()
10640
10641         while read extidx a b start end rest; do
10642                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10643                         nr_ext=$(( $nr_ext + 1 ))
10644                         starts+=( ${start%..} )
10645                         ends+=( ${end%:} )
10646                 fi
10647         done < <( filefrag -sv $1 )
10648
10649         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10650         return 1
10651 }
10652
10653 test_77n() {
10654         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10655
10656         touch $DIR/$tfile
10657         $TRUNCATE $DIR/$tfile 0
10658         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10659         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10660         check_filefrag_77n $DIR/$tfile ||
10661                 skip "$tfile blocks not contiguous around hole"
10662
10663         set_checksums 1
10664         stack_trap "set_checksums $ORIG_CSUM" EXIT
10665         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10666         stack_trap "rm -f $DIR/$tfile"
10667
10668         for algo in $CKSUM_TYPES; do
10669                 if [[ "$algo" =~ ^t10 ]]; then
10670                         set_checksum_type $algo ||
10671                                 error "fail to set checksum type $algo"
10672                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10673                                 error "fail to read $tfile with $algo"
10674                 fi
10675         done
10676         rm -f $DIR/$tfile
10677         return 0
10678 }
10679 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10680
10681 test_77o() {
10682         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10683                 skip "Need MDS version at least 2.14.55"
10684         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10685                 skip "Need OST version at least 2.14.55"
10686         local ofd=obdfilter
10687         local mdt=mdt
10688
10689         # print OST checksum_type
10690         echo "$ofd.$FSNAME-*.checksum_type:"
10691         do_nodes $(comma_list $(osts_nodes)) \
10692                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10693
10694         # print MDT checksum_type
10695         echo "$mdt.$FSNAME-*.checksum_type:"
10696         do_nodes $(comma_list $(mdts_nodes)) \
10697                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10698
10699         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10700                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10701
10702         (( $o_count == $OSTCOUNT )) ||
10703                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10704
10705         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10706                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10707
10708         (( $m_count == $MDSCOUNT )) ||
10709                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10710 }
10711 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10712
10713 cleanup_test_78() {
10714         trap 0
10715         rm -f $DIR/$tfile
10716 }
10717
10718 test_78() { # bug 10901
10719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10720         remote_ost || skip_env "local OST"
10721
10722         NSEQ=5
10723         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10724         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10725         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10726         echo "MemTotal: $MEMTOTAL"
10727
10728         # reserve 256MB of memory for the kernel and other running processes,
10729         # and then take 1/2 of the remaining memory for the read/write buffers.
10730         if [ $MEMTOTAL -gt 512 ] ;then
10731                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10732         else
10733                 # for those poor memory-starved high-end clusters...
10734                 MEMTOTAL=$((MEMTOTAL / 2))
10735         fi
10736         echo "Mem to use for directio: $MEMTOTAL"
10737
10738         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10739         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10740         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10741         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10742                 head -n1)
10743         echo "Smallest OST: $SMALLESTOST"
10744         [[ $SMALLESTOST -lt 10240 ]] &&
10745                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10746
10747         trap cleanup_test_78 EXIT
10748
10749         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10750                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10751
10752         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10753         echo "File size: $F78SIZE"
10754         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10755         for i in $(seq 1 $NSEQ); do
10756                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10757                 echo directIO rdwr round $i of $NSEQ
10758                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10759         done
10760
10761         cleanup_test_78
10762 }
10763 run_test 78 "handle large O_DIRECT writes correctly ============"
10764
10765 test_79() { # bug 12743
10766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10767
10768         wait_delete_completed
10769
10770         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10771         BKFREE=$(calc_osc_kbytes kbytesfree)
10772         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10773
10774         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10775         DFTOTAL=`echo $STRING | cut -d, -f1`
10776         DFUSED=`echo $STRING  | cut -d, -f2`
10777         DFAVAIL=`echo $STRING | cut -d, -f3`
10778         DFFREE=$(($DFTOTAL - $DFUSED))
10779
10780         ALLOWANCE=$((64 * $OSTCOUNT))
10781
10782         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10783            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10784                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10785         fi
10786         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10787            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10788                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10789         fi
10790         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10791            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10792                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10793         fi
10794 }
10795 run_test 79 "df report consistency check ======================="
10796
10797 test_80() { # bug 10718
10798         remote_ost_nodsh && skip "remote OST with nodsh"
10799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10800
10801         # relax strong synchronous semantics for slow backends like ZFS
10802         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10803                 local soc="obdfilter.*.sync_lock_cancel"
10804                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10805
10806                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10807                 if [ -z "$save" ]; then
10808                         soc="obdfilter.*.sync_on_lock_cancel"
10809                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10810                 fi
10811
10812                 if [ "$save" != "never" ]; then
10813                         local hosts=$(comma_list $(osts_nodes))
10814
10815                         do_nodes $hosts $LCTL set_param $soc=never
10816                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10817                 fi
10818         fi
10819
10820         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10821         sync; sleep 1; sync
10822         local before=$(date +%s)
10823         cancel_lru_locks osc
10824         local after=$(date +%s)
10825         local diff=$((after - before))
10826         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10827
10828         rm -f $DIR/$tfile
10829 }
10830 run_test 80 "Page eviction is equally fast at high offsets too"
10831
10832 test_81a() { # LU-456
10833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10834         remote_ost_nodsh && skip "remote OST with nodsh"
10835
10836         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10837         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10838         do_facet ost1 lctl set_param fail_loc=0x80000228
10839
10840         # write should trigger a retry and success
10841         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10842         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10843         RC=$?
10844         if [ $RC -ne 0 ] ; then
10845                 error "write should success, but failed for $RC"
10846         fi
10847 }
10848 run_test 81a "OST should retry write when get -ENOSPC ==============="
10849
10850 test_81b() { # LU-456
10851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10852         remote_ost_nodsh && skip "remote OST with nodsh"
10853
10854         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10855         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10856         do_facet ost1 lctl set_param fail_loc=0x228
10857
10858         # write should retry several times and return -ENOSPC finally
10859         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10860         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10861         RC=$?
10862         ENOSPC=28
10863         if [ $RC -ne $ENOSPC ] ; then
10864                 error "dd should fail for -ENOSPC, but succeed."
10865         fi
10866 }
10867 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10868
10869 test_99() {
10870         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10871
10872         test_mkdir $DIR/$tdir.cvsroot
10873         chown $RUNAS_ID $DIR/$tdir.cvsroot
10874
10875         cd $TMP
10876         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10877
10878         cd /etc/init.d
10879         # some versions of cvs import exit(1) when asked to import links or
10880         # files they can't read.  ignore those files.
10881         local toignore=$(find . -type l -printf '-I %f\n' -o \
10882                          ! -perm /4 -printf '-I %f\n')
10883         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10884                 $tdir.reposname vtag rtag
10885
10886         cd $DIR
10887         test_mkdir $DIR/$tdir.reposname
10888         chown $RUNAS_ID $DIR/$tdir.reposname
10889         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10890
10891         cd $DIR/$tdir.reposname
10892         $RUNAS touch foo99
10893         $RUNAS cvs add -m 'addmsg' foo99
10894         $RUNAS cvs update
10895         $RUNAS cvs commit -m 'nomsg' foo99
10896         rm -fr $DIR/$tdir.cvsroot
10897 }
10898 run_test 99 "cvs strange file/directory operations"
10899
10900 test_100() {
10901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10902         [[ "$NETTYPE" =~ tcp ]] ||
10903                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10904         remote_ost_nodsh && skip "remote OST with nodsh"
10905         remote_mds_nodsh && skip "remote MDS with nodsh"
10906         remote_servers ||
10907                 skip "useless for local single node setup"
10908
10909         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10910                 [ "$PROT" != "tcp" ] && continue
10911                 RPORT=$(echo $REMOTE | cut -d: -f2)
10912                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10913
10914                 rc=0
10915                 LPORT=`echo $LOCAL | cut -d: -f2`
10916                 if [ $LPORT -ge 1024 ]; then
10917                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10918                         netstat -tna
10919                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10920                 fi
10921         done
10922         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10923 }
10924 run_test 100 "check local port using privileged port ==========="
10925
10926 function get_named_value()
10927 {
10928     local tag=$1
10929
10930     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10931 }
10932
10933 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10934                    awk '/^max_cached_mb/ { print $2 }')
10935
10936 cleanup_101a() {
10937         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10938         trap 0
10939 }
10940
10941 test_101a() {
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943
10944         local s
10945         local discard
10946         local nreads=10000
10947         local cache_limit=32
10948
10949         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10950         trap cleanup_101a EXIT
10951         $LCTL set_param -n llite.*.read_ahead_stats=0
10952         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10953
10954         #
10955         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10956         #
10957         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10958         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10959
10960         discard=0
10961         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10962                    get_named_value 'read.but.discarded'); do
10963                         discard=$(($discard + $s))
10964         done
10965         cleanup_101a
10966
10967         $LCTL get_param osc.*-osc*.rpc_stats
10968         $LCTL get_param llite.*.read_ahead_stats
10969
10970         # Discard is generally zero, but sometimes a few random reads line up
10971         # and trigger larger readahead, which is wasted & leads to discards.
10972         if [[ $(($discard)) -gt $nreads ]]; then
10973                 error "too many ($discard) discarded pages"
10974         fi
10975         rm -f $DIR/$tfile || true
10976 }
10977 run_test 101a "check read-ahead for random reads"
10978
10979 setup_test101bc() {
10980         test_mkdir $DIR/$tdir
10981         local ssize=$1
10982         local FILE_LENGTH=$2
10983         STRIPE_OFFSET=0
10984
10985         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10986
10987         local list=$(comma_list $(osts_nodes))
10988         set_osd_param $list '' read_cache_enable 0
10989         set_osd_param $list '' writethrough_cache_enable 0
10990
10991         trap cleanup_test101bc EXIT
10992         # prepare the read-ahead file
10993         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10994
10995         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10996                                 count=$FILE_SIZE_MB 2> /dev/null
10997
10998 }
10999
11000 cleanup_test101bc() {
11001         trap 0
11002         rm -rf $DIR/$tdir
11003         rm -f $DIR/$tfile
11004
11005         local list=$(comma_list $(osts_nodes))
11006         set_osd_param $list '' read_cache_enable 1
11007         set_osd_param $list '' writethrough_cache_enable 1
11008 }
11009
11010 calc_total() {
11011         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11012 }
11013
11014 ra_check_101() {
11015         local read_size=$1
11016         local stripe_size=$2
11017         local stride_length=$((stripe_size / read_size))
11018         local stride_width=$((stride_length * OSTCOUNT))
11019         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11020                                 (stride_width - stride_length) ))
11021         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11022                   get_named_value 'read.but.discarded' | calc_total)
11023
11024         if [[ $discard -gt $discard_limit ]]; then
11025                 $LCTL get_param llite.*.read_ahead_stats
11026                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11027         else
11028                 echo "Read-ahead success for size ${read_size}"
11029         fi
11030 }
11031
11032 test_101b() {
11033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11035
11036         local STRIPE_SIZE=1048576
11037         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11038
11039         if [ $SLOW == "yes" ]; then
11040                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11041         else
11042                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11043         fi
11044
11045         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11046
11047         # prepare the read-ahead file
11048         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11049         cancel_lru_locks osc
11050         for BIDX in 2 4 8 16 32 64 128 256
11051         do
11052                 local BSIZE=$((BIDX*4096))
11053                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11054                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11055                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11056                 $LCTL set_param -n llite.*.read_ahead_stats=0
11057                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11058                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11059                 cancel_lru_locks osc
11060                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11061         done
11062         cleanup_test101bc
11063         true
11064 }
11065 run_test 101b "check stride-io mode read-ahead ================="
11066
11067 test_101c() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069
11070         local STRIPE_SIZE=1048576
11071         local FILE_LENGTH=$((STRIPE_SIZE*100))
11072         local nreads=10000
11073         local rsize=65536
11074         local osc_rpc_stats
11075
11076         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11077
11078         cancel_lru_locks osc
11079         $LCTL set_param osc.*.rpc_stats=0
11080         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11081         $LCTL get_param osc.*.rpc_stats
11082         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11083                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11084                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11085                 local size
11086
11087                 if [ $lines -le 20 ]; then
11088                         echo "continue debug"
11089                         continue
11090                 fi
11091                 for size in 1 2 4 8; do
11092                         local rpc=$(echo "$stats" |
11093                                     awk '($1 == "'$size':") {print $2; exit; }')
11094                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11095                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11096                 done
11097                 echo "$osc_rpc_stats check passed!"
11098         done
11099         cleanup_test101bc
11100         true
11101 }
11102 run_test 101c "check stripe_size aligned read-ahead"
11103
11104 test_101d() {
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106
11107         local file=$DIR/$tfile
11108         local sz_MB=${FILESIZE_101d:-80}
11109         local ra_MB=${READAHEAD_MB:-40}
11110
11111         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11112         [ $free_MB -lt $sz_MB ] &&
11113                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11114
11115         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11116         $LFS setstripe -c -1 $file || error "setstripe failed"
11117
11118         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11119         echo Cancel LRU locks on lustre client to flush the client cache
11120         cancel_lru_locks osc
11121
11122         echo Disable read-ahead
11123         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11124         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11125         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11126         $LCTL get_param -n llite.*.max_read_ahead_mb
11127
11128         echo "Reading the test file $file with read-ahead disabled"
11129         local sz_KB=$((sz_MB * 1024 / 4))
11130         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11131         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11132         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11133                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11134
11135         echo "Cancel LRU locks on lustre client to flush the client cache"
11136         cancel_lru_locks osc
11137         echo Enable read-ahead with ${ra_MB}MB
11138         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11139
11140         echo "Reading the test file $file with read-ahead enabled"
11141         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11142                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11143
11144         echo "read-ahead disabled time read $raOFF"
11145         echo "read-ahead enabled time read $raON"
11146
11147         rm -f $file
11148         wait_delete_completed
11149
11150         # use awk for this check instead of bash because it handles decimals
11151         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11152                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11153 }
11154 run_test 101d "file read with and without read-ahead enabled"
11155
11156 test_101e() {
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158
11159         local file=$DIR/$tfile
11160         local size_KB=500  #KB
11161         local count=100
11162         local bsize=1024
11163
11164         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11165         local need_KB=$((count * size_KB))
11166         [[ $free_KB -le $need_KB ]] &&
11167                 skip_env "Need free space $need_KB, have $free_KB"
11168
11169         echo "Creating $count ${size_KB}K test files"
11170         for ((i = 0; i < $count; i++)); do
11171                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11172         done
11173
11174         echo "Cancel LRU locks on lustre client to flush the client cache"
11175         cancel_lru_locks $OSC
11176
11177         echo "Reset readahead stats"
11178         $LCTL set_param -n llite.*.read_ahead_stats=0
11179
11180         for ((i = 0; i < $count; i++)); do
11181                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11182         done
11183
11184         $LCTL get_param llite.*.max_cached_mb
11185         $LCTL get_param llite.*.read_ahead_stats
11186         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11187                      get_named_value 'misses' | calc_total)
11188
11189         for ((i = 0; i < $count; i++)); do
11190                 rm -rf $file.$i 2>/dev/null
11191         done
11192
11193         #10000 means 20% reads are missing in readahead
11194         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11195 }
11196 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11197
11198 test_101f() {
11199         which iozone || skip_env "no iozone installed"
11200
11201         local old_debug=$($LCTL get_param debug)
11202         old_debug=${old_debug#*=}
11203         $LCTL set_param debug="reada mmap"
11204
11205         # create a test file
11206         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11207
11208         echo Cancel LRU locks on lustre client to flush the client cache
11209         cancel_lru_locks osc
11210
11211         echo Reset readahead stats
11212         $LCTL set_param -n llite.*.read_ahead_stats=0
11213
11214         echo mmap read the file with small block size
11215         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11216                 > /dev/null 2>&1
11217
11218         echo checking missing pages
11219         $LCTL get_param llite.*.read_ahead_stats
11220         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11221                         get_named_value 'misses' | calc_total)
11222
11223         $LCTL set_param debug="$old_debug"
11224         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11225         rm -f $DIR/$tfile
11226 }
11227 run_test 101f "check mmap read performance"
11228
11229 test_101g_brw_size_test() {
11230         local mb=$1
11231         local pages=$((mb * 1048576 / PAGE_SIZE))
11232         local file=$DIR/$tfile
11233
11234         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11235                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11236         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11237                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11238                         return 2
11239         done
11240
11241         stack_trap "rm -f $file" EXIT
11242         $LCTL set_param -n osc.*.rpc_stats=0
11243
11244         # 10 RPCs should be enough for the test
11245         local count=10
11246         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11247                 { error "dd write ${mb} MB blocks failed"; return 3; }
11248         cancel_lru_locks osc
11249         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11250                 { error "dd write ${mb} MB blocks failed"; return 4; }
11251
11252         # calculate number of full-sized read and write RPCs
11253         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11254                 sed -n '/pages per rpc/,/^$/p' |
11255                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11256                 END { print reads,writes }'))
11257         # allow one extra full-sized read RPC for async readahead
11258         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11259                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11260         [[ ${rpcs[1]} == $count ]] ||
11261                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11262 }
11263
11264 test_101g() {
11265         remote_ost_nodsh && skip "remote OST with nodsh"
11266
11267         local rpcs
11268         local osts=$(get_facets OST)
11269         local list=$(comma_list $(osts_nodes))
11270         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11271         local brw_size="obdfilter.*.brw_size"
11272
11273         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11274
11275         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11276
11277         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11278                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11279                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11280            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11281                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11282                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11283
11284                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11285                         suffix="M"
11286
11287                 if [[ $orig_mb -lt 16 ]]; then
11288                         save_lustre_params $osts "$brw_size" > $p
11289                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11290                                 error "set 16MB RPC size failed"
11291
11292                         echo "remount client to enable new RPC size"
11293                         remount_client $MOUNT || error "remount_client failed"
11294                 fi
11295
11296                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11297                 # should be able to set brw_size=12, but no rpc_stats for that
11298                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11299         fi
11300
11301         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11302
11303         if [[ $orig_mb -lt 16 ]]; then
11304                 restore_lustre_params < $p
11305                 remount_client $MOUNT || error "remount_client restore failed"
11306         fi
11307
11308         rm -f $p $DIR/$tfile
11309 }
11310 run_test 101g "Big bulk(4/16 MiB) readahead"
11311
11312 test_101h() {
11313         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11314
11315         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11316                 error "dd 70M file failed"
11317         echo Cancel LRU locks on lustre client to flush the client cache
11318         cancel_lru_locks osc
11319
11320         echo "Reset readahead stats"
11321         $LCTL set_param -n llite.*.read_ahead_stats 0
11322
11323         echo "Read 10M of data but cross 64M bundary"
11324         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11325         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11326                      get_named_value 'misses' | calc_total)
11327         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11328         rm -f $p $DIR/$tfile
11329 }
11330 run_test 101h "Readahead should cover current read window"
11331
11332 test_101i() {
11333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11334                 error "dd 10M file failed"
11335
11336         local max_per_file_mb=$($LCTL get_param -n \
11337                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11338         cancel_lru_locks osc
11339         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11340         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11341                 error "set max_read_ahead_per_file_mb to 1 failed"
11342
11343         echo "Reset readahead stats"
11344         $LCTL set_param llite.*.read_ahead_stats=0
11345
11346         dd if=$DIR/$tfile of=/dev/null bs=2M
11347
11348         $LCTL get_param llite.*.read_ahead_stats
11349         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11350                      awk '/misses/ { print $2 }')
11351         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11352         rm -f $DIR/$tfile
11353 }
11354 run_test 101i "allow current readahead to exceed reservation"
11355
11356 test_101j() {
11357         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11358                 error "setstripe $DIR/$tfile failed"
11359         local file_size=$((1048576 * 16))
11360         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11361         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11362
11363         echo Disable read-ahead
11364         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11365
11366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11367         for blk in $PAGE_SIZE 1048576 $file_size; do
11368                 cancel_lru_locks osc
11369                 echo "Reset readahead stats"
11370                 $LCTL set_param -n llite.*.read_ahead_stats=0
11371                 local count=$(($file_size / $blk))
11372                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11373                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11374                              get_named_value 'failed.to.fast.read' | calc_total)
11375                 $LCTL get_param -n llite.*.read_ahead_stats
11376                 [ $miss -eq $count ] || error "expected $count got $miss"
11377         done
11378
11379         rm -f $p $DIR/$tfile
11380 }
11381 run_test 101j "A complete read block should be submitted when no RA"
11382
11383 test_101k()
11384 {
11385         local file=$DIR/$tfile
11386
11387         check_set_fallocate_or_skip
11388
11389         $LCTL set_param -n llite.*.read_ahead_stats=0
11390         fallocate -l 16K $file || error "failed to fallocate $file"
11391         cancel_lru_locks osc
11392         $MULTIOP $file or1048576c
11393         $LCTL get_param llite.*.read_ahead_stats
11394 }
11395 run_test 101k "read ahead for small file"
11396
11397 setup_test102() {
11398         test_mkdir $DIR/$tdir
11399         chown $RUNAS_ID $DIR/$tdir
11400         STRIPE_SIZE=65536
11401         STRIPE_OFFSET=1
11402         STRIPE_COUNT=$OSTCOUNT
11403         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11404
11405         trap cleanup_test102 EXIT
11406         cd $DIR
11407         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11408         cd $DIR/$tdir
11409         for num in 1 2 3 4; do
11410                 for count in $(seq 1 $STRIPE_COUNT); do
11411                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11412                                 local size=`expr $STRIPE_SIZE \* $num`
11413                                 local file=file"$num-$idx-$count"
11414                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11415                         done
11416                 done
11417         done
11418
11419         cd $DIR
11420         $1 tar cf $TMP/f102.tar $tdir --xattrs
11421 }
11422
11423 cleanup_test102() {
11424         trap 0
11425         rm -f $TMP/f102.tar
11426         rm -rf $DIR/d0.sanity/d102
11427 }
11428
11429 test_102a() {
11430         [ "$UID" != 0 ] && skip "must run as root"
11431         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11432                 skip_env "must have user_xattr"
11433
11434         [ -z "$(which setfattr 2>/dev/null)" ] &&
11435                 skip_env "could not find setfattr"
11436
11437         local testfile=$DIR/$tfile
11438
11439         touch $testfile
11440         echo "set/get xattr..."
11441         setfattr -n trusted.name1 -v value1 $testfile ||
11442                 error "setfattr -n trusted.name1=value1 $testfile failed"
11443         getfattr -n trusted.name1 $testfile 2> /dev/null |
11444           grep "trusted.name1=.value1" ||
11445                 error "$testfile missing trusted.name1=value1"
11446
11447         setfattr -n user.author1 -v author1 $testfile ||
11448                 error "setfattr -n user.author1=author1 $testfile failed"
11449         getfattr -n user.author1 $testfile 2> /dev/null |
11450           grep "user.author1=.author1" ||
11451                 error "$testfile missing trusted.author1=author1"
11452
11453         echo "listxattr..."
11454         setfattr -n trusted.name2 -v value2 $testfile ||
11455                 error "$testfile unable to set trusted.name2"
11456         setfattr -n trusted.name3 -v value3 $testfile ||
11457                 error "$testfile unable to set trusted.name3"
11458         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11459             grep "trusted.name" | wc -l) -eq 3 ] ||
11460                 error "$testfile missing 3 trusted.name xattrs"
11461
11462         setfattr -n user.author2 -v author2 $testfile ||
11463                 error "$testfile unable to set user.author2"
11464         setfattr -n user.author3 -v author3 $testfile ||
11465                 error "$testfile unable to set user.author3"
11466         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11467             grep "user.author" | wc -l) -eq 3 ] ||
11468                 error "$testfile missing 3 user.author xattrs"
11469
11470         echo "remove xattr..."
11471         setfattr -x trusted.name1 $testfile ||
11472                 error "$testfile error deleting trusted.name1"
11473         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11474                 error "$testfile did not delete trusted.name1 xattr"
11475
11476         setfattr -x user.author1 $testfile ||
11477                 error "$testfile error deleting user.author1"
11478         echo "set lustre special xattr ..."
11479         $LFS setstripe -c1 $testfile
11480         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11481                 awk -F "=" '/trusted.lov/ { print $2 }' )
11482         setfattr -n "trusted.lov" -v $lovea $testfile ||
11483                 error "$testfile doesn't ignore setting trusted.lov again"
11484         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11485                 error "$testfile allow setting invalid trusted.lov"
11486         rm -f $testfile
11487 }
11488 run_test 102a "user xattr test =================================="
11489
11490 check_102b_layout() {
11491         local layout="$*"
11492         local testfile=$DIR/$tfile
11493
11494         echo "test layout '$layout'"
11495         $LFS setstripe $layout $testfile || error "setstripe failed"
11496         $LFS getstripe -y $testfile
11497
11498         echo "get/set/list trusted.lov xattr ..." # b=10930
11499         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11500         [[ "$value" =~ "trusted.lov" ]] ||
11501                 error "can't get trusted.lov from $testfile"
11502         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11503                 error "getstripe failed"
11504
11505         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11506
11507         value=$(cut -d= -f2 <<<$value)
11508         # LU-13168: truncated xattr should fail if short lov_user_md header
11509         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11510                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11511         for len in $lens; do
11512                 echo "setfattr $len $testfile.2"
11513                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11514                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11515         done
11516         local stripe_size=$($LFS getstripe -S $testfile.2)
11517         local stripe_count=$($LFS getstripe -c $testfile.2)
11518         [[ $stripe_size -eq 65536 ]] ||
11519                 error "stripe size $stripe_size != 65536"
11520         [[ $stripe_count -eq $stripe_count_orig ]] ||
11521                 error "stripe count $stripe_count != $stripe_count_orig"
11522         rm $testfile $testfile.2
11523 }
11524
11525 test_102b() {
11526         [ -z "$(which setfattr 2>/dev/null)" ] &&
11527                 skip_env "could not find setfattr"
11528         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11529
11530         # check plain layout
11531         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11532
11533         # and also check composite layout
11534         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11535
11536 }
11537 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11538
11539 test_102c() {
11540         [ -z "$(which setfattr 2>/dev/null)" ] &&
11541                 skip_env "could not find setfattr"
11542         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11543
11544         # b10930: get/set/list lustre.lov xattr
11545         echo "get/set/list lustre.lov xattr ..."
11546         test_mkdir $DIR/$tdir
11547         chown $RUNAS_ID $DIR/$tdir
11548         local testfile=$DIR/$tdir/$tfile
11549         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11550                 error "setstripe failed"
11551         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11552                 error "getstripe failed"
11553         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11554         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11555
11556         local testfile2=${testfile}2
11557         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11558                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11559
11560         $RUNAS $MCREATE $testfile2
11561         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11562         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11563         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11564         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11565         [ $stripe_count -eq $STRIPECOUNT ] ||
11566                 error "stripe count $stripe_count != $STRIPECOUNT"
11567 }
11568 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11569
11570 compare_stripe_info1() {
11571         local stripe_index_all_zero=true
11572
11573         for num in 1 2 3 4; do
11574                 for count in $(seq 1 $STRIPE_COUNT); do
11575                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11576                                 local size=$((STRIPE_SIZE * num))
11577                                 local file=file"$num-$offset-$count"
11578                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11579                                 [[ $stripe_size -ne $size ]] &&
11580                                     error "$file: size $stripe_size != $size"
11581                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11582                                 # allow fewer stripes to be created, ORI-601
11583                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11584                                     error "$file: count $stripe_count != $count"
11585                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11586                                 [[ $stripe_index -ne 0 ]] &&
11587                                         stripe_index_all_zero=false
11588                         done
11589                 done
11590         done
11591         $stripe_index_all_zero &&
11592                 error "all files are being extracted starting from OST index 0"
11593         return 0
11594 }
11595
11596 have_xattrs_include() {
11597         tar --help | grep -q xattrs-include &&
11598                 echo --xattrs-include="lustre.*"
11599 }
11600
11601 test_102d() {
11602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11603         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11604
11605         XINC=$(have_xattrs_include)
11606         setup_test102
11607         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11608         cd $DIR/$tdir/$tdir
11609         compare_stripe_info1
11610 }
11611 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11612
11613 test_102f() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11616
11617         XINC=$(have_xattrs_include)
11618         setup_test102
11619         test_mkdir $DIR/$tdir.restore
11620         cd $DIR
11621         tar cf - --xattrs $tdir | tar xf - \
11622                 -C $DIR/$tdir.restore --xattrs $XINC
11623         cd $DIR/$tdir.restore/$tdir
11624         compare_stripe_info1
11625 }
11626 run_test 102f "tar copy files, not keep osts"
11627
11628 grow_xattr() {
11629         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11630                 skip "must have user_xattr"
11631         [ -z "$(which setfattr 2>/dev/null)" ] &&
11632                 skip_env "could not find setfattr"
11633         [ -z "$(which getfattr 2>/dev/null)" ] &&
11634                 skip_env "could not find getfattr"
11635
11636         local xsize=${1:-1024}  # in bytes
11637         local file=$DIR/$tfile
11638         local value="$(generate_string $xsize)"
11639         local xbig=trusted.big
11640         local toobig=$2
11641
11642         touch $file
11643         log "save $xbig on $file"
11644         if [ -z "$toobig" ]
11645         then
11646                 setfattr -n $xbig -v $value $file ||
11647                         error "saving $xbig on $file failed"
11648         else
11649                 setfattr -n $xbig -v $value $file &&
11650                         error "saving $xbig on $file succeeded"
11651                 return 0
11652         fi
11653
11654         local orig=$(get_xattr_value $xbig $file)
11655         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11656
11657         local xsml=trusted.sml
11658         log "save $xsml on $file"
11659         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11660
11661         local new=$(get_xattr_value $xbig $file)
11662         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11663
11664         log "grow $xsml on $file"
11665         setfattr -n $xsml -v "$value" $file ||
11666                 error "growing $xsml on $file failed"
11667
11668         new=$(get_xattr_value $xbig $file)
11669         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11670         log "$xbig still valid after growing $xsml"
11671
11672         rm -f $file
11673 }
11674
11675 test_102h() { # bug 15777
11676         grow_xattr 1024
11677 }
11678 run_test 102h "grow xattr from inside inode to external block"
11679
11680 test_102ha() {
11681         large_xattr_enabled || skip_env "ea_inode feature disabled"
11682
11683         echo "setting xattr of max xattr size: $(max_xattr_size)"
11684         grow_xattr $(max_xattr_size)
11685
11686         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11687         echo "This should fail:"
11688         grow_xattr $(($(max_xattr_size) + 10)) 1
11689 }
11690 run_test 102ha "grow xattr from inside inode to external inode"
11691
11692 test_102i() { # bug 17038
11693         [ -z "$(which getfattr 2>/dev/null)" ] &&
11694                 skip "could not find getfattr"
11695
11696         touch $DIR/$tfile
11697         ln -s $DIR/$tfile $DIR/${tfile}link
11698         getfattr -n trusted.lov $DIR/$tfile ||
11699                 error "lgetxattr on $DIR/$tfile failed"
11700         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11701                 grep -i "no such attr" ||
11702                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11703         rm -f $DIR/$tfile $DIR/${tfile}link
11704 }
11705 run_test 102i "lgetxattr test on symbolic link ============"
11706
11707 test_102j() {
11708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11709         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11710
11711         XINC=$(have_xattrs_include)
11712         setup_test102 "$RUNAS"
11713         chown $RUNAS_ID $DIR/$tdir
11714         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11715         cd $DIR/$tdir/$tdir
11716         compare_stripe_info1 "$RUNAS"
11717 }
11718 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11719
11720 test_102k() {
11721         [ -z "$(which setfattr 2>/dev/null)" ] &&
11722                 skip "could not find setfattr"
11723
11724         touch $DIR/$tfile
11725         # b22187 just check that does not crash for regular file.
11726         setfattr -n trusted.lov $DIR/$tfile
11727         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11728         local test_kdir=$DIR/$tdir
11729         test_mkdir $test_kdir
11730         local default_size=$($LFS getstripe -S $test_kdir)
11731         local default_count=$($LFS getstripe -c $test_kdir)
11732         local default_offset=$($LFS getstripe -i $test_kdir)
11733         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11734                 error 'dir setstripe failed'
11735         setfattr -n trusted.lov $test_kdir
11736         local stripe_size=$($LFS getstripe -S $test_kdir)
11737         local stripe_count=$($LFS getstripe -c $test_kdir)
11738         local stripe_offset=$($LFS getstripe -i $test_kdir)
11739         [ $stripe_size -eq $default_size ] ||
11740                 error "stripe size $stripe_size != $default_size"
11741         [ $stripe_count -eq $default_count ] ||
11742                 error "stripe count $stripe_count != $default_count"
11743         [ $stripe_offset -eq $default_offset ] ||
11744                 error "stripe offset $stripe_offset != $default_offset"
11745         rm -rf $DIR/$tfile $test_kdir
11746 }
11747 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11748
11749 test_102l() {
11750         [ -z "$(which getfattr 2>/dev/null)" ] &&
11751                 skip "could not find getfattr"
11752
11753         # LU-532 trusted. xattr is invisible to non-root
11754         local testfile=$DIR/$tfile
11755
11756         touch $testfile
11757
11758         echo "listxattr as user..."
11759         chown $RUNAS_ID $testfile
11760         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11761             grep -q "trusted" &&
11762                 error "$testfile trusted xattrs are user visible"
11763
11764         return 0;
11765 }
11766 run_test 102l "listxattr size test =================================="
11767
11768 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11769         local path=$DIR/$tfile
11770         touch $path
11771
11772         listxattr_size_check $path || error "listattr_size_check $path failed"
11773 }
11774 run_test 102m "Ensure listxattr fails on small bufffer ========"
11775
11776 cleanup_test102
11777
11778 getxattr() { # getxattr path name
11779         # Return the base64 encoding of the value of xattr name on path.
11780         local path=$1
11781         local name=$2
11782
11783         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11784         # file: $path
11785         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11786         #
11787         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11788
11789         getfattr --absolute-names --encoding=base64 --name=$name $path |
11790                 awk -F= -v name=$name '$1 == name {
11791                         print substr($0, index($0, "=") + 1);
11792         }'
11793 }
11794
11795 test_102n() { # LU-4101 mdt: protect internal xattrs
11796         [ -z "$(which setfattr 2>/dev/null)" ] &&
11797                 skip "could not find setfattr"
11798         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11799         then
11800                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11801         fi
11802
11803         local file0=$DIR/$tfile.0
11804         local file1=$DIR/$tfile.1
11805         local xattr0=$TMP/$tfile.0
11806         local xattr1=$TMP/$tfile.1
11807         local namelist="lov lma lmv link fid version som hsm"
11808         local name
11809         local value
11810
11811         rm -rf $file0 $file1 $xattr0 $xattr1
11812         touch $file0 $file1
11813
11814         # Get 'before' xattrs of $file1.
11815         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11816
11817         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11818                 namelist+=" lfsck_namespace"
11819         for name in $namelist; do
11820                 # Try to copy xattr from $file0 to $file1.
11821                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11822
11823                 setfattr --name=trusted.$name --value="$value" $file1 ||
11824                         error "setxattr 'trusted.$name' failed"
11825
11826                 # Try to set a garbage xattr.
11827                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11828
11829                 if [[ x$name == "xlov" ]]; then
11830                         setfattr --name=trusted.lov --value="$value" $file1 &&
11831                         error "setxattr invalid 'trusted.lov' success"
11832                 else
11833                         setfattr --name=trusted.$name --value="$value" $file1 ||
11834                                 error "setxattr invalid 'trusted.$name' failed"
11835                 fi
11836
11837                 # Try to remove the xattr from $file1. We don't care if this
11838                 # appears to succeed or fail, we just don't want there to be
11839                 # any changes or crashes.
11840                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11841         done
11842
11843         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11844         then
11845                 name="lfsck_ns"
11846                 # Try to copy xattr from $file0 to $file1.
11847                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11848
11849                 setfattr --name=trusted.$name --value="$value" $file1 ||
11850                         error "setxattr 'trusted.$name' failed"
11851
11852                 # Try to set a garbage xattr.
11853                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11854
11855                 setfattr --name=trusted.$name --value="$value" $file1 ||
11856                         error "setxattr 'trusted.$name' failed"
11857
11858                 # Try to remove the xattr from $file1. We don't care if this
11859                 # appears to succeed or fail, we just don't want there to be
11860                 # any changes or crashes.
11861                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11862         fi
11863
11864         # Get 'after' xattrs of file1.
11865         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11866
11867         if ! diff $xattr0 $xattr1; then
11868                 error "before and after xattrs of '$file1' differ"
11869         fi
11870
11871         rm -rf $file0 $file1 $xattr0 $xattr1
11872
11873         return 0
11874 }
11875 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11876
11877 test_102p() { # LU-4703 setxattr did not check ownership
11878         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11879                 skip "MDS needs to be at least 2.5.56"
11880
11881         local testfile=$DIR/$tfile
11882
11883         touch $testfile
11884
11885         echo "setfacl as user..."
11886         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11887         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11888
11889         echo "setfattr as user..."
11890         setfacl -m "u:$RUNAS_ID:---" $testfile
11891         $RUNAS setfattr -x system.posix_acl_access $testfile
11892         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11893 }
11894 run_test 102p "check setxattr(2) correctly fails without permission"
11895
11896 test_102q() {
11897         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11898                 skip "MDS needs to be at least 2.6.92"
11899
11900         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11901 }
11902 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11903
11904 test_102r() {
11905         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11906                 skip "MDS needs to be at least 2.6.93"
11907
11908         touch $DIR/$tfile || error "touch"
11909         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11910         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11911         rm $DIR/$tfile || error "rm"
11912
11913         #normal directory
11914         mkdir -p $DIR/$tdir || error "mkdir"
11915         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11916         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11917         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11918                 error "$testfile error deleting user.author1"
11919         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11920                 grep "user.$(basename $tdir)" &&
11921                 error "$tdir did not delete user.$(basename $tdir)"
11922         rmdir $DIR/$tdir || error "rmdir"
11923
11924         #striped directory
11925         test_mkdir $DIR/$tdir
11926         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11927         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11928         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11929                 error "$testfile error deleting user.author1"
11930         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11931                 grep "user.$(basename $tdir)" &&
11932                 error "$tdir did not delete user.$(basename $tdir)"
11933         rmdir $DIR/$tdir || error "rm striped dir"
11934 }
11935 run_test 102r "set EAs with empty values"
11936
11937 test_102s() {
11938         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11939                 skip "MDS needs to be at least 2.11.52"
11940
11941         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11942
11943         save_lustre_params client "llite.*.xattr_cache" > $save
11944
11945         for cache in 0 1; do
11946                 lctl set_param llite.*.xattr_cache=$cache
11947
11948                 rm -f $DIR/$tfile
11949                 touch $DIR/$tfile || error "touch"
11950                 for prefix in lustre security system trusted user; do
11951                         # Note getxattr() may fail with 'Operation not
11952                         # supported' or 'No such attribute' depending
11953                         # on prefix and cache.
11954                         getfattr -n $prefix.n102s $DIR/$tfile &&
11955                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11956                 done
11957         done
11958
11959         restore_lustre_params < $save
11960 }
11961 run_test 102s "getting nonexistent xattrs should fail"
11962
11963 test_102t() {
11964         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11965                 skip "MDS needs to be at least 2.11.52"
11966
11967         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11968
11969         save_lustre_params client "llite.*.xattr_cache" > $save
11970
11971         for cache in 0 1; do
11972                 lctl set_param llite.*.xattr_cache=$cache
11973
11974                 for buf_size in 0 256; do
11975                         rm -f $DIR/$tfile
11976                         touch $DIR/$tfile || error "touch"
11977                         setfattr -n user.multiop $DIR/$tfile
11978                         $MULTIOP $DIR/$tfile oa$buf_size ||
11979                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11980                 done
11981         done
11982
11983         restore_lustre_params < $save
11984 }
11985 run_test 102t "zero length xattr values handled correctly"
11986
11987 run_acl_subtest()
11988 {
11989         local test=$LUSTRE/tests/acl/$1.test
11990         local tmp=$(mktemp -t $1-XXXXXX).test
11991         local bin=$2
11992         local dmn=$3
11993         local grp=$4
11994         local nbd=$5
11995         export LANG=C
11996
11997
11998         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11999         local sedgroups="-e s/:users/:$grp/g"
12000         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12001
12002         sed $sedusers $sedgroups < $test > $tmp
12003         stack_trap "rm -f $tmp"
12004         [[ -s $tmp ]] || error "sed failed to create test script"
12005
12006         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12007         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12008 }
12009
12010 test_103a() {
12011         [ "$UID" != 0 ] && skip "must run as root"
12012         $GSS && skip_env "could not run under gss"
12013         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12014                 skip_env "must have acl enabled"
12015         which setfacl || skip_env "could not find setfacl"
12016         remote_mds_nodsh && skip "remote MDS with nodsh"
12017
12018         ACLBIN=${ACLBIN:-"bin"}
12019         ACLDMN=${ACLDMN:-"daemon"}
12020         ACLGRP=${ACLGRP:-"users"}
12021         ACLNBD=${ACLNBD:-"nobody"}
12022
12023         if ! id $ACLBIN ||
12024            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12025                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12026                 ACLBIN=$USER0
12027                 if ! id $ACLBIN ; then
12028                         cat /etc/passwd
12029                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12030                 fi
12031         fi
12032         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12033            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12034                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12035                 ACLDMN=$USER1
12036                 if ! id $ACLDMN ; then
12037                         cat /etc/passwd
12038                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12039                 fi
12040         fi
12041         if ! getent group $ACLGRP; then
12042                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12043                 ACLGRP="$TSTUSR"
12044                 if ! getent group $ACLGRP; then
12045                         echo "cannot find group '$ACLGRP', adding it"
12046                         cat /etc/group
12047                         add_group 60000 $ACLGRP
12048                 fi
12049         fi
12050
12051         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12052         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12053         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12054
12055         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12056                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12057                 ACLGRP="$TSTUSR"
12058                 if ! getent group $ACLGRP; then
12059                         echo "cannot find group '$ACLGRP', adding it"
12060                         cat /etc/group
12061                         add_group 60000 $ACLGRP
12062                 fi
12063                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12064                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12065                         cat /etc/group
12066                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12067                 fi
12068         fi
12069
12070         gpasswd -a $ACLDMN $ACLBIN ||
12071                 error "setting client group failed"             # LU-5641
12072         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12073                 error "setting MDS group failed"                # LU-5641
12074
12075         declare -a identity_old
12076
12077         for num in $(seq $MDSCOUNT); do
12078                 switch_identity $num true || identity_old[$num]=$?
12079         done
12080
12081         SAVE_UMASK=$(umask)
12082         umask 0022
12083         mkdir -p $DIR/$tdir
12084         cd $DIR/$tdir
12085
12086         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12087         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12088         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12089         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12090         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12091         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12092         if ! id -u $ACLNBD ||
12093            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12094                 ACLNBD="nfsnobody"
12095                 if ! id -u $ACLNBD; then
12096                         ACLNBD=""
12097                 fi
12098         fi
12099         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12100                 add_group $(id -u $ACLNBD) $ACLNBD
12101                 if ! getent group $ACLNBD; then
12102                         ACLNBD=""
12103                 fi
12104         fi
12105         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12106            [[ -n "$ACLNBD" ]] && which setfattr; then
12107                 run_acl_subtest permissions_xattr \
12108                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12109         elif [[ -z "$ACLNBD" ]]; then
12110                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12111         else
12112                 echo "skip 'permission_xattr' test - missing setfattr command"
12113         fi
12114         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12115
12116         # inheritance test got from HP
12117         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12118         chmod +x make-tree || error "chmod +x failed"
12119         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12120         rm -f make-tree
12121
12122         echo "LU-974 ignore umask when acl is enabled..."
12123         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12124         if [ $MDSCOUNT -ge 2 ]; then
12125                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12126         fi
12127
12128         echo "LU-2561 newly created file is same size as directory..."
12129         if [ "$mds1_FSTYPE" != "zfs" ]; then
12130                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12131         else
12132                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12133         fi
12134
12135         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12136
12137         cd $SAVE_PWD
12138         umask $SAVE_UMASK
12139
12140         for num in $(seq $MDSCOUNT); do
12141                 if [ "${identity_old[$num]}" = 1 ]; then
12142                         switch_identity $num false || identity_old[$num]=$?
12143                 fi
12144         done
12145 }
12146 run_test 103a "acl test"
12147
12148 test_103b() {
12149         declare -a pids
12150         local U
12151
12152         for U in {0..511}; do
12153                 {
12154                 local O=$(printf "%04o" $U)
12155
12156                 umask $(printf "%04o" $((511 ^ $O)))
12157                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12158                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12159
12160                 (( $S == ($O & 0666) )) ||
12161                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12162
12163                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12164                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12165                 (( $S == ($O & 0666) )) ||
12166                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12167
12168                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12169                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12170                 (( $S == ($O & 0666) )) ||
12171                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12172                 rm -f $DIR/$tfile.[smp]$0
12173                 } &
12174                 local pid=$!
12175
12176                 # limit the concurrently running threads to 64. LU-11878
12177                 local idx=$((U % 64))
12178                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12179                 pids[idx]=$pid
12180         done
12181         wait
12182 }
12183 run_test 103b "umask lfs setstripe"
12184
12185 test_103c() {
12186         mkdir -p $DIR/$tdir
12187         cp -rp $DIR/$tdir $DIR/$tdir.bak
12188
12189         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12190                 error "$DIR/$tdir shouldn't contain default ACL"
12191         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12192                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12193         true
12194 }
12195 run_test 103c "'cp -rp' won't set empty acl"
12196
12197 test_103e() {
12198         local numacl
12199         local fileacl
12200         local saved_debug=$($LCTL get_param -n debug)
12201
12202         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12203                 skip "MDS needs to be at least 2.14.52"
12204
12205         large_xattr_enabled || skip_env "ea_inode feature disabled"
12206
12207         mkdir -p $DIR/$tdir
12208         # add big LOV EA to cause reply buffer overflow earlier
12209         $LFS setstripe -C 1000 $DIR/$tdir
12210         lctl set_param mdc.*-mdc*.stats=clear
12211
12212         $LCTL set_param debug=0
12213         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12214         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12215
12216         # add a large number of default ACLs (expect 8000+ for 2.13+)
12217         for U in {2..7000}; do
12218                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12219                         error "Able to add just $U default ACLs"
12220         done
12221         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12222         echo "$numacl default ACLs created"
12223
12224         stat $DIR/$tdir || error "Cannot stat directory"
12225         # check file creation
12226         touch $DIR/$tdir/$tfile ||
12227                 error "failed to create $tfile with $numacl default ACLs"
12228         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12229         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12230         echo "$fileacl ACLs were inherited"
12231         (( $fileacl == $numacl )) ||
12232                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12233         # check that new ACLs creation adds new ACLs to inherited ACLs
12234         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12235                 error "Cannot set new ACL"
12236         numacl=$((numacl + 1))
12237         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12238         (( $fileacl == $numacl )) ||
12239                 error "failed to add new ACL: $fileacl != $numacl as expected"
12240         # adds more ACLs to a file to reach their maximum at 8000+
12241         numacl=0
12242         for U in {20000..25000}; do
12243                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12244                 numacl=$((numacl + 1))
12245         done
12246         echo "Added $numacl more ACLs to the file"
12247         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12248         echo "Total $fileacl ACLs in file"
12249         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12250         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12251         rmdir $DIR/$tdir || error "Cannot remove directory"
12252 }
12253 run_test 103e "inheritance of big amount of default ACLs"
12254
12255 test_103f() {
12256         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12257                 skip "MDS needs to be at least 2.14.51"
12258
12259         large_xattr_enabled || skip_env "ea_inode feature disabled"
12260
12261         # enable changelog to consume more internal MDD buffers
12262         changelog_register
12263
12264         mkdir -p $DIR/$tdir
12265         # add big LOV EA
12266         $LFS setstripe -C 1000 $DIR/$tdir
12267         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12268         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12269         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12270         rmdir $DIR/$tdir || error "Cannot remove directory"
12271 }
12272 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12273
12274 test_104a() {
12275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12276
12277         touch $DIR/$tfile
12278         lfs df || error "lfs df failed"
12279         lfs df -ih || error "lfs df -ih failed"
12280         lfs df -h $DIR || error "lfs df -h $DIR failed"
12281         lfs df -i $DIR || error "lfs df -i $DIR failed"
12282         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12283         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12284
12285         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12286         lctl --device %$OSC deactivate
12287         lfs df || error "lfs df with deactivated OSC failed"
12288         lctl --device %$OSC activate
12289         # wait the osc back to normal
12290         wait_osc_import_ready client ost
12291
12292         lfs df || error "lfs df with reactivated OSC failed"
12293         rm -f $DIR/$tfile
12294 }
12295 run_test 104a "lfs df [-ih] [path] test ========================="
12296
12297 test_104b() {
12298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12299         [ $RUNAS_ID -eq $UID ] &&
12300                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12301
12302         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12303                         grep "Permission denied" | wc -l)))
12304         if [ $denied_cnt -ne 0 ]; then
12305                 error "lfs check servers test failed"
12306         fi
12307 }
12308 run_test 104b "$RUNAS lfs check servers test ===================="
12309
12310 #
12311 # Verify $1 is within range of $2.
12312 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12313 # $1 is <= 2% of $2. Else Fail.
12314 #
12315 value_in_range() {
12316         # Strip all units (M, G, T)
12317         actual=$(echo $1 | tr -d A-Z)
12318         expect=$(echo $2 | tr -d A-Z)
12319
12320         expect_lo=$(($expect * 98 / 100)) # 2% below
12321         expect_hi=$(($expect * 102 / 100)) # 2% above
12322
12323         # permit 2% drift above and below
12324         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12325 }
12326
12327 test_104c() {
12328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12329         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12330
12331         local ost_param="osd-zfs.$FSNAME-OST0000."
12332         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12333         local ofacets=$(get_facets OST)
12334         local mfacets=$(get_facets MDS)
12335         local saved_ost_blocks=
12336         local saved_mdt_blocks=
12337
12338         echo "Before recordsize change"
12339         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12340         df=($(df -h | grep "$MOUNT"$))
12341
12342         # For checking.
12343         echo "lfs output : ${lfs_df[*]}"
12344         echo "df  output : ${df[*]}"
12345
12346         for facet in ${ofacets//,/ }; do
12347                 if [ -z $saved_ost_blocks ]; then
12348                         saved_ost_blocks=$(do_facet $facet \
12349                                 lctl get_param -n $ost_param.blocksize)
12350                         echo "OST Blocksize: $saved_ost_blocks"
12351                 fi
12352                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12353                 do_facet $facet zfs set recordsize=32768 $ost
12354         done
12355
12356         # BS too small. Sufficient for functional testing.
12357         for facet in ${mfacets//,/ }; do
12358                 if [ -z $saved_mdt_blocks ]; then
12359                         saved_mdt_blocks=$(do_facet $facet \
12360                                 lctl get_param -n $mdt_param.blocksize)
12361                         echo "MDT Blocksize: $saved_mdt_blocks"
12362                 fi
12363                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12364                 do_facet $facet zfs set recordsize=32768 $mdt
12365         done
12366
12367         # Give new values chance to reflect change
12368         sleep 2
12369
12370         echo "After recordsize change"
12371         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12372         df_after=($(df -h | grep "$MOUNT"$))
12373
12374         # For checking.
12375         echo "lfs output : ${lfs_df_after[*]}"
12376         echo "df  output : ${df_after[*]}"
12377
12378         # Verify lfs df
12379         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12380                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12381         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12382                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12383         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12384                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12385
12386         # Verify df
12387         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12388                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12389         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12390                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12391         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12392                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12393
12394         # Restore MDT recordize back to original
12395         for facet in ${mfacets//,/ }; do
12396                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12397                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12398         done
12399
12400         # Restore OST recordize back to original
12401         for facet in ${ofacets//,/ }; do
12402                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12403                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12404         done
12405
12406         return 0
12407 }
12408 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12409
12410 test_104d() {
12411         (( $RUNAS_ID != $UID )) ||
12412                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12413
12414         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12415                 skip "lustre version doesn't support lctl dl with non-root"
12416
12417         # debugfs only allows root users to access files, so the
12418         # previous move of the "devices" file to debugfs broke
12419         # "lctl dl" for non-root users. The LU-9680 Netlink
12420         # interface again allows non-root users to list devices.
12421         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12422                 error "lctl dl doesn't work for non root"
12423
12424         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12425         [ "$ost_count" -eq $OSTCOUNT ]  ||
12426                 error "lctl dl reports wrong number of OST devices"
12427
12428         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12429         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12430                 error "lctl dl reports wrong number of MDT devices"
12431 }
12432 run_test 104d "$RUNAS lctl dl test"
12433
12434 test_105a() {
12435         # doesn't work on 2.4 kernels
12436         touch $DIR/$tfile
12437         if $(flock_is_enabled); then
12438                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12439         else
12440                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12441         fi
12442         rm -f $DIR/$tfile
12443 }
12444 run_test 105a "flock when mounted without -o flock test ========"
12445
12446 test_105b() {
12447         touch $DIR/$tfile
12448         if $(flock_is_enabled); then
12449                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12450         else
12451                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12452         fi
12453         rm -f $DIR/$tfile
12454 }
12455 run_test 105b "fcntl when mounted without -o flock test ========"
12456
12457 test_105c() {
12458         touch $DIR/$tfile
12459         if $(flock_is_enabled); then
12460                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12461         else
12462                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12463         fi
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 105c "lockf when mounted without -o flock test"
12467
12468 test_105d() { # bug 15924
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         test_mkdir $DIR/$tdir
12472         flock_is_enabled || skip_env "mount w/o flock enabled"
12473         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12474         $LCTL set_param fail_loc=0x80000315
12475         flocks_test 2 $DIR/$tdir
12476 }
12477 run_test 105d "flock race (should not freeze) ========"
12478
12479 test_105e() { # bug 22660 && 22040
12480         flock_is_enabled || skip_env "mount w/o flock enabled"
12481
12482         touch $DIR/$tfile
12483         flocks_test 3 $DIR/$tfile
12484 }
12485 run_test 105e "Two conflicting flocks from same process"
12486
12487 test_106() { #bug 10921
12488         test_mkdir $DIR/$tdir
12489         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12490         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12491 }
12492 run_test 106 "attempt exec of dir followed by chown of that dir"
12493
12494 test_107() {
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         CDIR=`pwd`
12498         local file=core
12499
12500         cd $DIR
12501         rm -f $file
12502
12503         local save_pattern=$(sysctl -n kernel.core_pattern)
12504         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12505         sysctl -w kernel.core_pattern=$file
12506         sysctl -w kernel.core_uses_pid=0
12507
12508         ulimit -c unlimited
12509         sleep 60 &
12510         SLEEPPID=$!
12511
12512         sleep 1
12513
12514         kill -s 11 $SLEEPPID
12515         wait $SLEEPPID
12516         if [ -e $file ]; then
12517                 size=`stat -c%s $file`
12518                 [ $size -eq 0 ] && error "Fail to create core file $file"
12519         else
12520                 error "Fail to create core file $file"
12521         fi
12522         rm -f $file
12523         sysctl -w kernel.core_pattern=$save_pattern
12524         sysctl -w kernel.core_uses_pid=$save_uses_pid
12525         cd $CDIR
12526 }
12527 run_test 107 "Coredump on SIG"
12528
12529 test_110() {
12530         test_mkdir $DIR/$tdir
12531         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12532         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12533                 error "mkdir with 256 char should fail, but did not"
12534         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12535                 error "create with 255 char failed"
12536         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12537                 error "create with 256 char should fail, but did not"
12538
12539         ls -l $DIR/$tdir
12540         rm -rf $DIR/$tdir
12541 }
12542 run_test 110 "filename length checking"
12543
12544 test_116a() { # was previously test_116()
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12547         remote_mds_nodsh && skip "remote MDS with nodsh"
12548
12549         echo -n "Free space priority "
12550         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12551                 head -n1
12552         declare -a AVAIL
12553         free_min_max
12554
12555         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12556         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12557         stack_trap simple_cleanup_common
12558
12559         # Check if we need to generate uneven OSTs
12560         test_mkdir -p $DIR/$tdir/OST${MINI}
12561         local FILL=$((MINV / 4))
12562         local DIFF=$((MAXV - MINV))
12563         local DIFF2=$((DIFF * 100 / MINV))
12564
12565         local threshold=$(do_facet $SINGLEMDS \
12566                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12567         threshold=${threshold%%%}
12568         echo -n "Check for uneven OSTs: "
12569         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12570
12571         if [[ $DIFF2 -gt $threshold ]]; then
12572                 echo "ok"
12573                 echo "Don't need to fill OST$MINI"
12574         else
12575                 # generate uneven OSTs. Write 2% over the QOS threshold value
12576                 echo "no"
12577                 DIFF=$((threshold - DIFF2 + 2))
12578                 DIFF2=$((MINV * DIFF / 100))
12579                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12580                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12581                         error "setstripe failed"
12582                 DIFF=$((DIFF2 / 2048))
12583                 i=0
12584                 while [ $i -lt $DIFF ]; do
12585                         i=$((i + 1))
12586                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12587                                 bs=2M count=1 2>/dev/null
12588                         echo -n .
12589                 done
12590                 echo .
12591                 sync
12592                 sleep_maxage
12593                 free_min_max
12594         fi
12595
12596         DIFF=$((MAXV - MINV))
12597         DIFF2=$((DIFF * 100 / MINV))
12598         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12599         if [ $DIFF2 -gt $threshold ]; then
12600                 echo "ok"
12601         else
12602                 skip "QOS imbalance criteria not met"
12603         fi
12604
12605         MINI1=$MINI
12606         MINV1=$MINV
12607         MAXI1=$MAXI
12608         MAXV1=$MAXV
12609
12610         # now fill using QOS
12611         $LFS setstripe -c 1 $DIR/$tdir
12612         FILL=$((FILL / 200))
12613         if [ $FILL -gt 600 ]; then
12614                 FILL=600
12615         fi
12616         echo "writing $FILL files to QOS-assigned OSTs"
12617         i=0
12618         while [ $i -lt $FILL ]; do
12619                 i=$((i + 1))
12620                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12621                         count=1 2>/dev/null
12622                 echo -n .
12623         done
12624         echo "wrote $i 200k files"
12625         sync
12626         sleep_maxage
12627
12628         echo "Note: free space may not be updated, so measurements might be off"
12629         free_min_max
12630         DIFF2=$((MAXV - MINV))
12631         echo "free space delta: orig $DIFF final $DIFF2"
12632         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12633         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12634         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12635         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12636         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12637         if [[ $DIFF -gt 0 ]]; then
12638                 FILL=$((DIFF2 * 100 / DIFF - 100))
12639                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12640         fi
12641
12642         # Figure out which files were written where
12643         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12644                awk '/'$MINI1': / {print $2; exit}')
12645         echo $UUID
12646         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12647         echo "$MINC files created on smaller OST $MINI1"
12648         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12649                awk '/'$MAXI1': / {print $2; exit}')
12650         echo $UUID
12651         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12652         echo "$MAXC files created on larger OST $MAXI1"
12653         if [[ $MINC -gt 0 ]]; then
12654                 FILL=$((MAXC * 100 / MINC - 100))
12655                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12656         fi
12657         [[ $MAXC -gt $MINC ]] ||
12658                 error_ignore LU-9 "stripe QOS didn't balance free space"
12659 }
12660 run_test 116a "stripe QOS: free space balance ==================="
12661
12662 test_116b() { # LU-2093
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664         remote_mds_nodsh && skip "remote MDS with nodsh"
12665
12666 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12667         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12668                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12669         [ -z "$old_rr" ] && skip "no QOS"
12670         do_facet $SINGLEMDS lctl set_param \
12671                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12672         mkdir -p $DIR/$tdir
12673         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12674         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12675         do_facet $SINGLEMDS lctl set_param fail_loc=0
12676         rm -rf $DIR/$tdir
12677         do_facet $SINGLEMDS lctl set_param \
12678                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12679 }
12680 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12681
12682 test_117() # bug 10891
12683 {
12684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12685
12686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12687         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12688         lctl set_param fail_loc=0x21e
12689         > $DIR/$tfile || error "truncate failed"
12690         lctl set_param fail_loc=0
12691         echo "Truncate succeeded."
12692         rm -f $DIR/$tfile
12693 }
12694 run_test 117 "verify osd extend =========="
12695
12696 NO_SLOW_RESENDCOUNT=4
12697 export OLD_RESENDCOUNT=""
12698 set_resend_count () {
12699         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12700         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12701         lctl set_param -n $PROC_RESENDCOUNT $1
12702         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12703 }
12704
12705 # for reduce test_118* time (b=14842)
12706 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12707
12708 # Reset async IO behavior after error case
12709 reset_async() {
12710         FILE=$DIR/reset_async
12711
12712         # Ensure all OSCs are cleared
12713         $LFS setstripe -c -1 $FILE
12714         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12715         sync
12716         rm $FILE
12717 }
12718
12719 test_118a() #bug 11710
12720 {
12721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12722
12723         reset_async
12724
12725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12726         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12727         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12728
12729         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12730                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12731                 return 1;
12732         fi
12733         rm -f $DIR/$tfile
12734 }
12735 run_test 118a "verify O_SYNC works =========="
12736
12737 test_118b()
12738 {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740         remote_ost_nodsh && skip "remote OST with nodsh"
12741
12742         reset_async
12743
12744         #define OBD_FAIL_SRV_ENOENT 0x217
12745         set_nodes_failloc "$(osts_nodes)" 0x217
12746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12747         RC=$?
12748         set_nodes_failloc "$(osts_nodes)" 0
12749         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12750         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12751                     grep -c writeback)
12752
12753         if [[ $RC -eq 0 ]]; then
12754                 error "Must return error due to dropped pages, rc=$RC"
12755                 return 1;
12756         fi
12757
12758         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12759                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12760                 return 1;
12761         fi
12762
12763         echo "Dirty pages not leaked on ENOENT"
12764
12765         # Due to the above error the OSC will issue all RPCs syncronously
12766         # until a subsequent RPC completes successfully without error.
12767         $MULTIOP $DIR/$tfile Ow4096yc
12768         rm -f $DIR/$tfile
12769
12770         return 0
12771 }
12772 run_test 118b "Reclaim dirty pages on fatal error =========="
12773
12774 test_118c()
12775 {
12776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12777
12778         # for 118c, restore the original resend count, LU-1940
12779         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12780                                 set_resend_count $OLD_RESENDCOUNT
12781         remote_ost_nodsh && skip "remote OST with nodsh"
12782
12783         reset_async
12784
12785         #define OBD_FAIL_OST_EROFS               0x216
12786         set_nodes_failloc "$(osts_nodes)" 0x216
12787
12788         # multiop should block due to fsync until pages are written
12789         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12790         MULTIPID=$!
12791         sleep 1
12792
12793         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12794                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12795         fi
12796
12797         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12798                     grep -c writeback)
12799         if [[ $WRITEBACK -eq 0 ]]; then
12800                 error "No page in writeback, writeback=$WRITEBACK"
12801         fi
12802
12803         set_nodes_failloc "$(osts_nodes)" 0
12804         wait $MULTIPID
12805         RC=$?
12806         if [[ $RC -ne 0 ]]; then
12807                 error "Multiop fsync failed, rc=$RC"
12808         fi
12809
12810         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12811         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12812                     grep -c writeback)
12813         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12814                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12815         fi
12816
12817         rm -f $DIR/$tfile
12818         echo "Dirty pages flushed via fsync on EROFS"
12819         return 0
12820 }
12821 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12822
12823 # continue to use small resend count to reduce test_118* time (b=14842)
12824 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12825
12826 test_118d()
12827 {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         remote_ost_nodsh && skip "remote OST with nodsh"
12830
12831         reset_async
12832
12833         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12834         set_nodes_failloc "$(osts_nodes)" 0x214
12835         # multiop should block due to fsync until pages are written
12836         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12837         MULTIPID=$!
12838         sleep 1
12839
12840         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12841                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12842         fi
12843
12844         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12845                     grep -c writeback)
12846         if [[ $WRITEBACK -eq 0 ]]; then
12847                 error "No page in writeback, writeback=$WRITEBACK"
12848         fi
12849
12850         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12851         set_nodes_failloc "$(osts_nodes)" 0
12852
12853         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12854         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12855                     grep -c writeback)
12856         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12857                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12858         fi
12859
12860         rm -f $DIR/$tfile
12861         echo "Dirty pages gaurenteed flushed via fsync"
12862         return 0
12863 }
12864 run_test 118d "Fsync validation inject a delay of the bulk =========="
12865
12866 test_118f() {
12867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12868
12869         reset_async
12870
12871         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12872         lctl set_param fail_loc=0x8000040a
12873
12874         # Should simulate EINVAL error which is fatal
12875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12876         RC=$?
12877         if [[ $RC -eq 0 ]]; then
12878                 error "Must return error due to dropped pages, rc=$RC"
12879         fi
12880
12881         lctl set_param fail_loc=0x0
12882
12883         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12884         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12885         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12886                     grep -c writeback)
12887         if [[ $LOCKED -ne 0 ]]; then
12888                 error "Locked pages remain in cache, locked=$LOCKED"
12889         fi
12890
12891         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12892                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12893         fi
12894
12895         rm -f $DIR/$tfile
12896         echo "No pages locked after fsync"
12897
12898         reset_async
12899         return 0
12900 }
12901 run_test 118f "Simulate unrecoverable OSC side error =========="
12902
12903 test_118g() {
12904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12905
12906         reset_async
12907
12908         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12909         lctl set_param fail_loc=0x406
12910
12911         # simulate local -ENOMEM
12912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12913         RC=$?
12914
12915         lctl set_param fail_loc=0
12916         if [[ $RC -eq 0 ]]; then
12917                 error "Must return error due to dropped pages, rc=$RC"
12918         fi
12919
12920         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12921         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12922         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12923                         grep -c writeback)
12924         if [[ $LOCKED -ne 0 ]]; then
12925                 error "Locked pages remain in cache, locked=$LOCKED"
12926         fi
12927
12928         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12929                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12930         fi
12931
12932         rm -f $DIR/$tfile
12933         echo "No pages locked after fsync"
12934
12935         reset_async
12936         return 0
12937 }
12938 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12939
12940 test_118h() {
12941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12942         remote_ost_nodsh && skip "remote OST with nodsh"
12943
12944         reset_async
12945
12946         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12947         set_nodes_failloc "$(osts_nodes)" 0x20e
12948         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12949         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12950         RC=$?
12951
12952         set_nodes_failloc "$(osts_nodes)" 0
12953         if [[ $RC -eq 0 ]]; then
12954                 error "Must return error due to dropped pages, rc=$RC"
12955         fi
12956
12957         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12958         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12960                     grep -c writeback)
12961         if [[ $LOCKED -ne 0 ]]; then
12962                 error "Locked pages remain in cache, locked=$LOCKED"
12963         fi
12964
12965         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12966                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12967         fi
12968
12969         rm -f $DIR/$tfile
12970         echo "No pages locked after fsync"
12971
12972         return 0
12973 }
12974 run_test 118h "Verify timeout in handling recoverables errors  =========="
12975
12976 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12977
12978 test_118i() {
12979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12980         remote_ost_nodsh && skip "remote OST with nodsh"
12981
12982         reset_async
12983
12984         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12985         set_nodes_failloc "$(osts_nodes)" 0x20e
12986
12987         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12988         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12989         PID=$!
12990         sleep 5
12991         set_nodes_failloc "$(osts_nodes)" 0
12992
12993         wait $PID
12994         RC=$?
12995         if [[ $RC -ne 0 ]]; then
12996                 error "got error, but should be not, rc=$RC"
12997         fi
12998
12999         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13002         if [[ $LOCKED -ne 0 ]]; then
13003                 error "Locked pages remain in cache, locked=$LOCKED"
13004         fi
13005
13006         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13007                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13008         fi
13009
13010         rm -f $DIR/$tfile
13011         echo "No pages locked after fsync"
13012
13013         return 0
13014 }
13015 run_test 118i "Fix error before timeout in recoverable error  =========="
13016
13017 [ "$SLOW" = "no" ] && set_resend_count 4
13018
13019 test_118j() {
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021         remote_ost_nodsh && skip "remote OST with nodsh"
13022
13023         reset_async
13024
13025         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13026         set_nodes_failloc "$(osts_nodes)" 0x220
13027
13028         # return -EIO from OST
13029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13030         RC=$?
13031         set_nodes_failloc "$(osts_nodes)" 0x0
13032         if [[ $RC -eq 0 ]]; then
13033                 error "Must return error due to dropped pages, rc=$RC"
13034         fi
13035
13036         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13039         if [[ $LOCKED -ne 0 ]]; then
13040                 error "Locked pages remain in cache, locked=$LOCKED"
13041         fi
13042
13043         # in recoverable error on OST we want resend and stay until it finished
13044         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13045                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13046         fi
13047
13048         rm -f $DIR/$tfile
13049         echo "No pages locked after fsync"
13050
13051         return 0
13052 }
13053 run_test 118j "Simulate unrecoverable OST side error =========="
13054
13055 test_118k()
13056 {
13057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13058         remote_ost_nodsh && skip "remote OSTs with nodsh"
13059
13060         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13061         set_nodes_failloc "$(osts_nodes)" 0x20e
13062         test_mkdir $DIR/$tdir
13063
13064         for ((i=0;i<10;i++)); do
13065                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13066                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13067                 SLEEPPID=$!
13068                 sleep 0.500s
13069                 kill $SLEEPPID
13070                 wait $SLEEPPID
13071         done
13072
13073         set_nodes_failloc "$(osts_nodes)" 0
13074         rm -rf $DIR/$tdir
13075 }
13076 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13077
13078 test_118l() # LU-646
13079 {
13080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13081
13082         test_mkdir $DIR/$tdir
13083         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13084         rm -rf $DIR/$tdir
13085 }
13086 run_test 118l "fsync dir"
13087
13088 test_118m() # LU-3066
13089 {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091
13092         test_mkdir $DIR/$tdir
13093         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13094         rm -rf $DIR/$tdir
13095 }
13096 run_test 118m "fdatasync dir ========="
13097
13098 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13099
13100 test_118n()
13101 {
13102         local begin
13103         local end
13104
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106         remote_ost_nodsh && skip "remote OSTs with nodsh"
13107
13108         # Sleep to avoid a cached response.
13109         #define OBD_STATFS_CACHE_SECONDS 1
13110         sleep 2
13111
13112         # Inject a 10 second delay in the OST_STATFS handler.
13113         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13114         set_nodes_failloc "$(osts_nodes)" 0x242
13115
13116         begin=$SECONDS
13117         stat --file-system $MOUNT > /dev/null
13118         end=$SECONDS
13119
13120         set_nodes_failloc "$(osts_nodes)" 0
13121
13122         if ((end - begin > 20)); then
13123             error "statfs took $((end - begin)) seconds, expected 10"
13124         fi
13125 }
13126 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13127
13128 test_119a() # bug 11737
13129 {
13130         BSIZE=$((512 * 1024))
13131         directio write $DIR/$tfile 0 1 $BSIZE
13132         # We ask to read two blocks, which is more than a file size.
13133         # directio will indicate an error when requested and actual
13134         # sizes aren't equeal (a normal situation in this case) and
13135         # print actual read amount.
13136         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13137         if [ "$NOB" != "$BSIZE" ]; then
13138                 error "read $NOB bytes instead of $BSIZE"
13139         fi
13140         rm -f $DIR/$tfile
13141 }
13142 run_test 119a "Short directIO read must return actual read amount"
13143
13144 test_119b() # bug 11737
13145 {
13146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13147
13148         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13150         sync
13151         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13152                 error "direct read failed"
13153         rm -f $DIR/$tfile
13154 }
13155 run_test 119b "Sparse directIO read must return actual read amount"
13156
13157 test_119c() # bug 13099
13158 {
13159         BSIZE=1048576
13160         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13161         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13162         rm -f $DIR/$tfile
13163 }
13164 run_test 119c "Testing for direct read hitting hole"
13165
13166 test_119d() # bug 15950
13167 {
13168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13169
13170         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13171         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13172         BSIZE=1048576
13173         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13174         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13175         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13176         lctl set_param fail_loc=0x40d
13177         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13178         pid_dio=$!
13179         sleep 1
13180         cat $DIR/$tfile > /dev/null &
13181         lctl set_param fail_loc=0
13182         pid_reads=$!
13183         wait $pid_dio
13184         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13185         sleep 2
13186         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13187         error "the read rpcs have not completed in 2s"
13188         rm -f $DIR/$tfile
13189         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13190 }
13191 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13192
13193 test_120a() {
13194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13195         remote_mds_nodsh && skip "remote MDS with nodsh"
13196         test_mkdir -i0 -c1 $DIR/$tdir
13197         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13198                 skip_env "no early lock cancel on server"
13199
13200         lru_resize_disable mdc
13201         lru_resize_disable osc
13202         cancel_lru_locks mdc
13203         # asynchronous object destroy at MDT could cause bl ast to client
13204         cancel_lru_locks osc
13205
13206         stat $DIR/$tdir > /dev/null
13207         can1=$(do_facet mds1 \
13208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13209                awk '/ldlm_cancel/ {print $2}')
13210         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13211                awk '/ldlm_bl_callback/ {print $2}')
13212         test_mkdir -i0 -c1 $DIR/$tdir/d1
13213         can2=$(do_facet mds1 \
13214                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13215                awk '/ldlm_cancel/ {print $2}')
13216         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13217                awk '/ldlm_bl_callback/ {print $2}')
13218         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13219         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13220         lru_resize_enable mdc
13221         lru_resize_enable osc
13222 }
13223 run_test 120a "Early Lock Cancel: mkdir test"
13224
13225 test_120b() {
13226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13227         remote_mds_nodsh && skip "remote MDS with nodsh"
13228         test_mkdir $DIR/$tdir
13229         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13230                 skip_env "no early lock cancel on server"
13231
13232         lru_resize_disable mdc
13233         lru_resize_disable osc
13234         cancel_lru_locks mdc
13235         stat $DIR/$tdir > /dev/null
13236         can1=$(do_facet $SINGLEMDS \
13237                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13238                awk '/ldlm_cancel/ {print $2}')
13239         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13240                awk '/ldlm_bl_callback/ {print $2}')
13241         touch $DIR/$tdir/f1
13242         can2=$(do_facet $SINGLEMDS \
13243                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13244                awk '/ldlm_cancel/ {print $2}')
13245         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13246                awk '/ldlm_bl_callback/ {print $2}')
13247         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13248         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13249         lru_resize_enable mdc
13250         lru_resize_enable osc
13251 }
13252 run_test 120b "Early Lock Cancel: create test"
13253
13254 test_120c() {
13255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13256         remote_mds_nodsh && skip "remote MDS with nodsh"
13257         test_mkdir -i0 -c1 $DIR/$tdir
13258         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13259                 skip "no early lock cancel on server"
13260
13261         lru_resize_disable mdc
13262         lru_resize_disable osc
13263         test_mkdir -i0 -c1 $DIR/$tdir/d1
13264         test_mkdir -i0 -c1 $DIR/$tdir/d2
13265         touch $DIR/$tdir/d1/f1
13266         cancel_lru_locks mdc
13267         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13268         can1=$(do_facet mds1 \
13269                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13270                awk '/ldlm_cancel/ {print $2}')
13271         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13272                awk '/ldlm_bl_callback/ {print $2}')
13273         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13274         can2=$(do_facet mds1 \
13275                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13276                awk '/ldlm_cancel/ {print $2}')
13277         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13278                awk '/ldlm_bl_callback/ {print $2}')
13279         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13280         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13281         lru_resize_enable mdc
13282         lru_resize_enable osc
13283 }
13284 run_test 120c "Early Lock Cancel: link test"
13285
13286 test_120d() {
13287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13288         remote_mds_nodsh && skip "remote MDS with nodsh"
13289         test_mkdir -i0 -c1 $DIR/$tdir
13290         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13291                 skip_env "no early lock cancel on server"
13292
13293         lru_resize_disable mdc
13294         lru_resize_disable osc
13295         touch $DIR/$tdir
13296         cancel_lru_locks mdc
13297         stat $DIR/$tdir > /dev/null
13298         can1=$(do_facet mds1 \
13299                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13300                awk '/ldlm_cancel/ {print $2}')
13301         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13302                awk '/ldlm_bl_callback/ {print $2}')
13303         chmod a+x $DIR/$tdir
13304         can2=$(do_facet mds1 \
13305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13306                awk '/ldlm_cancel/ {print $2}')
13307         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13308                awk '/ldlm_bl_callback/ {print $2}')
13309         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13310         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13311         lru_resize_enable mdc
13312         lru_resize_enable osc
13313 }
13314 run_test 120d "Early Lock Cancel: setattr test"
13315
13316 test_120e() {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13319                 skip_env "no early lock cancel on server"
13320         remote_mds_nodsh && skip "remote MDS with nodsh"
13321
13322         local dlmtrace_set=false
13323
13324         test_mkdir -i0 -c1 $DIR/$tdir
13325         lru_resize_disable mdc
13326         lru_resize_disable osc
13327         ! $LCTL get_param debug | grep -q dlmtrace &&
13328                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13329         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13330         cancel_lru_locks mdc
13331         cancel_lru_locks osc
13332         dd if=$DIR/$tdir/f1 of=/dev/null
13333         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13334         # XXX client can not do early lock cancel of OST lock
13335         # during unlink (LU-4206), so cancel osc lock now.
13336         sleep 2
13337         cancel_lru_locks osc
13338         can1=$(do_facet mds1 \
13339                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13340                awk '/ldlm_cancel/ {print $2}')
13341         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13342                awk '/ldlm_bl_callback/ {print $2}')
13343         unlink $DIR/$tdir/f1
13344         sleep 5
13345         can2=$(do_facet mds1 \
13346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13347                awk '/ldlm_cancel/ {print $2}')
13348         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13349                awk '/ldlm_bl_callback/ {print $2}')
13350         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13351                 $LCTL dk $TMP/cancel.debug.txt
13352         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13353                 $LCTL dk $TMP/blocking.debug.txt
13354         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13355         lru_resize_enable mdc
13356         lru_resize_enable osc
13357 }
13358 run_test 120e "Early Lock Cancel: unlink test"
13359
13360 test_120f() {
13361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13362         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13363                 skip_env "no early lock cancel on server"
13364         remote_mds_nodsh && skip "remote MDS with nodsh"
13365
13366         test_mkdir -i0 -c1 $DIR/$tdir
13367         lru_resize_disable mdc
13368         lru_resize_disable osc
13369         test_mkdir -i0 -c1 $DIR/$tdir/d1
13370         test_mkdir -i0 -c1 $DIR/$tdir/d2
13371         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13372         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13373         cancel_lru_locks mdc
13374         cancel_lru_locks osc
13375         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13376         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13377         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13378         # XXX client can not do early lock cancel of OST lock
13379         # during rename (LU-4206), so cancel osc lock now.
13380         sleep 2
13381         cancel_lru_locks osc
13382         can1=$(do_facet mds1 \
13383                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13384                awk '/ldlm_cancel/ {print $2}')
13385         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13386                awk '/ldlm_bl_callback/ {print $2}')
13387         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13388         sleep 5
13389         can2=$(do_facet mds1 \
13390                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13391                awk '/ldlm_cancel/ {print $2}')
13392         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13393                awk '/ldlm_bl_callback/ {print $2}')
13394         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13395         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13396         lru_resize_enable mdc
13397         lru_resize_enable osc
13398 }
13399 run_test 120f "Early Lock Cancel: rename test"
13400
13401 test_120g() {
13402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13403         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13404                 skip_env "no early lock cancel on server"
13405         remote_mds_nodsh && skip "remote MDS with nodsh"
13406
13407         lru_resize_disable mdc
13408         lru_resize_disable osc
13409         count=10000
13410         echo create $count files
13411         test_mkdir $DIR/$tdir
13412         cancel_lru_locks mdc
13413         cancel_lru_locks osc
13414         t0=$(date +%s)
13415
13416         can0=$(do_facet $SINGLEMDS \
13417                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13418                awk '/ldlm_cancel/ {print $2}')
13419         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13420                awk '/ldlm_bl_callback/ {print $2}')
13421         createmany -o $DIR/$tdir/f $count
13422         sync
13423         can1=$(do_facet $SINGLEMDS \
13424                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13425                awk '/ldlm_cancel/ {print $2}')
13426         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13427                awk '/ldlm_bl_callback/ {print $2}')
13428         t1=$(date +%s)
13429         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13430         echo rm $count files
13431         rm -r $DIR/$tdir
13432         sync
13433         can2=$(do_facet $SINGLEMDS \
13434                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13435                awk '/ldlm_cancel/ {print $2}')
13436         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13437                awk '/ldlm_bl_callback/ {print $2}')
13438         t2=$(date +%s)
13439         echo total: $count removes in $((t2-t1))
13440         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13441         sleep 2
13442         # wait for commitment of removal
13443         lru_resize_enable mdc
13444         lru_resize_enable osc
13445 }
13446 run_test 120g "Early Lock Cancel: performance test"
13447
13448 test_121() { #bug #10589
13449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13450
13451         rm -rf $DIR/$tfile
13452         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13453 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13454         lctl set_param fail_loc=0x310
13455         cancel_lru_locks osc > /dev/null
13456         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13457         lctl set_param fail_loc=0
13458         [[ $reads -eq $writes ]] ||
13459                 error "read $reads blocks, must be $writes blocks"
13460 }
13461 run_test 121 "read cancel race ========="
13462
13463 test_123a_base() { # was test 123, statahead(bug 11401)
13464         local lsx="$1"
13465
13466         SLOWOK=0
13467         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13468                 log "testing UP system. Performance may be lower than expected."
13469                 SLOWOK=1
13470         fi
13471         running_in_vm && SLOWOK=1
13472
13473         rm -rf $DIR/$tdir
13474         test_mkdir $DIR/$tdir
13475         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13476         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13477         MULT=10
13478         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13479                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13480
13481                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13482                 lctl set_param -n llite.*.statahead_max 0
13483                 lctl get_param llite.*.statahead_max
13484                 cancel_lru_locks mdc
13485                 cancel_lru_locks osc
13486                 stime=$(date +%s)
13487                 time $lsx $DIR/$tdir | wc -l
13488                 etime=$(date +%s)
13489                 delta=$((etime - stime))
13490                 log "$lsx $i files without statahead: $delta sec"
13491                 lctl set_param llite.*.statahead_max=$max
13492
13493                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13494                          awk '/statahead.wrong:/ { print $NF }')
13495                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13496                 cancel_lru_locks mdc
13497                 cancel_lru_locks osc
13498                 stime=$(date +%s)
13499                 time $lsx $DIR/$tdir | wc -l
13500                 etime=$(date +%s)
13501                 delta_sa=$((etime - stime))
13502                 log "$lsx $i files with statahead: $delta_sa sec"
13503                 lctl get_param -n llite.*.statahead_stats
13504                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13505                          awk '/statahead.wrong:/ { print $NF }')
13506
13507                 [[ $swrong -lt $ewrong ]] &&
13508                         log "statahead was stopped, maybe too many locks held!"
13509                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13510
13511                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13512                         max=$(lctl get_param -n llite.*.statahead_max |
13513                                 head -n 1)
13514                         lctl set_param -n llite.*.statahead_max 0
13515                         lctl get_param llite.*.statahead_max
13516                         cancel_lru_locks mdc
13517                         cancel_lru_locks osc
13518                         stime=$(date +%s)
13519                         time $lsx $DIR/$tdir | wc -l
13520                         etime=$(date +%s)
13521                         delta=$((etime - stime))
13522                         log "$lsx $i files again without statahead: $delta sec"
13523                         lctl set_param llite.*.statahead_max=$max
13524                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13525                                 if [ $SLOWOK -eq 0 ]; then
13526                                         error "$lsx $i files is slower with statahead!"
13527                                 else
13528                                         log "$lsx $i files is slower with statahead!"
13529                                 fi
13530                                 break
13531                         fi
13532                 fi
13533
13534                 [ $delta -gt 20 ] && break
13535                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13536                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13537         done
13538         log "$lsx done"
13539
13540         stime=$(date +%s)
13541         rm -r $DIR/$tdir
13542         sync
13543         etime=$(date +%s)
13544         delta=$((etime - stime))
13545         log "rm -r $DIR/$tdir/: $delta seconds"
13546         log "rm done"
13547         lctl get_param -n llite.*.statahead_stats
13548 }
13549
13550 test_123aa() {
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552
13553         test_123a_base "ls -l"
13554 }
13555 run_test 123aa "verify statahead work"
13556
13557 test_123ab() {
13558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13559
13560         statx_supported || skip_env "Test must be statx() syscall supported"
13561
13562         test_123a_base "$STATX -l"
13563 }
13564 run_test 123ab "verify statahead work by using statx"
13565
13566 test_123ac() {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568
13569         statx_supported || skip_env "Test must be statx() syscall supported"
13570
13571         local rpcs_before
13572         local rpcs_after
13573         local agl_before
13574         local agl_after
13575
13576         cancel_lru_locks $OSC
13577         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13578         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13579                      awk '/agl.total:/ { print $NF }')
13580         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13581         test_123a_base "$STATX --cached=always -D"
13582         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13583                     awk '/agl.total:/ { print $NF }')
13584         [ $agl_before -eq $agl_after ] ||
13585                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13586         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13587         [ $rpcs_after -eq $rpcs_before ] ||
13588                 error "$STATX should not send glimpse RPCs to $OSC"
13589 }
13590 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13591
13592 test_123b () { # statahead(bug 15027)
13593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13594
13595         test_mkdir $DIR/$tdir
13596         createmany -o $DIR/$tdir/$tfile-%d 1000
13597
13598         cancel_lru_locks mdc
13599         cancel_lru_locks osc
13600
13601 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13602         lctl set_param fail_loc=0x80000803
13603         ls -lR $DIR/$tdir > /dev/null
13604         log "ls done"
13605         lctl set_param fail_loc=0x0
13606         lctl get_param -n llite.*.statahead_stats
13607         rm -r $DIR/$tdir
13608         sync
13609
13610 }
13611 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13612
13613 test_123c() {
13614         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13615
13616         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13617         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13618         touch $DIR/$tdir.1/{1..3}
13619         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13620
13621         remount_client $MOUNT
13622
13623         $MULTIOP $DIR/$tdir.0 Q
13624
13625         # let statahead to complete
13626         ls -l $DIR/$tdir.0 > /dev/null
13627
13628         testid=$(echo $TESTNAME | tr '_' ' ')
13629         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13630                 error "statahead warning" || true
13631 }
13632 run_test 123c "Can not initialize inode warning on DNE statahead"
13633
13634 test_123d() {
13635         local num=100
13636         local swrong
13637         local ewrong
13638
13639         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13640         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13641                 error "setdirstripe $DIR/$tdir failed"
13642         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13643         remount_client $MOUNT
13644         $LCTL get_param llite.*.statahead_max
13645         $LCTL set_param llite.*.statahead_stats=0 ||
13646                 error "clear statahead_stats failed"
13647         swrong=$(lctl get_param -n llite.*.statahead_stats |
13648                  awk '/statahead.wrong:/ { print $NF }')
13649         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13650         # wait for statahead thread finished to update hit/miss stats.
13651         sleep 1
13652         $LCTL get_param -n llite.*.statahead_stats
13653         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13654                  awk '/statahead.wrong:/ { print $NF }')
13655         (( $swrong == $ewrong )) ||
13656                 log "statahead was stopped, maybe too many locks held!"
13657 }
13658 run_test 123d "Statahead on striped directories works correctly"
13659
13660 test_124a() {
13661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13662         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13663                 skip_env "no lru resize on server"
13664
13665         local NR=2000
13666
13667         test_mkdir $DIR/$tdir
13668
13669         log "create $NR files at $DIR/$tdir"
13670         createmany -o $DIR/$tdir/f $NR ||
13671                 error "failed to create $NR files in $DIR/$tdir"
13672
13673         cancel_lru_locks mdc
13674         ls -l $DIR/$tdir > /dev/null
13675
13676         local NSDIR=""
13677         local LRU_SIZE=0
13678         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13679                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13680                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13681                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13682                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13683                         log "NSDIR=$NSDIR"
13684                         log "NS=$(basename $NSDIR)"
13685                         break
13686                 fi
13687         done
13688
13689         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13690                 skip "Not enough cached locks created!"
13691         fi
13692         log "LRU=$LRU_SIZE"
13693
13694         local SLEEP=30
13695
13696         # We know that lru resize allows one client to hold $LIMIT locks
13697         # for 10h. After that locks begin to be killed by client.
13698         local MAX_HRS=10
13699         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13700         log "LIMIT=$LIMIT"
13701         if [ $LIMIT -lt $LRU_SIZE ]; then
13702                 skip "Limit is too small $LIMIT"
13703         fi
13704
13705         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13706         # killing locks. Some time was spent for creating locks. This means
13707         # that up to the moment of sleep finish we must have killed some of
13708         # them (10-100 locks). This depends on how fast ther were created.
13709         # Many of them were touched in almost the same moment and thus will
13710         # be killed in groups.
13711         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13712
13713         # Use $LRU_SIZE_B here to take into account real number of locks
13714         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13715         local LRU_SIZE_B=$LRU_SIZE
13716         log "LVF=$LVF"
13717         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13718         log "OLD_LVF=$OLD_LVF"
13719         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13720
13721         # Let's make sure that we really have some margin. Client checks
13722         # cached locks every 10 sec.
13723         SLEEP=$((SLEEP+20))
13724         log "Sleep ${SLEEP} sec"
13725         local SEC=0
13726         while ((SEC<$SLEEP)); do
13727                 echo -n "..."
13728                 sleep 5
13729                 SEC=$((SEC+5))
13730                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13731                 echo -n "$LRU_SIZE"
13732         done
13733         echo ""
13734         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13735         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13736
13737         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13738                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13739                 unlinkmany $DIR/$tdir/f $NR
13740                 return
13741         }
13742
13743         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13744         log "unlink $NR files at $DIR/$tdir"
13745         unlinkmany $DIR/$tdir/f $NR
13746 }
13747 run_test 124a "lru resize ======================================="
13748
13749 get_max_pool_limit()
13750 {
13751         local limit=$($LCTL get_param \
13752                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13753         local max=0
13754         for l in $limit; do
13755                 if [[ $l -gt $max ]]; then
13756                         max=$l
13757                 fi
13758         done
13759         echo $max
13760 }
13761
13762 test_124b() {
13763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13764         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13765                 skip_env "no lru resize on server"
13766
13767         LIMIT=$(get_max_pool_limit)
13768
13769         NR=$(($(default_lru_size)*20))
13770         if [[ $NR -gt $LIMIT ]]; then
13771                 log "Limit lock number by $LIMIT locks"
13772                 NR=$LIMIT
13773         fi
13774
13775         IFree=$(mdsrate_inodes_available)
13776         if [ $IFree -lt $NR ]; then
13777                 log "Limit lock number by $IFree inodes"
13778                 NR=$IFree
13779         fi
13780
13781         lru_resize_disable mdc
13782         test_mkdir -p $DIR/$tdir/disable_lru_resize
13783
13784         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13785         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13786         cancel_lru_locks mdc
13787         stime=`date +%s`
13788         PID=""
13789         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13790         PID="$PID $!"
13791         sleep 2
13792         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13793         PID="$PID $!"
13794         sleep 2
13795         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13796         PID="$PID $!"
13797         wait $PID
13798         etime=`date +%s`
13799         nolruresize_delta=$((etime-stime))
13800         log "ls -la time: $nolruresize_delta seconds"
13801         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13802         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13803
13804         lru_resize_enable mdc
13805         test_mkdir -p $DIR/$tdir/enable_lru_resize
13806
13807         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13808         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13809         cancel_lru_locks mdc
13810         stime=`date +%s`
13811         PID=""
13812         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13813         PID="$PID $!"
13814         sleep 2
13815         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13816         PID="$PID $!"
13817         sleep 2
13818         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13819         PID="$PID $!"
13820         wait $PID
13821         etime=`date +%s`
13822         lruresize_delta=$((etime-stime))
13823         log "ls -la time: $lruresize_delta seconds"
13824         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13825
13826         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13827                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13828         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13829                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13830         else
13831                 log "lru resize performs the same with no lru resize"
13832         fi
13833         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13834 }
13835 run_test 124b "lru resize (performance test) ======================="
13836
13837 test_124c() {
13838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13839         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13840                 skip_env "no lru resize on server"
13841
13842         # cache ununsed locks on client
13843         local nr=100
13844         cancel_lru_locks mdc
13845         test_mkdir $DIR/$tdir
13846         createmany -o $DIR/$tdir/f $nr ||
13847                 error "failed to create $nr files in $DIR/$tdir"
13848         ls -l $DIR/$tdir > /dev/null
13849
13850         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13851         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13852         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13853         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13854         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13855
13856         # set lru_max_age to 1 sec
13857         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13858         echo "sleep $((recalc_p * 2)) seconds..."
13859         sleep $((recalc_p * 2))
13860
13861         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13862         # restore lru_max_age
13863         $LCTL set_param -n $nsdir.lru_max_age $max_age
13864         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13865         unlinkmany $DIR/$tdir/f $nr
13866 }
13867 run_test 124c "LRUR cancel very aged locks"
13868
13869 test_124d() {
13870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13871         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13872                 skip_env "no lru resize on server"
13873
13874         # cache ununsed locks on client
13875         local nr=100
13876
13877         lru_resize_disable mdc
13878         stack_trap "lru_resize_enable mdc" EXIT
13879
13880         cancel_lru_locks mdc
13881
13882         # asynchronous object destroy at MDT could cause bl ast to client
13883         test_mkdir $DIR/$tdir
13884         createmany -o $DIR/$tdir/f $nr ||
13885                 error "failed to create $nr files in $DIR/$tdir"
13886         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13887
13888         ls -l $DIR/$tdir > /dev/null
13889
13890         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13891         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13892         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13893         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13894
13895         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13896
13897         # set lru_max_age to 1 sec
13898         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13899         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13900
13901         echo "sleep $((recalc_p * 2)) seconds..."
13902         sleep $((recalc_p * 2))
13903
13904         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13905
13906         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13907 }
13908 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13909
13910 test_125() { # 13358
13911         $LCTL get_param -n llite.*.client_type | grep -q local ||
13912                 skip "must run as local client"
13913         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13914                 skip_env "must have acl enabled"
13915         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13916
13917         test_mkdir $DIR/$tdir
13918         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13919         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13920                 error "setfacl $DIR/$tdir failed"
13921         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13922 }
13923 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13924
13925 test_126() { # bug 12829/13455
13926         $GSS && skip_env "must run as gss disabled"
13927         $LCTL get_param -n llite.*.client_type | grep -q local ||
13928                 skip "must run as local client"
13929         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13930
13931         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13932         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13933         rm -f $DIR/$tfile
13934         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13935 }
13936 run_test 126 "check that the fsgid provided by the client is taken into account"
13937
13938 test_127a() { # bug 15521
13939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13940         local name count samp unit min max sum sumsq
13941         local tmpfile=$TMP/$tfile.tmp
13942
13943         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13944         echo "stats before reset"
13945         stack_trap "rm -f $tmpfile"
13946         local now=$(date +%s)
13947
13948         $LCTL get_param osc.*.stats | tee $tmpfile
13949
13950         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13951         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13952         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13953         local uptime=$(awk '{ print $1 }' /proc/uptime)
13954
13955         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13956         (( ${snapshot_time%\.*} >= $now - 5 &&
13957            ${snapshot_time%\.*} <= $now + 5 )) ||
13958                 error "snapshot_time=$snapshot_time != now=$now"
13959         # elapsed _should_ be from mount, but at least less than uptime
13960         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13961                 error "elapsed=$elapsed > uptime=$uptime"
13962         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13963            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13964                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13965
13966         $LCTL set_param osc.*.stats=0
13967         local reset=$(date +%s)
13968         local fsize=$((2048 * 1024))
13969
13970         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13971         cancel_lru_locks osc
13972         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13973
13974         now=$(date +%s)
13975         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13976         while read name count samp unit min max sum sumsq; do
13977                 [[ "$samp" == "samples" ]] || continue
13978
13979                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13980                 [ ! $min ] && error "Missing min value for $name proc entry"
13981                 eval $name=$count || error "Wrong proc format"
13982
13983                 case $name in
13984                 read_bytes|write_bytes)
13985                         [[ "$unit" =~ "bytes" ]] ||
13986                                 error "unit is not 'bytes': $unit"
13987                         (( $min >= 4096 )) || error "min is too small: $min"
13988                         (( $min <= $fsize )) || error "min is too big: $min"
13989                         (( $max >= 4096 )) || error "max is too small: $max"
13990                         (( $max <= $fsize )) || error "max is too big: $max"
13991                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13992                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13993                                 error "sumsquare is too small: $sumsq"
13994                         (( $sumsq <= $fsize * $fsize )) ||
13995                                 error "sumsquare is too big: $sumsq"
13996                         ;;
13997                 ost_read|ost_write)
13998                         [[ "$unit" =~ "usec" ]] ||
13999                                 error "unit is not 'usec': $unit"
14000                         ;;
14001                 *)      ;;
14002                 esac
14003         done < $tmpfile
14004
14005         #check that we actually got some stats
14006         [ "$read_bytes" ] || error "Missing read_bytes stats"
14007         [ "$write_bytes" ] || error "Missing write_bytes stats"
14008         [ "$read_bytes" != 0 ] || error "no read done"
14009         [ "$write_bytes" != 0 ] || error "no write done"
14010
14011         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14012         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14013         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14014
14015         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14016         (( ${snapshot_time%\.*} >= $now - 5 &&
14017            ${snapshot_time%\.*} <= $now + 5 )) ||
14018                 error "reset snapshot_time=$snapshot_time != now=$now"
14019         # elapsed should be from time of stats reset
14020         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14021            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14022                 error "reset elapsed=$elapsed > $now - $reset"
14023         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14024            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14025                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14026 }
14027 run_test 127a "verify the client stats are sane"
14028
14029 test_127b() { # bug LU-333
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031         local name count samp unit min max sum sumsq
14032
14033         echo "stats before reset"
14034         $LCTL get_param llite.*.stats
14035         $LCTL set_param llite.*.stats=0
14036
14037         # perform 2 reads and writes so MAX is different from SUM.
14038         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14039         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14040         cancel_lru_locks osc
14041         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14042         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14043
14044         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14045         stack_trap "rm -f $TMP/$tfile.tmp"
14046         while read name count samp unit min max sum sumsq; do
14047                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14048                 eval $name=$count || error "Wrong proc format"
14049
14050                 case $name in
14051                 read_bytes|write_bytes)
14052                         [[ "$unit" =~ "bytes" ]] ||
14053                                 error "unit is not 'bytes': $unit"
14054                         (( $count == 2 )) || error "count is not 2: $count"
14055                         (( $min == $PAGE_SIZE )) ||
14056                                 error "min is not $PAGE_SIZE: $min"
14057                         (( $max == $PAGE_SIZE )) ||
14058                                 error "max is not $PAGE_SIZE: $max"
14059                         (( $sum == $PAGE_SIZE * 2 )) ||
14060                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14061                         ;;
14062                 read|write)
14063                         [[ "$unit" =~ "usec" ]] ||
14064                                 error "unit is not 'usec': $unit"
14065                         ;;
14066                 *)      ;;
14067                 esac
14068         done < $TMP/$tfile.tmp
14069
14070         #check that we actually got some stats
14071         [ "$read_bytes" ] || error "Missing read_bytes stats"
14072         [ "$write_bytes" ] || error "Missing write_bytes stats"
14073         [ "$read_bytes" != 0 ] || error "no read done"
14074         [ "$write_bytes" != 0 ] || error "no write done"
14075 }
14076 run_test 127b "verify the llite client stats are sane"
14077
14078 test_127c() { # LU-12394
14079         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14080         local size
14081         local bsize
14082         local reads
14083         local writes
14084         local count
14085
14086         $LCTL set_param llite.*.extents_stats=1
14087         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14088
14089         # Use two stripes so there is enough space in default config
14090         $LFS setstripe -c 2 $DIR/$tfile
14091
14092         # Extent stats start at 0-4K and go in power of two buckets
14093         # LL_HIST_START = 12 --> 2^12 = 4K
14094         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14095         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14096         # small configs
14097         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14098                 do
14099                 # Write and read, 2x each, second time at a non-zero offset
14100                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14101                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14102                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14103                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14104                 rm -f $DIR/$tfile
14105         done
14106
14107         $LCTL get_param llite.*.extents_stats
14108
14109         count=2
14110         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14111                 do
14112                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14113                                 grep -m 1 $bsize)
14114                 reads=$(echo $bucket | awk '{print $5}')
14115                 writes=$(echo $bucket | awk '{print $9}')
14116                 [ "$reads" -eq $count ] ||
14117                         error "$reads reads in < $bsize bucket, expect $count"
14118                 [ "$writes" -eq $count ] ||
14119                         error "$writes writes in < $bsize bucket, expect $count"
14120         done
14121
14122         # Test mmap write and read
14123         $LCTL set_param llite.*.extents_stats=c
14124         size=512
14125         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14126         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14127         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14128
14129         $LCTL get_param llite.*.extents_stats
14130
14131         count=$(((size*1024) / PAGE_SIZE))
14132
14133         bsize=$((2 * PAGE_SIZE / 1024))K
14134
14135         bucket=$($LCTL get_param -n llite.*.extents_stats |
14136                         grep -m 1 $bsize)
14137         reads=$(echo $bucket | awk '{print $5}')
14138         writes=$(echo $bucket | awk '{print $9}')
14139         # mmap writes fault in the page first, creating an additonal read
14140         [ "$reads" -eq $((2 * count)) ] ||
14141                 error "$reads reads in < $bsize bucket, expect $count"
14142         [ "$writes" -eq $count ] ||
14143                 error "$writes writes in < $bsize bucket, expect $count"
14144 }
14145 run_test 127c "test llite extent stats with regular & mmap i/o"
14146
14147 test_128() { # bug 15212
14148         touch $DIR/$tfile
14149         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14150                 find $DIR/$tfile
14151                 find $DIR/$tfile
14152         EOF
14153
14154         result=$(grep error $TMP/$tfile.log)
14155         rm -f $DIR/$tfile $TMP/$tfile.log
14156         [ -z "$result" ] ||
14157                 error "consecutive find's under interactive lfs failed"
14158 }
14159 run_test 128 "interactive lfs for 2 consecutive find's"
14160
14161 set_dir_limits () {
14162         local mntdev
14163         local canondev
14164         local node
14165
14166         local ldproc=/proc/fs/ldiskfs
14167         local facets=$(get_facets MDS)
14168
14169         for facet in ${facets//,/ }; do
14170                 canondev=$(ldiskfs_canon \
14171                            *.$(convert_facet2label $facet).mntdev $facet)
14172                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14173                         ldproc=/sys/fs/ldiskfs
14174                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14175                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14176         done
14177 }
14178
14179 check_mds_dmesg() {
14180         local facets=$(get_facets MDS)
14181         for facet in ${facets//,/ }; do
14182                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14183         done
14184         return 1
14185 }
14186
14187 test_129() {
14188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14189         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14190                 skip "Need MDS version with at least 2.5.56"
14191         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14192                 skip_env "ldiskfs only test"
14193         fi
14194         remote_mds_nodsh && skip "remote MDS with nodsh"
14195
14196         local ENOSPC=28
14197         local has_warning=false
14198
14199         rm -rf $DIR/$tdir
14200         mkdir -p $DIR/$tdir
14201
14202         # block size of mds1
14203         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14204         set_dir_limits $maxsize $((maxsize * 6 / 8))
14205         stack_trap "set_dir_limits 0 0"
14206         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14207         local dirsize=$(stat -c%s "$DIR/$tdir")
14208         local nfiles=0
14209         while (( $dirsize <= $maxsize )); do
14210                 $MCREATE $DIR/$tdir/file_base_$nfiles
14211                 rc=$?
14212                 # check two errors:
14213                 # ENOSPC for ext4 max_dir_size, which has been used since
14214                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14215                 if (( rc == ENOSPC )); then
14216                         set_dir_limits 0 0
14217                         echo "rc=$rc returned as expected after $nfiles files"
14218
14219                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14220                                 error "create failed w/o dir size limit"
14221
14222                         # messages may be rate limited if test is run repeatedly
14223                         check_mds_dmesg '"is approaching max"' ||
14224                                 echo "warning message should be output"
14225                         check_mds_dmesg '"has reached max"' ||
14226                                 echo "reached message should be output"
14227
14228                         dirsize=$(stat -c%s "$DIR/$tdir")
14229
14230                         [[ $dirsize -ge $maxsize ]] && return 0
14231                         error "dirsize $dirsize < $maxsize after $nfiles files"
14232                 elif (( rc != 0 )); then
14233                         break
14234                 fi
14235                 nfiles=$((nfiles + 1))
14236                 dirsize=$(stat -c%s "$DIR/$tdir")
14237         done
14238
14239         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14240 }
14241 run_test 129 "test directory size limit ========================"
14242
14243 OLDIFS="$IFS"
14244 cleanup_130() {
14245         trap 0
14246         IFS="$OLDIFS"
14247 }
14248
14249 test_130a() {
14250         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14251         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14252
14253         trap cleanup_130 EXIT RETURN
14254
14255         local fm_file=$DIR/$tfile
14256         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14257         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14258                 error "dd failed for $fm_file"
14259
14260         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14261         filefrag -ves $fm_file
14262         local rc=$?
14263         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14264                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14265         (( $rc == 0 )) || error "filefrag $fm_file failed"
14266
14267         filefrag_op=$(filefrag -ve -k $fm_file |
14268                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14269         local lun=$($LFS getstripe -i $fm_file)
14270
14271         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14272         IFS=$'\n'
14273         local tot_len=0
14274         for line in $filefrag_op; do
14275                 local frag_lun=$(echo $line | cut -d: -f5)
14276                 local ext_len=$(echo $line | cut -d: -f4)
14277
14278                 if (( $frag_lun != $lun )); then
14279                         error "FIEMAP on 1-stripe file($fm_file) failed"
14280                         return
14281                 fi
14282                 (( tot_len += ext_len ))
14283         done
14284
14285         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14286                 error "FIEMAP on 1-stripe file($fm_file) failed"
14287                 return
14288         fi
14289
14290         echo "FIEMAP on single striped file succeeded"
14291 }
14292 run_test 130a "FIEMAP (1-stripe file)"
14293
14294 test_130b() {
14295         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14296
14297         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14298         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14299         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14300                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14301
14302         trap cleanup_130 EXIT RETURN
14303
14304         local fm_file=$DIR/$tfile
14305         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14306                 error "setstripe on $fm_file"
14307
14308         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14309                 error "dd failed on $fm_file"
14310
14311         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14312         filefrag_op=$(filefrag -ve -k $fm_file |
14313                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14314
14315         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14316                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14317
14318         IFS=$'\n'
14319         local tot_len=0
14320         local num_luns=1
14321
14322         for line in $filefrag_op; do
14323                 local frag_lun=$(echo $line | cut -d: -f5 |
14324                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14325                 local ext_len=$(echo $line | cut -d: -f4)
14326                 if (( $frag_lun != $last_lun )); then
14327                         if (( tot_len != 1024 )); then
14328                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14329                                 return
14330                         else
14331                                 (( num_luns += 1 ))
14332                                 tot_len=0
14333                         fi
14334                 fi
14335                 (( tot_len += ext_len ))
14336                 last_lun=$frag_lun
14337         done
14338         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14339                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14340                 return
14341         fi
14342
14343         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14344 }
14345 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14346
14347 test_130c() {
14348         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14349
14350         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14351         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14352         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14353                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14354
14355         trap cleanup_130 EXIT RETURN
14356
14357         local fm_file=$DIR/$tfile
14358         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14359
14360         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14361                 error "dd failed on $fm_file"
14362
14363         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14364         filefrag_op=$(filefrag -ve -k $fm_file |
14365                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14366
14367         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14368                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14369
14370         IFS=$'\n'
14371         local tot_len=0
14372         local num_luns=1
14373         for line in $filefrag_op; do
14374                 local frag_lun=$(echo $line | cut -d: -f5 |
14375                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14376                 local ext_len=$(echo $line | cut -d: -f4)
14377                 if (( $frag_lun != $last_lun )); then
14378                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14379                         if (( logical != 512 )); then
14380                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14381                                 return
14382                         fi
14383                         if (( tot_len != 512 )); then
14384                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14385                                 return
14386                         else
14387                                 (( num_luns += 1 ))
14388                                 tot_len=0
14389                         fi
14390                 fi
14391                 (( tot_len += ext_len ))
14392                 last_lun=$frag_lun
14393         done
14394         if (( num_luns != 2 || tot_len != 512 )); then
14395                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14396                 return
14397         fi
14398
14399         echo "FIEMAP on 2-stripe file with hole succeeded"
14400 }
14401 run_test 130c "FIEMAP (2-stripe file with hole)"
14402
14403 test_130d() {
14404         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14405
14406         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14407         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14408         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14409                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14410
14411         trap cleanup_130 EXIT RETURN
14412
14413         local fm_file=$DIR/$tfile
14414         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14415                         error "setstripe on $fm_file"
14416
14417         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14418         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14419                 error "dd failed on $fm_file"
14420
14421         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14422         filefrag_op=$(filefrag -ve -k $fm_file |
14423                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14424
14425         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14426                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14427
14428         IFS=$'\n'
14429         local tot_len=0
14430         local num_luns=1
14431         for line in $filefrag_op; do
14432                 local frag_lun=$(echo $line | cut -d: -f5 |
14433                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14434                 local ext_len=$(echo $line | cut -d: -f4)
14435                 if (( $frag_lun != $last_lun )); then
14436                         if (( tot_len != 1024 )); then
14437                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14438                                 return
14439                         else
14440                                 (( num_luns += 1 ))
14441                                 local tot_len=0
14442                         fi
14443                 fi
14444                 (( tot_len += ext_len ))
14445                 last_lun=$frag_lun
14446         done
14447         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14448                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14449                 return
14450         fi
14451
14452         echo "FIEMAP on N-stripe file succeeded"
14453 }
14454 run_test 130d "FIEMAP (N-stripe file)"
14455
14456 test_130e() {
14457         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14458
14459         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14460         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14461         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14462                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14463
14464         trap cleanup_130 EXIT RETURN
14465
14466         local fm_file=$DIR/$tfile
14467         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14468
14469         local num_blks=512
14470         local expected_len=$(( (num_blks / 2) * 64 ))
14471         for ((i = 0; i < $num_blks; i++)); do
14472                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14473                         conv=notrunc > /dev/null 2>&1
14474         done
14475
14476         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14477         filefrag_op=$(filefrag -ve -k $fm_file |
14478                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14479
14480         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14481
14482         IFS=$'\n'
14483         local tot_len=0
14484         local num_luns=1
14485         for line in $filefrag_op; do
14486                 local frag_lun=$(echo $line | cut -d: -f5)
14487                 local ext_len=$(echo $line | cut -d: -f4)
14488                 if (( $frag_lun != $last_lun )); then
14489                         if (( tot_len != $expected_len )); then
14490                                 error "OST$last_lun $tot_len != $expected_len"
14491                         else
14492                                 (( num_luns += 1 ))
14493                                 tot_len=0
14494                         fi
14495                 fi
14496                 (( tot_len += ext_len ))
14497                 last_lun=$frag_lun
14498         done
14499         if (( num_luns != 2 || tot_len != $expected_len )); then
14500                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14501         fi
14502
14503         echo "FIEMAP with continuation calls succeeded"
14504 }
14505 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14506
14507 test_130f() {
14508         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14509         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14510         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14511                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14512
14513         local fm_file=$DIR/$tfile
14514         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14515                 error "multiop create with lov_delay_create on $fm_file"
14516
14517         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14518         filefrag_extents=$(filefrag -vek $fm_file |
14519                            awk '/extents? found/ { print $2 }')
14520         if (( $filefrag_extents != 0 )); then
14521                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14522         fi
14523
14524         rm -f $fm_file
14525 }
14526 run_test 130f "FIEMAP (unstriped file)"
14527
14528 test_130g() {
14529         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14530                 skip "Need MDS version with at least 2.12.53 for overstriping"
14531         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14532         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14533         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14534                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14535
14536         local file=$DIR/$tfile
14537         local nr=$((OSTCOUNT * 100))
14538
14539         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14540
14541         stack_trap "rm -f $file"
14542         dd if=/dev/zero of=$file count=$nr bs=1M
14543         sync
14544         nr=$($LFS getstripe -c $file)
14545
14546         local extents=$(filefrag -v $file |
14547                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14548
14549         echo "filefrag list $extents extents in file with stripecount $nr"
14550         if (( extents < nr )); then
14551                 $LFS getstripe $file
14552                 filefrag -v $file
14553                 error "filefrag printed $extents < $nr extents"
14554         fi
14555 }
14556 run_test 130g "FIEMAP (overstripe file)"
14557
14558 # Test for writev/readv
14559 test_131a() {
14560         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14561                 error "writev test failed"
14562         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14563                 error "readv failed"
14564         rm -f $DIR/$tfile
14565 }
14566 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14567
14568 test_131b() {
14569         local fsize=$((524288 + 1048576 + 1572864))
14570         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14571                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14572                         error "append writev test failed"
14573
14574         ((fsize += 1572864 + 1048576))
14575         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14576                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14577                         error "append writev test failed"
14578         rm -f $DIR/$tfile
14579 }
14580 run_test 131b "test append writev"
14581
14582 test_131c() {
14583         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14584         error "NOT PASS"
14585 }
14586 run_test 131c "test read/write on file w/o objects"
14587
14588 test_131d() {
14589         rwv -f $DIR/$tfile -w -n 1 1572864
14590         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14591         if [ "$NOB" != 1572864 ]; then
14592                 error "Short read filed: read $NOB bytes instead of 1572864"
14593         fi
14594         rm -f $DIR/$tfile
14595 }
14596 run_test 131d "test short read"
14597
14598 test_131e() {
14599         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14600         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14601         error "read hitting hole failed"
14602         rm -f $DIR/$tfile
14603 }
14604 run_test 131e "test read hitting hole"
14605
14606 check_stats() {
14607         local facet=$1
14608         local op=$2
14609         local want=${3:-0}
14610         local res
14611
14612         # open             11 samples [usecs] 468 4793 13658 35791898
14613         case $facet in
14614         mds*) res=($(do_facet $facet \
14615                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14616                  ;;
14617         ost*) res=($(do_facet $facet \
14618                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14619                  ;;
14620         *) error "Wrong facet '$facet'" ;;
14621         esac
14622         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14623         # if $want is zero, it means any stat increment is ok.
14624         if (( $want > 0 )); then
14625                 local count=${res[1]}
14626
14627                 if (( $count != $want )); then
14628                         if [[ $facet =~ "mds" ]]; then
14629                                 do_nodes $(comma_list $(mdts_nodes)) \
14630                                         $LCTL get_param mdt.*.md_stats
14631                         else
14632                                 do_nodes $(comma_list $(osts-nodes)) \
14633                                         $LCTL get_param obdfilter.*.stats
14634                         fi
14635                         error "The $op counter on $facet is $count, not $want"
14636                 fi
14637         fi
14638 }
14639
14640 test_133a() {
14641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14642         remote_ost_nodsh && skip "remote OST with nodsh"
14643         remote_mds_nodsh && skip "remote MDS with nodsh"
14644         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14645                 skip_env "MDS doesn't support rename stats"
14646
14647         local testdir=$DIR/${tdir}/stats_testdir
14648
14649         mkdir -p $DIR/${tdir}
14650
14651         # clear stats.
14652         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14653         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14654
14655         # verify mdt stats first.
14656         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14657         check_stats $SINGLEMDS "mkdir" 1
14658
14659         # clear "open" from "lfs mkdir" above
14660         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14661         touch ${testdir}/${tfile} || error "touch failed"
14662         check_stats $SINGLEMDS "open" 1
14663         check_stats $SINGLEMDS "close" 1
14664         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14665                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14666                 check_stats $SINGLEMDS "mknod" 2
14667         }
14668         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14669         check_stats $SINGLEMDS "unlink" 1
14670         rm -f ${testdir}/${tfile} || error "file remove failed"
14671         check_stats $SINGLEMDS "unlink" 2
14672
14673         # remove working dir and check mdt stats again.
14674         rmdir ${testdir} || error "rmdir failed"
14675         check_stats $SINGLEMDS "rmdir" 1
14676
14677         local testdir1=$DIR/${tdir}/stats_testdir1
14678         mkdir_on_mdt0 -p ${testdir}
14679         mkdir_on_mdt0 -p ${testdir1}
14680         touch ${testdir1}/test1
14681         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14682         check_stats $SINGLEMDS "crossdir_rename" 1
14683
14684         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14685         check_stats $SINGLEMDS "samedir_rename" 1
14686
14687         rm -rf $DIR/${tdir}
14688 }
14689 run_test 133a "Verifying MDT stats ========================================"
14690
14691 test_133b() {
14692         local res
14693
14694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14695         remote_ost_nodsh && skip "remote OST with nodsh"
14696         remote_mds_nodsh && skip "remote MDS with nodsh"
14697
14698         local testdir=$DIR/${tdir}/stats_testdir
14699
14700         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14701         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14702         touch ${testdir}/${tfile} || error "touch failed"
14703         cancel_lru_locks mdc
14704
14705         # clear stats.
14706         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14707         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14708
14709         # extra mdt stats verification.
14710         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14711         check_stats $SINGLEMDS "setattr" 1
14712         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14713         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14714         then            # LU-1740
14715                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14716                 check_stats $SINGLEMDS "getattr" 1
14717         fi
14718         rm -rf $DIR/${tdir}
14719
14720         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14721         # so the check below is not reliable
14722         [ $MDSCOUNT -eq 1 ] || return 0
14723
14724         # Sleep to avoid a cached response.
14725         #define OBD_STATFS_CACHE_SECONDS 1
14726         sleep 2
14727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14728         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14729         $LFS df || error "lfs failed"
14730         check_stats $SINGLEMDS "statfs" 1
14731
14732         # check aggregated statfs (LU-10018)
14733         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14734                 return 0
14735         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14736                 return 0
14737         sleep 2
14738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14739         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14740         df $DIR
14741         check_stats $SINGLEMDS "statfs" 1
14742
14743         # We want to check that the client didn't send OST_STATFS to
14744         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14745         # extra care is needed here.
14746         if remote_mds; then
14747                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14748                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14749
14750                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14751                 [ "$res" ] && error "OST got STATFS"
14752         fi
14753
14754         return 0
14755 }
14756 run_test 133b "Verifying extra MDT stats =================================="
14757
14758 test_133c() {
14759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14760         remote_ost_nodsh && skip "remote OST with nodsh"
14761         remote_mds_nodsh && skip "remote MDS with nodsh"
14762
14763         local testdir=$DIR/$tdir/stats_testdir
14764
14765         test_mkdir -p $testdir
14766
14767         # verify obdfilter stats.
14768         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14769         sync
14770         cancel_lru_locks osc
14771         wait_delete_completed
14772
14773         # clear stats.
14774         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14775         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14776
14777         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14778                 error "dd failed"
14779         sync
14780         cancel_lru_locks osc
14781         check_stats ost1 "write" 1
14782
14783         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14784         check_stats ost1 "read" 1
14785
14786         > $testdir/$tfile || error "truncate failed"
14787         check_stats ost1 "punch" 1
14788
14789         rm -f $testdir/$tfile || error "file remove failed"
14790         wait_delete_completed
14791         check_stats ost1 "destroy" 1
14792
14793         rm -rf $DIR/$tdir
14794 }
14795 run_test 133c "Verifying OST stats ========================================"
14796
14797 order_2() {
14798         local value=$1
14799         local orig=$value
14800         local order=1
14801
14802         while [ $value -ge 2 ]; do
14803                 order=$((order*2))
14804                 value=$((value/2))
14805         done
14806
14807         if [ $orig -gt $order ]; then
14808                 order=$((order*2))
14809         fi
14810         echo $order
14811 }
14812
14813 size_in_KMGT() {
14814     local value=$1
14815     local size=('K' 'M' 'G' 'T');
14816     local i=0
14817     local size_string=$value
14818
14819     while [ $value -ge 1024 ]; do
14820         if [ $i -gt 3 ]; then
14821             #T is the biggest unit we get here, if that is bigger,
14822             #just return XXXT
14823             size_string=${value}T
14824             break
14825         fi
14826         value=$((value >> 10))
14827         if [ $value -lt 1024 ]; then
14828             size_string=${value}${size[$i]}
14829             break
14830         fi
14831         i=$((i + 1))
14832     done
14833
14834     echo $size_string
14835 }
14836
14837 get_rename_size() {
14838         local size=$1
14839         local context=${2:-.}
14840         local sample=$(do_facet $SINGLEMDS $LCTL \
14841                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14842                 grep -A1 $context |
14843                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14844         echo $sample
14845 }
14846
14847 test_133d() {
14848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14849         remote_ost_nodsh && skip "remote OST with nodsh"
14850         remote_mds_nodsh && skip "remote MDS with nodsh"
14851         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14852                 skip_env "MDS doesn't support rename stats"
14853
14854         local testdir1=$DIR/${tdir}/stats_testdir1
14855         local testdir2=$DIR/${tdir}/stats_testdir2
14856         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14857
14858         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14859
14860         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14861         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14862
14863         createmany -o $testdir1/test 512 || error "createmany failed"
14864
14865         # check samedir rename size
14866         mv ${testdir1}/test0 ${testdir1}/test_0
14867
14868         local testdir1_size=$(ls -l $DIR/${tdir} |
14869                 awk '/stats_testdir1/ {print $5}')
14870         local testdir2_size=$(ls -l $DIR/${tdir} |
14871                 awk '/stats_testdir2/ {print $5}')
14872
14873         testdir1_size=$(order_2 $testdir1_size)
14874         testdir2_size=$(order_2 $testdir2_size)
14875
14876         testdir1_size=$(size_in_KMGT $testdir1_size)
14877         testdir2_size=$(size_in_KMGT $testdir2_size)
14878
14879         echo "source rename dir size: ${testdir1_size}"
14880         echo "target rename dir size: ${testdir2_size}"
14881
14882         local cmd="do_facet $SINGLEMDS $LCTL "
14883         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14884
14885         eval $cmd || error "$cmd failed"
14886         local samedir=$($cmd | grep 'same_dir')
14887         local same_sample=$(get_rename_size $testdir1_size)
14888         [ -z "$samedir" ] && error "samedir_rename_size count error"
14889         [[ $same_sample -eq 1 ]] ||
14890                 error "samedir_rename_size error $same_sample"
14891         echo "Check same dir rename stats success"
14892
14893         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14894
14895         # check crossdir rename size
14896         mv ${testdir1}/test_0 ${testdir2}/test_0
14897
14898         testdir1_size=$(ls -l $DIR/${tdir} |
14899                 awk '/stats_testdir1/ {print $5}')
14900         testdir2_size=$(ls -l $DIR/${tdir} |
14901                 awk '/stats_testdir2/ {print $5}')
14902
14903         testdir1_size=$(order_2 $testdir1_size)
14904         testdir2_size=$(order_2 $testdir2_size)
14905
14906         testdir1_size=$(size_in_KMGT $testdir1_size)
14907         testdir2_size=$(size_in_KMGT $testdir2_size)
14908
14909         echo "source rename dir size: ${testdir1_size}"
14910         echo "target rename dir size: ${testdir2_size}"
14911
14912         eval $cmd || error "$cmd failed"
14913         local crossdir=$($cmd | grep 'crossdir')
14914         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14915         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14916         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14917         [[ $src_sample -eq 1 ]] ||
14918                 error "crossdir_rename_size error $src_sample"
14919         [[ $tgt_sample -eq 1 ]] ||
14920                 error "crossdir_rename_size error $tgt_sample"
14921         echo "Check cross dir rename stats success"
14922         rm -rf $DIR/${tdir}
14923 }
14924 run_test 133d "Verifying rename_stats ========================================"
14925
14926 test_133e() {
14927         remote_mds_nodsh && skip "remote MDS with nodsh"
14928         remote_ost_nodsh && skip "remote OST with nodsh"
14929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14930
14931         local testdir=$DIR/${tdir}/stats_testdir
14932         local ctr f0 f1 bs=32768 count=42 sum
14933
14934         mkdir -p ${testdir} || error "mkdir failed"
14935
14936         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14937
14938         for ctr in {write,read}_bytes; do
14939                 sync
14940                 cancel_lru_locks osc
14941
14942                 do_facet ost1 $LCTL set_param -n \
14943                         "obdfilter.*.exports.clear=clear"
14944
14945                 if [ $ctr = write_bytes ]; then
14946                         f0=/dev/zero
14947                         f1=${testdir}/${tfile}
14948                 else
14949                         f0=${testdir}/${tfile}
14950                         f1=/dev/null
14951                 fi
14952
14953                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14954                         error "dd failed"
14955                 sync
14956                 cancel_lru_locks osc
14957
14958                 sum=$(do_facet ost1 $LCTL get_param \
14959                         "obdfilter.*.exports.*.stats" |
14960                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14961                                 $1 == ctr { sum += $7 }
14962                                 END { printf("%0.0f", sum) }')
14963
14964                 if ((sum != bs * count)); then
14965                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14966                 fi
14967         done
14968
14969         rm -rf $DIR/${tdir}
14970 }
14971 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14972
14973 test_133f() {
14974         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14975                 skip "too old lustre for get_param -R ($facet_ver)"
14976
14977         # verifying readability.
14978         $LCTL get_param -R '*' &> /dev/null
14979
14980         # Verifing writability with badarea_io.
14981         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14982         local skipped_params='force_lbug|changelog_mask|daemon_file'
14983         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14984                 egrep -v "$skipped_params" |
14985                 xargs -n 1 find $proc_dirs -name |
14986                 xargs -n 1 badarea_io ||
14987                 error "client badarea_io failed"
14988
14989         # remount the FS in case writes/reads /proc break the FS
14990         cleanup || error "failed to unmount"
14991         setup || error "failed to setup"
14992 }
14993 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14994
14995 test_133g() {
14996         remote_mds_nodsh && skip "remote MDS with nodsh"
14997         remote_ost_nodsh && skip "remote OST with nodsh"
14998
14999         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15000         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15001         local facet
15002         for facet in mds1 ost1; do
15003                 local facet_ver=$(lustre_version_code $facet)
15004                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15005                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15006                 else
15007                         log "$facet: too old lustre for get_param -R"
15008                 fi
15009                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15010                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15011                                 tr -d = | egrep -v $skipped_params |
15012                                 xargs -n 1 find $proc_dirs -name |
15013                                 xargs -n 1 badarea_io" ||
15014                                         error "$facet badarea_io failed"
15015                 else
15016                         skip_noexit "$facet: too old lustre for get_param -R"
15017                 fi
15018         done
15019
15020         # remount the FS in case writes/reads /proc break the FS
15021         cleanup || error "failed to unmount"
15022         setup || error "failed to setup"
15023 }
15024 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15025
15026 test_133h() {
15027         remote_mds_nodsh && skip "remote MDS with nodsh"
15028         remote_ost_nodsh && skip "remote OST with nodsh"
15029         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15030                 skip "Need MDS version at least 2.9.54"
15031
15032         local facet
15033         for facet in client mds1 ost1; do
15034                 # Get the list of files that are missing the terminating newline
15035                 local plist=$(do_facet $facet
15036                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15037                 local ent
15038                 for ent in $plist; do
15039                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15040                                 awk -v FS='\v' -v RS='\v\v' \
15041                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15042                                         print FILENAME}'" 2>/dev/null)
15043                         [ -z $missing ] || {
15044                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15045                                 error "file does not end with newline: $facet-$ent"
15046                         }
15047                 done
15048         done
15049 }
15050 run_test 133h "Proc files should end with newlines"
15051
15052 test_134a() {
15053         remote_mds_nodsh && skip "remote MDS with nodsh"
15054         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15055                 skip "Need MDS version at least 2.7.54"
15056
15057         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15058         cancel_lru_locks mdc
15059
15060         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15061         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15062         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15063
15064         local nr=1000
15065         createmany -o $DIR/$tdir/f $nr ||
15066                 error "failed to create $nr files in $DIR/$tdir"
15067         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15068
15069         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15070         do_facet mds1 $LCTL set_param fail_loc=0x327
15071         do_facet mds1 $LCTL set_param fail_val=500
15072         touch $DIR/$tdir/m
15073
15074         echo "sleep 10 seconds ..."
15075         sleep 10
15076         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15077
15078         do_facet mds1 $LCTL set_param fail_loc=0
15079         do_facet mds1 $LCTL set_param fail_val=0
15080         [ $lck_cnt -lt $unused ] ||
15081                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15082
15083         rm $DIR/$tdir/m
15084         unlinkmany $DIR/$tdir/f $nr
15085 }
15086 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15087
15088 test_134b() {
15089         remote_mds_nodsh && skip "remote MDS with nodsh"
15090         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15091                 skip "Need MDS version at least 2.7.54"
15092
15093         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15094         cancel_lru_locks mdc
15095
15096         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15097                         ldlm.lock_reclaim_threshold_mb)
15098         # disable reclaim temporarily
15099         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15100
15101         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15102         do_facet mds1 $LCTL set_param fail_loc=0x328
15103         do_facet mds1 $LCTL set_param fail_val=500
15104
15105         $LCTL set_param debug=+trace
15106
15107         local nr=600
15108         createmany -o $DIR/$tdir/f $nr &
15109         local create_pid=$!
15110
15111         echo "Sleep $TIMEOUT seconds ..."
15112         sleep $TIMEOUT
15113         if ! ps -p $create_pid  > /dev/null 2>&1; then
15114                 do_facet mds1 $LCTL set_param fail_loc=0
15115                 do_facet mds1 $LCTL set_param fail_val=0
15116                 do_facet mds1 $LCTL set_param \
15117                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15118                 error "createmany finished incorrectly!"
15119         fi
15120         do_facet mds1 $LCTL set_param fail_loc=0
15121         do_facet mds1 $LCTL set_param fail_val=0
15122         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15123         wait $create_pid || return 1
15124
15125         unlinkmany $DIR/$tdir/f $nr
15126 }
15127 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15128
15129 test_135() {
15130         remote_mds_nodsh && skip "remote MDS with nodsh"
15131         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15132                 skip "Need MDS version at least 2.13.50"
15133         local fname
15134
15135         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15136
15137 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15138         #set only one record at plain llog
15139         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15140
15141         #fill already existed plain llog each 64767
15142         #wrapping whole catalog
15143         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15144
15145         createmany -o $DIR/$tdir/$tfile_ 64700
15146         for (( i = 0; i < 64700; i = i + 2 ))
15147         do
15148                 rm $DIR/$tdir/$tfile_$i &
15149                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15150                 local pid=$!
15151                 wait $pid
15152         done
15153
15154         #waiting osp synchronization
15155         wait_delete_completed
15156 }
15157 run_test 135 "Race catalog processing"
15158
15159 test_136() {
15160         remote_mds_nodsh && skip "remote MDS with nodsh"
15161         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15162                 skip "Need MDS version at least 2.13.50"
15163         local fname
15164
15165         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15166         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15167         #set only one record at plain llog
15168 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15169         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15170
15171         #fill already existed 2 plain llogs each 64767
15172         #wrapping whole catalog
15173         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15174         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15175         wait_delete_completed
15176
15177         createmany -o $DIR/$tdir/$tfile_ 10
15178         sleep 25
15179
15180         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15181         for (( i = 0; i < 10; i = i + 3 ))
15182         do
15183                 rm $DIR/$tdir/$tfile_$i &
15184                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15185                 local pid=$!
15186                 wait $pid
15187                 sleep 7
15188                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15189         done
15190
15191         #waiting osp synchronization
15192         wait_delete_completed
15193 }
15194 run_test 136 "Race catalog processing 2"
15195
15196 test_140() { #bug-17379
15197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15198
15199         test_mkdir $DIR/$tdir
15200         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15201         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15202
15203         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15204         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15205         local i=0
15206         while i=$((i + 1)); do
15207                 test_mkdir $i
15208                 cd $i || error "Changing to $i"
15209                 ln -s ../stat stat || error "Creating stat symlink"
15210                 # Read the symlink until ELOOP present,
15211                 # not LBUGing the system is considered success,
15212                 # we didn't overrun the stack.
15213                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15214                 if [ $ret -ne 0 ]; then
15215                         if [ $ret -eq 40 ]; then
15216                                 break  # -ELOOP
15217                         else
15218                                 error "Open stat symlink"
15219                                         return
15220                         fi
15221                 fi
15222         done
15223         i=$((i - 1))
15224         echo "The symlink depth = $i"
15225         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15226                 error "Invalid symlink depth"
15227
15228         # Test recursive symlink
15229         ln -s symlink_self symlink_self
15230         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15231         echo "open symlink_self returns $ret"
15232         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15233 }
15234 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15235
15236 test_150a() {
15237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15238
15239         local TF="$TMP/$tfile"
15240
15241         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15242         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15243         cp $TF $DIR/$tfile
15244         cancel_lru_locks $OSC
15245         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15246         remount_client $MOUNT
15247         df -P $MOUNT
15248         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15249
15250         $TRUNCATE $TF 6000
15251         $TRUNCATE $DIR/$tfile 6000
15252         cancel_lru_locks $OSC
15253         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15254
15255         echo "12345" >>$TF
15256         echo "12345" >>$DIR/$tfile
15257         cancel_lru_locks $OSC
15258         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15259
15260         echo "12345" >>$TF
15261         echo "12345" >>$DIR/$tfile
15262         cancel_lru_locks $OSC
15263         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15264 }
15265 run_test 150a "truncate/append tests"
15266
15267 test_150b() {
15268         check_set_fallocate_or_skip
15269         local out
15270
15271         touch $DIR/$tfile
15272         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15273         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15274                 skip_eopnotsupp "$out|check_fallocate failed"
15275 }
15276 run_test 150b "Verify fallocate (prealloc) functionality"
15277
15278 test_150bb() {
15279         check_set_fallocate_or_skip
15280
15281         touch $DIR/$tfile
15282         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15283         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15284         > $DIR/$tfile
15285         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15286         # precomputed md5sum for 20MB of zeroes
15287         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15288         local sum=($(md5sum $DIR/$tfile))
15289
15290         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15291
15292         check_set_fallocate 1
15293
15294         > $DIR/$tfile
15295         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15296         sum=($(md5sum $DIR/$tfile))
15297
15298         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15299 }
15300 run_test 150bb "Verify fallocate modes both zero space"
15301
15302 test_150c() {
15303         check_set_fallocate_or_skip
15304         local striping="-c2"
15305
15306         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15307         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15308         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15309         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15310         local want=$((OSTCOUNT * 1048576))
15311
15312         # Must allocate all requested space, not more than 5% extra
15313         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15314                 error "bytes $bytes is not $want"
15315
15316         rm -f $DIR/$tfile
15317
15318         echo "verify fallocate on PFL file"
15319
15320         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15321
15322         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15323                 error "Create $DIR/$tfile failed"
15324         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15325         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15326         want=$((512 * 1048576))
15327
15328         # Must allocate all requested space, not more than 5% extra
15329         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15330                 error "bytes $bytes is not $want"
15331 }
15332 run_test 150c "Verify fallocate Size and Blocks"
15333
15334 test_150d() {
15335         check_set_fallocate_or_skip
15336         local striping="-c2"
15337
15338         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15339
15340         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15341         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15342                 error "setstripe failed"
15343         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15344         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15345         local want=$((OSTCOUNT * 1048576))
15346
15347         # Must allocate all requested space, not more than 5% extra
15348         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15349                 error "bytes $bytes is not $want"
15350 }
15351 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15352
15353 test_150e() {
15354         check_set_fallocate_or_skip
15355
15356         echo "df before:"
15357         $LFS df
15358         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15359         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15360                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15361
15362         # Find OST with Minimum Size
15363         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15364                        sort -un | head -1)
15365
15366         # Get 100MB per OST of the available space to reduce run time
15367         # else 60% of the available space if we are running SLOW tests
15368         if [ $SLOW == "no" ]; then
15369                 local space=$((1024 * 100 * OSTCOUNT))
15370         else
15371                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15372         fi
15373
15374         fallocate -l${space}k $DIR/$tfile ||
15375                 error "fallocate ${space}k $DIR/$tfile failed"
15376         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15377
15378         # get size immediately after fallocate. This should be correctly
15379         # updated
15380         local size=$(stat -c '%s' $DIR/$tfile)
15381         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15382
15383         # Sleep for a while for statfs to get updated. And not pull from cache.
15384         sleep 2
15385
15386         echo "df after fallocate:"
15387         $LFS df
15388
15389         (( size / 1024 == space )) || error "size $size != requested $space"
15390         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15391                 error "used $used < space $space"
15392
15393         rm $DIR/$tfile || error "rm failed"
15394         sync
15395         wait_delete_completed
15396
15397         echo "df after unlink:"
15398         $LFS df
15399 }
15400 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15401
15402 test_150f() {
15403         local size
15404         local blocks
15405         local want_size_before=20480 # in bytes
15406         local want_blocks_before=40 # 512 sized blocks
15407         local want_blocks_after=24  # 512 sized blocks
15408         local length=$(((want_blocks_before - want_blocks_after) * 512))
15409
15410         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15411                 skip "need at least 2.14.0 for fallocate punch"
15412
15413         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15414                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15415         fi
15416
15417         check_set_fallocate_or_skip
15418         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15419
15420         [[ "x$DOM" == "xyes" ]] &&
15421                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15422
15423         echo "Verify fallocate punch: Range within the file range"
15424         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15425                 error "dd failed for bs 4096 and count 5"
15426
15427         # Call fallocate with punch range which is within the file range
15428         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15429                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15430         # client must see changes immediately after fallocate
15431         size=$(stat -c '%s' $DIR/$tfile)
15432         blocks=$(stat -c '%b' $DIR/$tfile)
15433
15434         # Verify punch worked.
15435         (( blocks == want_blocks_after )) ||
15436                 error "punch failed: blocks $blocks != $want_blocks_after"
15437
15438         (( size == want_size_before )) ||
15439                 error "punch failed: size $size != $want_size_before"
15440
15441         # Verify there is hole in file
15442         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15443         # precomputed md5sum
15444         local expect="4a9a834a2db02452929c0a348273b4aa"
15445
15446         cksum=($(md5sum $DIR/$tfile))
15447         [[ "${cksum[0]}" == "$expect" ]] ||
15448                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15449
15450         # Start second sub-case for fallocate punch.
15451         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15452         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15453                 error "dd failed for bs 4096 and count 5"
15454
15455         # Punch range less than block size will have no change in block count
15456         want_blocks_after=40  # 512 sized blocks
15457
15458         # Punch overlaps two blocks and less than blocksize
15459         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15460                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15461         size=$(stat -c '%s' $DIR/$tfile)
15462         blocks=$(stat -c '%b' $DIR/$tfile)
15463
15464         # Verify punch worked.
15465         (( blocks == want_blocks_after )) ||
15466                 error "punch failed: blocks $blocks != $want_blocks_after"
15467
15468         (( size == want_size_before )) ||
15469                 error "punch failed: size $size != $want_size_before"
15470
15471         # Verify if range is really zero'ed out. We expect Zeros.
15472         # precomputed md5sum
15473         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15474         cksum=($(md5sum $DIR/$tfile))
15475         [[ "${cksum[0]}" == "$expect" ]] ||
15476                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15477 }
15478 run_test 150f "Verify fallocate punch functionality"
15479
15480 test_150g() {
15481         local space
15482         local size
15483         local blocks
15484         local blocks_after
15485         local size_after
15486         local BS=4096 # Block size in bytes
15487
15488         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15489                 skip "need at least 2.14.0 for fallocate punch"
15490
15491         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15492                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15493         fi
15494
15495         check_set_fallocate_or_skip
15496         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15497
15498         if [[ "x$DOM" == "xyes" ]]; then
15499                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15500                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15501         else
15502                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15503                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15504         fi
15505
15506         # Get 100MB per OST of the available space to reduce run time
15507         # else 60% of the available space if we are running SLOW tests
15508         if [ $SLOW == "no" ]; then
15509                 space=$((1024 * 100 * OSTCOUNT))
15510         else
15511                 # Find OST with Minimum Size
15512                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15513                         sort -un | head -1)
15514                 echo "min size OST: $space"
15515                 space=$(((space * 60)/100 * OSTCOUNT))
15516         fi
15517         # space in 1k units, round to 4k blocks
15518         local blkcount=$((space * 1024 / $BS))
15519
15520         echo "Verify fallocate punch: Very large Range"
15521         fallocate -l${space}k $DIR/$tfile ||
15522                 error "fallocate ${space}k $DIR/$tfile failed"
15523         # write 1M at the end, start and in the middle
15524         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15525                 error "dd failed: bs $BS count 256"
15526         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15527                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15528         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15529                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15530
15531         # Gather stats.
15532         size=$(stat -c '%s' $DIR/$tfile)
15533
15534         # gather punch length.
15535         local punch_size=$((size - (BS * 2)))
15536
15537         echo "punch_size = $punch_size"
15538         echo "size - punch_size: $((size - punch_size))"
15539         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15540
15541         # Call fallocate to punch all except 2 blocks. We leave the
15542         # first and the last block
15543         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15544         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15545                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15546
15547         size_after=$(stat -c '%s' $DIR/$tfile)
15548         blocks_after=$(stat -c '%b' $DIR/$tfile)
15549
15550         # Verify punch worked.
15551         # Size should be kept
15552         (( size == size_after )) ||
15553                 error "punch failed: size $size != $size_after"
15554
15555         # two 4k data blocks to remain plus possible 1 extra extent block
15556         (( blocks_after <= ((BS / 512) * 3) )) ||
15557                 error "too many blocks remains: $blocks_after"
15558
15559         # Verify that file has hole between the first and the last blocks
15560         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15561         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15562
15563         echo "Hole at [$hole_start, $hole_end)"
15564         (( hole_start == BS )) ||
15565                 error "no hole at offset $BS after punch"
15566
15567         (( hole_end == BS + punch_size )) ||
15568                 error "data at offset $hole_end < $((BS + punch_size))"
15569 }
15570 run_test 150g "Verify fallocate punch on large range"
15571
15572 test_150h() {
15573         local file=$DIR/$tfile
15574         local size
15575
15576         check_set_fallocate_or_skip
15577         statx_supported || skip_env "Test must be statx() syscall supported"
15578
15579         # fallocate() does not update the size information on the MDT
15580         fallocate -l 16K $file || error "failed to fallocate $file"
15581         cancel_lru_locks $OSC
15582         # STATX with cached-always mode will not send glimpse RPCs to OST,
15583         # it uses the caching attrs on the client side as much as possible.
15584         size=$($STATX --cached=always -c %s $file)
15585         [ $size == 16384 ] ||
15586                 error "size after fallocate() is $size, expected 16384"
15587 }
15588 run_test 150h "Verify extend fallocate updates the file size"
15589
15590 #LU-2902 roc_hit was not able to read all values from lproc
15591 function roc_hit_init() {
15592         local list=$(comma_list $(osts_nodes))
15593         local dir=$DIR/$tdir-check
15594         local file=$dir/$tfile
15595         local BEFORE
15596         local AFTER
15597         local idx
15598
15599         test_mkdir $dir
15600         #use setstripe to do a write to every ost
15601         for i in $(seq 0 $((OSTCOUNT-1))); do
15602                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15603                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15604                 idx=$(printf %04x $i)
15605                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15606                         awk '$1 == "cache_access" {sum += $7}
15607                                 END { printf("%0.0f", sum) }')
15608
15609                 cancel_lru_locks osc
15610                 cat $file >/dev/null
15611
15612                 AFTER=$(get_osd_param $list *OST*$idx stats |
15613                         awk '$1 == "cache_access" {sum += $7}
15614                                 END { printf("%0.0f", sum) }')
15615
15616                 echo BEFORE:$BEFORE AFTER:$AFTER
15617                 if ! let "AFTER - BEFORE == 4"; then
15618                         rm -rf $dir
15619                         error "roc_hit is not safe to use"
15620                 fi
15621                 rm $file
15622         done
15623
15624         rm -rf $dir
15625 }
15626
15627 function roc_hit() {
15628         local list=$(comma_list $(osts_nodes))
15629         echo $(get_osd_param $list '' stats |
15630                 awk '$1 == "cache_hit" {sum += $7}
15631                         END { printf("%0.0f", sum) }')
15632 }
15633
15634 function set_cache() {
15635         local on=1
15636
15637         if [ "$2" == "off" ]; then
15638                 on=0;
15639         fi
15640         local list=$(comma_list $(osts_nodes))
15641         set_osd_param $list '' $1_cache_enable $on
15642
15643         cancel_lru_locks osc
15644 }
15645
15646 test_151() {
15647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15648         remote_ost_nodsh && skip "remote OST with nodsh"
15649
15650         local CPAGES=3
15651         local list=$(comma_list $(osts_nodes))
15652
15653         # check whether obdfilter is cache capable at all
15654         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15655                 skip "not cache-capable obdfilter"
15656         fi
15657
15658         # check cache is enabled on all obdfilters
15659         if get_osd_param $list '' read_cache_enable | grep 0; then
15660                 skip "oss cache is disabled"
15661         fi
15662
15663         set_osd_param $list '' writethrough_cache_enable 1
15664
15665         # check write cache is enabled on all obdfilters
15666         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15667                 skip "oss write cache is NOT enabled"
15668         fi
15669
15670         roc_hit_init
15671
15672         #define OBD_FAIL_OBD_NO_LRU  0x609
15673         do_nodes $list $LCTL set_param fail_loc=0x609
15674
15675         # pages should be in the case right after write
15676         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15677                 error "dd failed"
15678
15679         local BEFORE=$(roc_hit)
15680         cancel_lru_locks osc
15681         cat $DIR/$tfile >/dev/null
15682         local AFTER=$(roc_hit)
15683
15684         do_nodes $list $LCTL set_param fail_loc=0
15685
15686         if ! let "AFTER - BEFORE == CPAGES"; then
15687                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15688         fi
15689
15690         cancel_lru_locks osc
15691         # invalidates OST cache
15692         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15693         set_osd_param $list '' read_cache_enable 0
15694         cat $DIR/$tfile >/dev/null
15695
15696         # now data shouldn't be found in the cache
15697         BEFORE=$(roc_hit)
15698         cancel_lru_locks osc
15699         cat $DIR/$tfile >/dev/null
15700         AFTER=$(roc_hit)
15701         if let "AFTER - BEFORE != 0"; then
15702                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15703         fi
15704
15705         set_osd_param $list '' read_cache_enable 1
15706         rm -f $DIR/$tfile
15707 }
15708 run_test 151 "test cache on oss and controls ==============================="
15709
15710 test_152() {
15711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15712
15713         local TF="$TMP/$tfile"
15714
15715         # simulate ENOMEM during write
15716 #define OBD_FAIL_OST_NOMEM      0x226
15717         lctl set_param fail_loc=0x80000226
15718         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15719         cp $TF $DIR/$tfile
15720         sync || error "sync failed"
15721         lctl set_param fail_loc=0
15722
15723         # discard client's cache
15724         cancel_lru_locks osc
15725
15726         # simulate ENOMEM during read
15727         lctl set_param fail_loc=0x80000226
15728         cmp $TF $DIR/$tfile || error "cmp failed"
15729         lctl set_param fail_loc=0
15730
15731         rm -f $TF
15732 }
15733 run_test 152 "test read/write with enomem ============================"
15734
15735 test_153() {
15736         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15737 }
15738 run_test 153 "test if fdatasync does not crash ======================="
15739
15740 dot_lustre_fid_permission_check() {
15741         local fid=$1
15742         local ffid=$MOUNT/.lustre/fid/$fid
15743         local test_dir=$2
15744
15745         echo "stat fid $fid"
15746         stat $ffid || error "stat $ffid failed."
15747         echo "touch fid $fid"
15748         touch $ffid || error "touch $ffid failed."
15749         echo "write to fid $fid"
15750         cat /etc/hosts > $ffid || error "write $ffid failed."
15751         echo "read fid $fid"
15752         diff /etc/hosts $ffid || error "read $ffid failed."
15753         echo "append write to fid $fid"
15754         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15755         echo "rename fid $fid"
15756         mv $ffid $test_dir/$tfile.1 &&
15757                 error "rename $ffid to $tfile.1 should fail."
15758         touch $test_dir/$tfile.1
15759         mv $test_dir/$tfile.1 $ffid &&
15760                 error "rename $tfile.1 to $ffid should fail."
15761         rm -f $test_dir/$tfile.1
15762         echo "truncate fid $fid"
15763         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15764         echo "link fid $fid"
15765         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15766         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15767                 echo "setfacl fid $fid"
15768                 setfacl -R -m u:$USER0:rwx $ffid ||
15769                         error "setfacl $ffid failed"
15770                 echo "getfacl fid $fid"
15771                 getfacl $ffid || error "getfacl $ffid failed."
15772         fi
15773         echo "unlink fid $fid"
15774         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15775         echo "mknod fid $fid"
15776         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15777
15778         fid=[0xf00000400:0x1:0x0]
15779         ffid=$MOUNT/.lustre/fid/$fid
15780
15781         echo "stat non-exist fid $fid"
15782         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15783         echo "write to non-exist fid $fid"
15784         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15785         echo "link new fid $fid"
15786         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15787
15788         mkdir -p $test_dir/$tdir
15789         touch $test_dir/$tdir/$tfile
15790         fid=$($LFS path2fid $test_dir/$tdir)
15791         rc=$?
15792         [ $rc -ne 0 ] &&
15793                 error "error: could not get fid for $test_dir/$dir/$tfile."
15794
15795         ffid=$MOUNT/.lustre/fid/$fid
15796
15797         echo "ls $fid"
15798         ls $ffid || error "ls $ffid failed."
15799         echo "touch $fid/$tfile.1"
15800         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15801
15802         echo "touch $MOUNT/.lustre/fid/$tfile"
15803         touch $MOUNT/.lustre/fid/$tfile && \
15804                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15805
15806         echo "setxattr to $MOUNT/.lustre/fid"
15807         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15808
15809         echo "listxattr for $MOUNT/.lustre/fid"
15810         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15811
15812         echo "delxattr from $MOUNT/.lustre/fid"
15813         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15814
15815         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15816         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15817                 error "touch invalid fid should fail."
15818
15819         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15820         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15821                 error "touch non-normal fid should fail."
15822
15823         echo "rename $tdir to $MOUNT/.lustre/fid"
15824         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15825                 error "rename to $MOUNT/.lustre/fid should fail."
15826
15827         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15828         then            # LU-3547
15829                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15830                 local new_obf_mode=777
15831
15832                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15833                 chmod $new_obf_mode $DIR/.lustre/fid ||
15834                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15835
15836                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15837                 [ $obf_mode -eq $new_obf_mode ] ||
15838                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15839
15840                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15841                 chmod $old_obf_mode $DIR/.lustre/fid ||
15842                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15843         fi
15844
15845         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15846         fid=$($LFS path2fid $test_dir/$tfile-2)
15847
15848         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15849         then # LU-5424
15850                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15851                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15852                         error "create lov data thru .lustre failed"
15853         fi
15854         echo "cp /etc/passwd $test_dir/$tfile-2"
15855         cp /etc/passwd $test_dir/$tfile-2 ||
15856                 error "copy to $test_dir/$tfile-2 failed."
15857         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15858         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15859                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15860
15861         rm -rf $test_dir/tfile.lnk
15862         rm -rf $test_dir/$tfile-2
15863 }
15864
15865 test_154A() {
15866         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15867                 skip "Need MDS version at least 2.4.1"
15868
15869         local tf=$DIR/$tfile
15870         touch $tf
15871
15872         local fid=$($LFS path2fid $tf)
15873         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15874
15875         # check that we get the same pathname back
15876         local rootpath
15877         local found
15878         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15879                 echo "$rootpath $fid"
15880                 found=$($LFS fid2path $rootpath "$fid")
15881                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15882                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15883         done
15884
15885         # check wrong root path format
15886         rootpath=$MOUNT"_wrong"
15887         found=$($LFS fid2path $rootpath "$fid")
15888         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15889 }
15890 run_test 154A "lfs path2fid and fid2path basic checks"
15891
15892 test_154B() {
15893         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15894                 skip "Need MDS version at least 2.4.1"
15895
15896         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15897         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15898         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15899         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15900
15901         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15902         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15903
15904         # check that we get the same pathname
15905         echo "PFID: $PFID, name: $name"
15906         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15907         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15908         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15909                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15910
15911         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15912 }
15913 run_test 154B "verify the ll_decode_linkea tool"
15914
15915 test_154a() {
15916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15917         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15918         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15919                 skip "Need MDS version at least 2.2.51"
15920         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15921
15922         cp /etc/hosts $DIR/$tfile
15923
15924         fid=$($LFS path2fid $DIR/$tfile)
15925         rc=$?
15926         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15927
15928         dot_lustre_fid_permission_check "$fid" $DIR ||
15929                 error "dot lustre permission check $fid failed"
15930
15931         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15932
15933         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15934
15935         touch $MOUNT/.lustre/file &&
15936                 error "creation is not allowed under .lustre"
15937
15938         mkdir $MOUNT/.lustre/dir &&
15939                 error "mkdir is not allowed under .lustre"
15940
15941         rm -rf $DIR/$tfile
15942 }
15943 run_test 154a "Open-by-FID"
15944
15945 test_154b() {
15946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15947         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15949         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15950                 skip "Need MDS version at least 2.2.51"
15951
15952         local remote_dir=$DIR/$tdir/remote_dir
15953         local MDTIDX=1
15954         local rc=0
15955
15956         mkdir -p $DIR/$tdir
15957         $LFS mkdir -i $MDTIDX $remote_dir ||
15958                 error "create remote directory failed"
15959
15960         cp /etc/hosts $remote_dir/$tfile
15961
15962         fid=$($LFS path2fid $remote_dir/$tfile)
15963         rc=$?
15964         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15965
15966         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15967                 error "dot lustre permission check $fid failed"
15968         rm -rf $DIR/$tdir
15969 }
15970 run_test 154b "Open-by-FID for remote directory"
15971
15972 test_154c() {
15973         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15974                 skip "Need MDS version at least 2.4.1"
15975
15976         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15977         local FID1=$($LFS path2fid $DIR/$tfile.1)
15978         local FID2=$($LFS path2fid $DIR/$tfile.2)
15979         local FID3=$($LFS path2fid $DIR/$tfile.3)
15980
15981         local N=1
15982         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15983                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15984                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15985                 local want=FID$N
15986                 [ "$FID" = "${!want}" ] ||
15987                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15988                 N=$((N + 1))
15989         done
15990
15991         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15992         do
15993                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15994                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15995                 N=$((N + 1))
15996         done
15997 }
15998 run_test 154c "lfs path2fid and fid2path multiple arguments"
15999
16000 test_154d() {
16001         remote_mds_nodsh && skip "remote MDS with nodsh"
16002         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16003                 skip "Need MDS version at least 2.5.53"
16004
16005         if remote_mds; then
16006                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16007         else
16008                 nid="0@lo"
16009         fi
16010         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16011         local fd
16012         local cmd
16013
16014         rm -f $DIR/$tfile
16015         touch $DIR/$tfile
16016
16017         local fid=$($LFS path2fid $DIR/$tfile)
16018         # Open the file
16019         fd=$(free_fd)
16020         cmd="exec $fd<$DIR/$tfile"
16021         eval $cmd
16022         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16023         echo "$fid_list" | grep "$fid"
16024         rc=$?
16025
16026         cmd="exec $fd>/dev/null"
16027         eval $cmd
16028         if [ $rc -ne 0 ]; then
16029                 error "FID $fid not found in open files list $fid_list"
16030         fi
16031 }
16032 run_test 154d "Verify open file fid"
16033
16034 test_154e()
16035 {
16036         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16037                 skip "Need MDS version at least 2.6.50"
16038
16039         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16040                 error ".lustre returned by readdir"
16041         fi
16042 }
16043 run_test 154e ".lustre is not returned by readdir"
16044
16045 test_154f() {
16046         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16047
16048         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16049         mkdir_on_mdt0 $DIR/$tdir
16050         # test dirs inherit from its stripe
16051         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16052         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16053         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16054         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16055         touch $DIR/f
16056
16057         # get fid of parents
16058         local FID0=$($LFS path2fid $DIR/$tdir)
16059         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16060         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16061         local FID3=$($LFS path2fid $DIR)
16062
16063         # check that path2fid --parents returns expected <parent_fid>/name
16064         # 1) test for a directory (single parent)
16065         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16066         [ "$parent" == "$FID0/foo1" ] ||
16067                 error "expected parent: $FID0/foo1, got: $parent"
16068
16069         # 2) test for a file with nlink > 1 (multiple parents)
16070         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16071         echo "$parent" | grep -F "$FID1/$tfile" ||
16072                 error "$FID1/$tfile not returned in parent list"
16073         echo "$parent" | grep -F "$FID2/link" ||
16074                 error "$FID2/link not returned in parent list"
16075
16076         # 3) get parent by fid
16077         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16078         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16079         echo "$parent" | grep -F "$FID1/$tfile" ||
16080                 error "$FID1/$tfile not returned in parent list (by fid)"
16081         echo "$parent" | grep -F "$FID2/link" ||
16082                 error "$FID2/link not returned in parent list (by fid)"
16083
16084         # 4) test for entry in root directory
16085         parent=$($LFS path2fid --parents $DIR/f)
16086         echo "$parent" | grep -F "$FID3/f" ||
16087                 error "$FID3/f not returned in parent list"
16088
16089         # 5) test it on root directory
16090         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16091                 error "$MOUNT should not have parents"
16092
16093         # enable xattr caching and check that linkea is correctly updated
16094         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16095         save_lustre_params client "llite.*.xattr_cache" > $save
16096         lctl set_param llite.*.xattr_cache 1
16097
16098         # 6.1) linkea update on rename
16099         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16100
16101         # get parents by fid
16102         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16103         # foo1 should no longer be returned in parent list
16104         echo "$parent" | grep -F "$FID1" &&
16105                 error "$FID1 should no longer be in parent list"
16106         # the new path should appear
16107         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16108                 error "$FID2/$tfile.moved is not in parent list"
16109
16110         # 6.2) linkea update on unlink
16111         rm -f $DIR/$tdir/foo2/link
16112         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16113         # foo2/link should no longer be returned in parent list
16114         echo "$parent" | grep -F "$FID2/link" &&
16115                 error "$FID2/link should no longer be in parent list"
16116         true
16117
16118         rm -f $DIR/f
16119         restore_lustre_params < $save
16120         rm -f $save
16121 }
16122 run_test 154f "get parent fids by reading link ea"
16123
16124 test_154g()
16125 {
16126         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16127            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16128                 skip "Need MDS version at least 2.6.92"
16129
16130         mkdir_on_mdt0 $DIR/$tdir
16131         llapi_fid_test -d $DIR/$tdir
16132 }
16133 run_test 154g "various llapi FID tests"
16134
16135 test_155_small_load() {
16136     local temp=$TMP/$tfile
16137     local file=$DIR/$tfile
16138
16139     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16140         error "dd of=$temp bs=6096 count=1 failed"
16141     cp $temp $file
16142     cancel_lru_locks $OSC
16143     cmp $temp $file || error "$temp $file differ"
16144
16145     $TRUNCATE $temp 6000
16146     $TRUNCATE $file 6000
16147     cmp $temp $file || error "$temp $file differ (truncate1)"
16148
16149     echo "12345" >>$temp
16150     echo "12345" >>$file
16151     cmp $temp $file || error "$temp $file differ (append1)"
16152
16153     echo "12345" >>$temp
16154     echo "12345" >>$file
16155     cmp $temp $file || error "$temp $file differ (append2)"
16156
16157     rm -f $temp $file
16158     true
16159 }
16160
16161 test_155_big_load() {
16162         remote_ost_nodsh && skip "remote OST with nodsh"
16163
16164         local temp=$TMP/$tfile
16165         local file=$DIR/$tfile
16166
16167         free_min_max
16168         local cache_size=$(do_facet ost$((MAXI+1)) \
16169                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16170
16171         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16172         # pre-set value
16173         if [ -z "$cache_size" ]; then
16174                 cache_size=256
16175         fi
16176         local large_file_size=$((cache_size * 2))
16177
16178         echo "OSS cache size: $cache_size KB"
16179         echo "Large file size: $large_file_size KB"
16180
16181         [ $MAXV -le $large_file_size ] &&
16182                 skip_env "max available OST size needs > $large_file_size KB"
16183
16184         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16185
16186         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16187                 error "dd of=$temp bs=$large_file_size count=1k failed"
16188         cp $temp $file
16189         ls -lh $temp $file
16190         cancel_lru_locks osc
16191         cmp $temp $file || error "$temp $file differ"
16192
16193         rm -f $temp $file
16194         true
16195 }
16196
16197 save_writethrough() {
16198         local facets=$(get_facets OST)
16199
16200         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16201 }
16202
16203 test_155a() {
16204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16205
16206         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16207
16208         save_writethrough $p
16209
16210         set_cache read on
16211         set_cache writethrough on
16212         test_155_small_load
16213         restore_lustre_params < $p
16214         rm -f $p
16215 }
16216 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16217
16218 test_155b() {
16219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16220
16221         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16222
16223         save_writethrough $p
16224
16225         set_cache read on
16226         set_cache writethrough off
16227         test_155_small_load
16228         restore_lustre_params < $p
16229         rm -f $p
16230 }
16231 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16232
16233 test_155c() {
16234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16235
16236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16237
16238         save_writethrough $p
16239
16240         set_cache read off
16241         set_cache writethrough on
16242         test_155_small_load
16243         restore_lustre_params < $p
16244         rm -f $p
16245 }
16246 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16247
16248 test_155d() {
16249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16250
16251         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16252
16253         save_writethrough $p
16254
16255         set_cache read off
16256         set_cache writethrough off
16257         test_155_small_load
16258         restore_lustre_params < $p
16259         rm -f $p
16260 }
16261 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16262
16263 test_155e() {
16264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16265
16266         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16267
16268         save_writethrough $p
16269
16270         set_cache read on
16271         set_cache writethrough on
16272         test_155_big_load
16273         restore_lustre_params < $p
16274         rm -f $p
16275 }
16276 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16277
16278 test_155f() {
16279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16280
16281         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16282
16283         save_writethrough $p
16284
16285         set_cache read on
16286         set_cache writethrough off
16287         test_155_big_load
16288         restore_lustre_params < $p
16289         rm -f $p
16290 }
16291 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16292
16293 test_155g() {
16294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16295
16296         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16297
16298         save_writethrough $p
16299
16300         set_cache read off
16301         set_cache writethrough on
16302         test_155_big_load
16303         restore_lustre_params < $p
16304         rm -f $p
16305 }
16306 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16307
16308 test_155h() {
16309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16310
16311         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16312
16313         save_writethrough $p
16314
16315         set_cache read off
16316         set_cache writethrough off
16317         test_155_big_load
16318         restore_lustre_params < $p
16319         rm -f $p
16320 }
16321 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16322
16323 test_156() {
16324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16325         remote_ost_nodsh && skip "remote OST with nodsh"
16326         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16327                 skip "stats not implemented on old servers"
16328         [ "$ost1_FSTYPE" = "zfs" ] &&
16329                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16330
16331         local CPAGES=3
16332         local BEFORE
16333         local AFTER
16334         local file="$DIR/$tfile"
16335         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16336
16337         save_writethrough $p
16338         roc_hit_init
16339
16340         log "Turn on read and write cache"
16341         set_cache read on
16342         set_cache writethrough on
16343
16344         log "Write data and read it back."
16345         log "Read should be satisfied from the cache."
16346         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16347         BEFORE=$(roc_hit)
16348         cancel_lru_locks osc
16349         cat $file >/dev/null
16350         AFTER=$(roc_hit)
16351         if ! let "AFTER - BEFORE == CPAGES"; then
16352                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16353         else
16354                 log "cache hits: before: $BEFORE, after: $AFTER"
16355         fi
16356
16357         log "Read again; it should be satisfied from the cache."
16358         BEFORE=$AFTER
16359         cancel_lru_locks osc
16360         cat $file >/dev/null
16361         AFTER=$(roc_hit)
16362         if ! let "AFTER - BEFORE == CPAGES"; then
16363                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16364         else
16365                 log "cache hits:: before: $BEFORE, after: $AFTER"
16366         fi
16367
16368         log "Turn off the read cache and turn on the write cache"
16369         set_cache read off
16370         set_cache writethrough on
16371
16372         log "Read again; it should be satisfied from the cache."
16373         BEFORE=$(roc_hit)
16374         cancel_lru_locks osc
16375         cat $file >/dev/null
16376         AFTER=$(roc_hit)
16377         if ! let "AFTER - BEFORE == CPAGES"; then
16378                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16379         else
16380                 log "cache hits:: before: $BEFORE, after: $AFTER"
16381         fi
16382
16383         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16384                 # > 2.12.56 uses pagecache if cached
16385                 log "Read again; it should not be satisfied from the cache."
16386                 BEFORE=$AFTER
16387                 cancel_lru_locks osc
16388                 cat $file >/dev/null
16389                 AFTER=$(roc_hit)
16390                 if ! let "AFTER - BEFORE == 0"; then
16391                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16392                 else
16393                         log "cache hits:: before: $BEFORE, after: $AFTER"
16394                 fi
16395         fi
16396
16397         log "Write data and read it back."
16398         log "Read should be satisfied from the cache."
16399         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16400         BEFORE=$(roc_hit)
16401         cancel_lru_locks osc
16402         cat $file >/dev/null
16403         AFTER=$(roc_hit)
16404         if ! let "AFTER - BEFORE == CPAGES"; then
16405                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16406         else
16407                 log "cache hits:: before: $BEFORE, after: $AFTER"
16408         fi
16409
16410         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16411                 # > 2.12.56 uses pagecache if cached
16412                 log "Read again; it should not be satisfied from the cache."
16413                 BEFORE=$AFTER
16414                 cancel_lru_locks osc
16415                 cat $file >/dev/null
16416                 AFTER=$(roc_hit)
16417                 if ! let "AFTER - BEFORE == 0"; then
16418                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16419                 else
16420                         log "cache hits:: before: $BEFORE, after: $AFTER"
16421                 fi
16422         fi
16423
16424         log "Turn off read and write cache"
16425         set_cache read off
16426         set_cache writethrough off
16427
16428         log "Write data and read it back"
16429         log "It should not be satisfied from the cache."
16430         rm -f $file
16431         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16432         cancel_lru_locks osc
16433         BEFORE=$(roc_hit)
16434         cat $file >/dev/null
16435         AFTER=$(roc_hit)
16436         if ! let "AFTER - BEFORE == 0"; then
16437                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16438         else
16439                 log "cache hits:: before: $BEFORE, after: $AFTER"
16440         fi
16441
16442         log "Turn on the read cache and turn off the write cache"
16443         set_cache read on
16444         set_cache writethrough off
16445
16446         log "Write data and read it back"
16447         log "It should not be satisfied from the cache."
16448         rm -f $file
16449         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16450         BEFORE=$(roc_hit)
16451         cancel_lru_locks osc
16452         cat $file >/dev/null
16453         AFTER=$(roc_hit)
16454         if ! let "AFTER - BEFORE == 0"; then
16455                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16456         else
16457                 log "cache hits:: before: $BEFORE, after: $AFTER"
16458         fi
16459
16460         log "Read again; it should be satisfied from the cache."
16461         BEFORE=$(roc_hit)
16462         cancel_lru_locks osc
16463         cat $file >/dev/null
16464         AFTER=$(roc_hit)
16465         if ! let "AFTER - BEFORE == CPAGES"; then
16466                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16467         else
16468                 log "cache hits:: before: $BEFORE, after: $AFTER"
16469         fi
16470
16471         restore_lustre_params < $p
16472         rm -f $p $file
16473 }
16474 run_test 156 "Verification of tunables"
16475
16476 test_160a() {
16477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16478         remote_mds_nodsh && skip "remote MDS with nodsh"
16479         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16480                 skip "Need MDS version at least 2.2.0"
16481
16482         changelog_register || error "changelog_register failed"
16483         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16484         changelog_users $SINGLEMDS | grep -q $cl_user ||
16485                 error "User $cl_user not found in changelog_users"
16486
16487         mkdir_on_mdt0 $DIR/$tdir
16488
16489         # change something
16490         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16491         changelog_clear 0 || error "changelog_clear failed"
16492         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16493         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16494         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16495         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16496         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16497         rm $DIR/$tdir/pics/desktop.jpg
16498
16499         echo "verifying changelog mask"
16500         changelog_chmask "-MKDIR"
16501         changelog_chmask "-CLOSE"
16502
16503         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16504         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16505
16506         changelog_chmask "+MKDIR"
16507         changelog_chmask "+CLOSE"
16508
16509         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16510         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16511
16512         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16513         CLOSES=$(changelog_dump | grep -c "CLOSE")
16514         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16515         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16516
16517         # verify contents
16518         echo "verifying target fid"
16519         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16520         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16521         [ "$fidc" == "$fidf" ] ||
16522                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16523         echo "verifying parent fid"
16524         # The FID returned from the Changelog may be the directory shard on
16525         # a different MDT, and not the FID returned by path2fid on the parent.
16526         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16527         # since this is what will matter when recreating this file in the tree.
16528         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16529         local pathp=$($LFS fid2path $MOUNT "$fidp")
16530         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16531                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16532
16533         echo "getting records for $cl_user"
16534         changelog_users $SINGLEMDS
16535         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16536         local nclr=3
16537         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16538                 error "changelog_clear failed"
16539         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16540         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16541         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16542                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16543
16544         local min0_rec=$(changelog_users $SINGLEMDS |
16545                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16546         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16547                           awk '{ print $1; exit; }')
16548
16549         changelog_dump | tail -n 5
16550         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16551         [ $first_rec == $((min0_rec + 1)) ] ||
16552                 error "first index should be $min0_rec + 1 not $first_rec"
16553
16554         # LU-3446 changelog index reset on MDT restart
16555         local cur_rec1=$(changelog_users $SINGLEMDS |
16556                          awk '/^current.index:/ { print $NF }')
16557         changelog_clear 0 ||
16558                 error "clear all changelog records for $cl_user failed"
16559         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16560         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16561                 error "Fail to start $SINGLEMDS"
16562         local cur_rec2=$(changelog_users $SINGLEMDS |
16563                          awk '/^current.index:/ { print $NF }')
16564         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16565         [ $cur_rec1 == $cur_rec2 ] ||
16566                 error "current index should be $cur_rec1 not $cur_rec2"
16567
16568         echo "verifying users from this test are deregistered"
16569         changelog_deregister || error "changelog_deregister failed"
16570         changelog_users $SINGLEMDS | grep -q $cl_user &&
16571                 error "User '$cl_user' still in changelog_users"
16572
16573         # lctl get_param -n mdd.*.changelog_users
16574         # current_index: 144
16575         # ID    index (idle seconds)
16576         # cl3   144   (2) mask=<list>
16577         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16578                 # this is the normal case where all users were deregistered
16579                 # make sure no new records are added when no users are present
16580                 local last_rec1=$(changelog_users $SINGLEMDS |
16581                                   awk '/^current.index:/ { print $NF }')
16582                 touch $DIR/$tdir/chloe
16583                 local last_rec2=$(changelog_users $SINGLEMDS |
16584                                   awk '/^current.index:/ { print $NF }')
16585                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16586                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16587         else
16588                 # any changelog users must be leftovers from a previous test
16589                 changelog_users $SINGLEMDS
16590                 echo "other changelog users; can't verify off"
16591         fi
16592 }
16593 run_test 160a "changelog sanity"
16594
16595 test_160b() { # LU-3587
16596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16597         remote_mds_nodsh && skip "remote MDS with nodsh"
16598         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16599                 skip "Need MDS version at least 2.2.0"
16600
16601         changelog_register || error "changelog_register failed"
16602         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16603         changelog_users $SINGLEMDS | grep -q $cl_user ||
16604                 error "User '$cl_user' not found in changelog_users"
16605
16606         local longname1=$(str_repeat a 255)
16607         local longname2=$(str_repeat b 255)
16608
16609         cd $DIR
16610         echo "creating very long named file"
16611         touch $longname1 || error "create of '$longname1' failed"
16612         echo "renaming very long named file"
16613         mv $longname1 $longname2
16614
16615         changelog_dump | grep RENME | tail -n 5
16616         rm -f $longname2
16617 }
16618 run_test 160b "Verify that very long rename doesn't crash in changelog"
16619
16620 test_160c() {
16621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16622         remote_mds_nodsh && skip "remote MDS with nodsh"
16623
16624         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16625                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16626                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16627                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16628
16629         local rc=0
16630
16631         # Registration step
16632         changelog_register || error "changelog_register failed"
16633
16634         rm -rf $DIR/$tdir
16635         mkdir -p $DIR/$tdir
16636         $MCREATE $DIR/$tdir/foo_160c
16637         changelog_chmask "-TRUNC"
16638         $TRUNCATE $DIR/$tdir/foo_160c 200
16639         changelog_chmask "+TRUNC"
16640         $TRUNCATE $DIR/$tdir/foo_160c 199
16641         changelog_dump | tail -n 5
16642         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16643         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16644 }
16645 run_test 160c "verify that changelog log catch the truncate event"
16646
16647 test_160d() {
16648         remote_mds_nodsh && skip "remote MDS with nodsh"
16649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16651         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16652                 skip "Need MDS version at least 2.7.60"
16653
16654         # Registration step
16655         changelog_register || error "changelog_register failed"
16656
16657         mkdir -p $DIR/$tdir/migrate_dir
16658         changelog_clear 0 || error "changelog_clear failed"
16659
16660         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16661         changelog_dump | tail -n 5
16662         local migrates=$(changelog_dump | grep -c "MIGRT")
16663         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16664 }
16665 run_test 160d "verify that changelog log catch the migrate event"
16666
16667 test_160e() {
16668         remote_mds_nodsh && skip "remote MDS with nodsh"
16669
16670         # Create a user
16671         changelog_register || error "changelog_register failed"
16672
16673         local MDT0=$(facet_svc $SINGLEMDS)
16674         local rc
16675
16676         # No user (expect fail)
16677         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16678         rc=$?
16679         if [ $rc -eq 0 ]; then
16680                 error "Should fail without user"
16681         elif [ $rc -ne 4 ]; then
16682                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16683         fi
16684
16685         # Delete a future user (expect fail)
16686         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16687         rc=$?
16688         if [ $rc -eq 0 ]; then
16689                 error "Deleted non-existant user cl77"
16690         elif [ $rc -ne 2 ]; then
16691                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16692         fi
16693
16694         # Clear to a bad index (1 billion should be safe)
16695         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16696         rc=$?
16697
16698         if [ $rc -eq 0 ]; then
16699                 error "Successfully cleared to invalid CL index"
16700         elif [ $rc -ne 22 ]; then
16701                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16702         fi
16703 }
16704 run_test 160e "changelog negative testing (should return errors)"
16705
16706 test_160f() {
16707         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16708         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16709                 skip "Need MDS version at least 2.10.56"
16710
16711         local mdts=$(comma_list $(mdts_nodes))
16712
16713         # Create a user
16714         changelog_register || error "first changelog_register failed"
16715         changelog_register || error "second changelog_register failed"
16716         local cl_users
16717         declare -A cl_user1
16718         declare -A cl_user2
16719         local user_rec1
16720         local user_rec2
16721         local i
16722
16723         # generate some changelog records to accumulate on each MDT
16724         # use all_char because created files should be evenly distributed
16725         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16726                 error "test_mkdir $tdir failed"
16727         log "$(date +%s): creating first files"
16728         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16729                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16730                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16731         done
16732
16733         # check changelogs have been generated
16734         local start=$SECONDS
16735         local idle_time=$((MDSCOUNT * 5 + 5))
16736         local nbcl=$(changelog_dump | wc -l)
16737         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16738
16739         for param in "changelog_max_idle_time=$idle_time" \
16740                      "changelog_gc=1" \
16741                      "changelog_min_gc_interval=2" \
16742                      "changelog_min_free_cat_entries=3"; do
16743                 local MDT0=$(facet_svc $SINGLEMDS)
16744                 local var="${param%=*}"
16745                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16746
16747                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16748                 do_nodes $mdts $LCTL set_param mdd.*.$param
16749         done
16750
16751         # force cl_user2 to be idle (1st part), but also cancel the
16752         # cl_user1 records so that it is not evicted later in the test.
16753         local sleep1=$((idle_time / 2))
16754         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16755         sleep $sleep1
16756
16757         # simulate changelog catalog almost full
16758         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16759         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16760
16761         for i in $(seq $MDSCOUNT); do
16762                 cl_users=(${CL_USERS[mds$i]})
16763                 cl_user1[mds$i]="${cl_users[0]}"
16764                 cl_user2[mds$i]="${cl_users[1]}"
16765
16766                 [ -n "${cl_user1[mds$i]}" ] ||
16767                         error "mds$i: no user registered"
16768                 [ -n "${cl_user2[mds$i]}" ] ||
16769                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16770
16771                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16772                 [ -n "$user_rec1" ] ||
16773                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16774                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16775                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16776                 [ -n "$user_rec2" ] ||
16777                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16778                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16779                      "$user_rec1 + 2 == $user_rec2"
16780                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16781                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16782                               "$user_rec1 + 2, but is $user_rec2"
16783                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16784                 [ -n "$user_rec2" ] ||
16785                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16786                 [ $user_rec1 == $user_rec2 ] ||
16787                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16788                               "$user_rec1, but is $user_rec2"
16789         done
16790
16791         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16792         local sleep2=$((idle_time - (SECONDS - start) + 1))
16793         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16794         sleep $sleep2
16795
16796         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16797         # cl_user1 should be OK because it recently processed records.
16798         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16799         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16800                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16801                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16802         done
16803
16804         # ensure gc thread is done
16805         for i in $(mdts_nodes); do
16806                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16807                         error "$i: GC-thread not done"
16808         done
16809
16810         local first_rec
16811         for (( i = 1; i <= MDSCOUNT; i++ )); do
16812                 # check cl_user1 still registered
16813                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16815                 # check cl_user2 unregistered
16816                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16817                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16818
16819                 # check changelogs are present and starting at $user_rec1 + 1
16820                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16821                 [ -n "$user_rec1" ] ||
16822                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16823                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16824                             awk '{ print $1; exit; }')
16825
16826                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16827                 [ $((user_rec1 + 1)) == $first_rec ] ||
16828                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16829         done
16830 }
16831 run_test 160f "changelog garbage collect (timestamped users)"
16832
16833 test_160g() {
16834         remote_mds_nodsh && skip "remote MDS with nodsh"
16835         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16836                 skip "Need MDS version at least 2.14.55"
16837
16838         local mdts=$(comma_list $(mdts_nodes))
16839
16840         # Create a user
16841         changelog_register || error "first changelog_register failed"
16842         changelog_register || error "second changelog_register failed"
16843         local cl_users
16844         declare -A cl_user1
16845         declare -A cl_user2
16846         local user_rec1
16847         local user_rec2
16848         local i
16849
16850         # generate some changelog records to accumulate on each MDT
16851         # use all_char because created files should be evenly distributed
16852         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16853                 error "test_mkdir $tdir failed"
16854         for ((i = 0; i < MDSCOUNT; i++)); do
16855                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16856                         error "create $DIR/$tdir/d$i.1 failed"
16857         done
16858
16859         # check changelogs have been generated
16860         local nbcl=$(changelog_dump | wc -l)
16861         (( $nbcl > 0 )) || error "no changelogs found"
16862
16863         # reduce the max_idle_indexes value to make sure we exceed it
16864         for param in "changelog_max_idle_indexes=2" \
16865                      "changelog_gc=1" \
16866                      "changelog_min_gc_interval=2"; do
16867                 local MDT0=$(facet_svc $SINGLEMDS)
16868                 local var="${param%=*}"
16869                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16870
16871                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16872                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16873                         error "unable to set mdd.*.$param"
16874         done
16875
16876         local start=$SECONDS
16877         for i in $(seq $MDSCOUNT); do
16878                 cl_users=(${CL_USERS[mds$i]})
16879                 cl_user1[mds$i]="${cl_users[0]}"
16880                 cl_user2[mds$i]="${cl_users[1]}"
16881
16882                 [ -n "${cl_user1[mds$i]}" ] ||
16883                         error "mds$i: user1 is not registered"
16884                 [ -n "${cl_user2[mds$i]}" ] ||
16885                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16886
16887                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16888                 [ -n "$user_rec1" ] ||
16889                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16890                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16891                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16892                 [ -n "$user_rec2" ] ||
16893                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16894                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16895                      "$user_rec1 + 2 == $user_rec2"
16896                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16897                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16898                               "expected $user_rec1 + 2, but is $user_rec2"
16899                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16900                 [ -n "$user_rec2" ] ||
16901                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16902                 [ $user_rec1 == $user_rec2 ] ||
16903                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16904                               "expected $user_rec1, but is $user_rec2"
16905         done
16906
16907         # ensure we are past the previous changelog_min_gc_interval set above
16908         local sleep2=$((start + 2 - SECONDS))
16909         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16910         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16911         # cl_user1 should be OK because it recently processed records.
16912         for ((i = 0; i < MDSCOUNT; i++)); do
16913                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16914                         error "create $DIR/$tdir/d$i.3 failed"
16915         done
16916
16917         # ensure gc thread is done
16918         for i in $(mdts_nodes); do
16919                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16920                         error "$i: GC-thread not done"
16921         done
16922
16923         local first_rec
16924         for (( i = 1; i <= MDSCOUNT; i++ )); do
16925                 # check cl_user1 still registered
16926                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16927                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16928                 # check cl_user2 unregistered
16929                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16930                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16931
16932                 # check changelogs are present and starting at $user_rec1 + 1
16933                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16934                 [ -n "$user_rec1" ] ||
16935                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16936                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16937                             awk '{ print $1; exit; }')
16938
16939                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16940                 [ $((user_rec1 + 1)) == $first_rec ] ||
16941                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16942         done
16943 }
16944 run_test 160g "changelog garbage collect on idle records"
16945
16946 test_160h() {
16947         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16948         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16949                 skip "Need MDS version at least 2.10.56"
16950
16951         local mdts=$(comma_list $(mdts_nodes))
16952
16953         # Create a user
16954         changelog_register || error "first changelog_register failed"
16955         changelog_register || error "second changelog_register failed"
16956         local cl_users
16957         declare -A cl_user1
16958         declare -A cl_user2
16959         local user_rec1
16960         local user_rec2
16961         local i
16962
16963         # generate some changelog records to accumulate on each MDT
16964         # use all_char because created files should be evenly distributed
16965         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16966                 error "test_mkdir $tdir failed"
16967         for ((i = 0; i < MDSCOUNT; i++)); do
16968                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16969                         error "create $DIR/$tdir/d$i.1 failed"
16970         done
16971
16972         # check changelogs have been generated
16973         local nbcl=$(changelog_dump | wc -l)
16974         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16975
16976         for param in "changelog_max_idle_time=10" \
16977                      "changelog_gc=1" \
16978                      "changelog_min_gc_interval=2"; do
16979                 local MDT0=$(facet_svc $SINGLEMDS)
16980                 local var="${param%=*}"
16981                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16982
16983                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16984                 do_nodes $mdts $LCTL set_param mdd.*.$param
16985         done
16986
16987         # force cl_user2 to be idle (1st part)
16988         sleep 9
16989
16990         for i in $(seq $MDSCOUNT); do
16991                 cl_users=(${CL_USERS[mds$i]})
16992                 cl_user1[mds$i]="${cl_users[0]}"
16993                 cl_user2[mds$i]="${cl_users[1]}"
16994
16995                 [ -n "${cl_user1[mds$i]}" ] ||
16996                         error "mds$i: no user registered"
16997                 [ -n "${cl_user2[mds$i]}" ] ||
16998                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16999
17000                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17001                 [ -n "$user_rec1" ] ||
17002                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17003                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17004                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17005                 [ -n "$user_rec2" ] ||
17006                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17007                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17008                      "$user_rec1 + 2 == $user_rec2"
17009                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17010                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17011                               "$user_rec1 + 2, but is $user_rec2"
17012                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17013                 [ -n "$user_rec2" ] ||
17014                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17015                 [ $user_rec1 == $user_rec2 ] ||
17016                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17017                               "$user_rec1, but is $user_rec2"
17018         done
17019
17020         # force cl_user2 to be idle (2nd part) and to reach
17021         # changelog_max_idle_time
17022         sleep 2
17023
17024         # force each GC-thread start and block then
17025         # one per MDT/MDD, set fail_val accordingly
17026         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17027         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17028
17029         # generate more changelogs to trigger fail_loc
17030         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17031                 error "create $DIR/$tdir/${tfile}bis failed"
17032
17033         # stop MDT to stop GC-thread, should be done in back-ground as it will
17034         # block waiting for the thread to be released and exit
17035         declare -A stop_pids
17036         for i in $(seq $MDSCOUNT); do
17037                 stop mds$i &
17038                 stop_pids[mds$i]=$!
17039         done
17040
17041         for i in $(mdts_nodes); do
17042                 local facet
17043                 local nb=0
17044                 local facets=$(facets_up_on_host $i)
17045
17046                 for facet in ${facets//,/ }; do
17047                         if [[ $facet == mds* ]]; then
17048                                 nb=$((nb + 1))
17049                         fi
17050                 done
17051                 # ensure each MDS's gc threads are still present and all in "R"
17052                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17053                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17054                         error "$i: expected $nb GC-thread"
17055                 wait_update $i \
17056                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17057                         "R" 20 ||
17058                         error "$i: GC-thread not found in R-state"
17059                 # check umounts of each MDT on MDS have reached kthread_stop()
17060                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17061                         error "$i: expected $nb umount"
17062                 wait_update $i \
17063                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17064                         error "$i: umount not found in D-state"
17065         done
17066
17067         # release all GC-threads
17068         do_nodes $mdts $LCTL set_param fail_loc=0
17069
17070         # wait for MDT stop to complete
17071         for i in $(seq $MDSCOUNT); do
17072                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17073         done
17074
17075         # XXX
17076         # may try to check if any orphan changelog records are present
17077         # via ldiskfs/zfs and llog_reader...
17078
17079         # re-start/mount MDTs
17080         for i in $(seq $MDSCOUNT); do
17081                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17082                         error "Fail to start mds$i"
17083         done
17084
17085         local first_rec
17086         for i in $(seq $MDSCOUNT); do
17087                 # check cl_user1 still registered
17088                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17089                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17090                 # check cl_user2 unregistered
17091                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17092                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17093
17094                 # check changelogs are present and starting at $user_rec1 + 1
17095                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17096                 [ -n "$user_rec1" ] ||
17097                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17098                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17099                             awk '{ print $1; exit; }')
17100
17101                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17102                 [ $((user_rec1 + 1)) == $first_rec ] ||
17103                         error "mds$i: first index should be $user_rec1 + 1, " \
17104                               "but is $first_rec"
17105         done
17106 }
17107 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17108               "during mount"
17109
17110 test_160i() {
17111
17112         local mdts=$(comma_list $(mdts_nodes))
17113
17114         changelog_register || error "first changelog_register failed"
17115
17116         # generate some changelog records to accumulate on each MDT
17117         # use all_char because created files should be evenly distributed
17118         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17119                 error "test_mkdir $tdir failed"
17120         for ((i = 0; i < MDSCOUNT; i++)); do
17121                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17122                         error "create $DIR/$tdir/d$i.1 failed"
17123         done
17124
17125         # check changelogs have been generated
17126         local nbcl=$(changelog_dump | wc -l)
17127         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17128
17129         # simulate race between register and unregister
17130         # XXX as fail_loc is set per-MDS, with DNE configs the race
17131         # simulation will only occur for one MDT per MDS and for the
17132         # others the normal race scenario will take place
17133         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17134         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17135         do_nodes $mdts $LCTL set_param fail_val=1
17136
17137         # unregister 1st user
17138         changelog_deregister &
17139         local pid1=$!
17140         # wait some time for deregister work to reach race rdv
17141         sleep 2
17142         # register 2nd user
17143         changelog_register || error "2nd user register failed"
17144
17145         wait $pid1 || error "1st user deregister failed"
17146
17147         local i
17148         local last_rec
17149         declare -A LAST_REC
17150         for i in $(seq $MDSCOUNT); do
17151                 if changelog_users mds$i | grep "^cl"; then
17152                         # make sure new records are added with one user present
17153                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17154                                           awk '/^current.index:/ { print $NF }')
17155                 else
17156                         error "mds$i has no user registered"
17157                 fi
17158         done
17159
17160         # generate more changelog records to accumulate on each MDT
17161         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17162                 error "create $DIR/$tdir/${tfile}bis failed"
17163
17164         for i in $(seq $MDSCOUNT); do
17165                 last_rec=$(changelog_users $SINGLEMDS |
17166                            awk '/^current.index:/ { print $NF }')
17167                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17168                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17169                         error "changelogs are off on mds$i"
17170         done
17171 }
17172 run_test 160i "changelog user register/unregister race"
17173
17174 test_160j() {
17175         remote_mds_nodsh && skip "remote MDS with nodsh"
17176         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17177                 skip "Need MDS version at least 2.12.56"
17178
17179         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17180         stack_trap "umount $MOUNT2" EXIT
17181
17182         changelog_register || error "first changelog_register failed"
17183         stack_trap "changelog_deregister" EXIT
17184
17185         # generate some changelog
17186         # use all_char because created files should be evenly distributed
17187         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17188                 error "mkdir $tdir failed"
17189         for ((i = 0; i < MDSCOUNT; i++)); do
17190                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17191                         error "create $DIR/$tdir/d$i.1 failed"
17192         done
17193
17194         # open the changelog device
17195         exec 3>/dev/changelog-$FSNAME-MDT0000
17196         stack_trap "exec 3>&-" EXIT
17197         exec 4</dev/changelog-$FSNAME-MDT0000
17198         stack_trap "exec 4<&-" EXIT
17199
17200         # umount the first lustre mount
17201         umount $MOUNT
17202         stack_trap "mount_client $MOUNT" EXIT
17203
17204         # read changelog, which may or may not fail, but should not crash
17205         cat <&4 >/dev/null
17206
17207         # clear changelog
17208         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17209         changelog_users $SINGLEMDS | grep -q $cl_user ||
17210                 error "User $cl_user not found in changelog_users"
17211
17212         printf 'clear:'$cl_user':0' >&3
17213 }
17214 run_test 160j "client can be umounted while its chanangelog is being used"
17215
17216 test_160k() {
17217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17218         remote_mds_nodsh && skip "remote MDS with nodsh"
17219
17220         mkdir -p $DIR/$tdir/1/1
17221
17222         changelog_register || error "changelog_register failed"
17223         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17224
17225         changelog_users $SINGLEMDS | grep -q $cl_user ||
17226                 error "User '$cl_user' not found in changelog_users"
17227 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17228         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17229         rmdir $DIR/$tdir/1/1 & sleep 1
17230         mkdir $DIR/$tdir/2
17231         touch $DIR/$tdir/2/2
17232         rm -rf $DIR/$tdir/2
17233
17234         wait
17235         sleep 4
17236
17237         changelog_dump | grep rmdir || error "rmdir not recorded"
17238 }
17239 run_test 160k "Verify that changelog records are not lost"
17240
17241 # Verifies that a file passed as a parameter has recently had an operation
17242 # performed on it that has generated an MTIME changelog which contains the
17243 # correct parent FID. As files might reside on a different MDT from the
17244 # parent directory in DNE configurations, the FIDs are translated to paths
17245 # before being compared, which should be identical
17246 compare_mtime_changelog() {
17247         local file="${1}"
17248         local mdtidx
17249         local mtime
17250         local cl_fid
17251         local pdir
17252         local dir
17253
17254         mdtidx=$($LFS getstripe --mdt-index $file)
17255         mdtidx=$(printf "%04x" $mdtidx)
17256
17257         # Obtain the parent FID from the MTIME changelog
17258         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17259         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17260
17261         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17262         [ -z "$cl_fid" ] && error "parent FID not present"
17263
17264         # Verify that the path for the parent FID is the same as the path for
17265         # the test directory
17266         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17267
17268         dir=$(dirname $1)
17269
17270         [[ "${pdir%/}" == "$dir" ]] ||
17271                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17272 }
17273
17274 test_160l() {
17275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17276
17277         remote_mds_nodsh && skip "remote MDS with nodsh"
17278         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17279                 skip "Need MDS version at least 2.13.55"
17280
17281         local cl_user
17282
17283         changelog_register || error "changelog_register failed"
17284         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17285
17286         changelog_users $SINGLEMDS | grep -q $cl_user ||
17287                 error "User '$cl_user' not found in changelog_users"
17288
17289         # Clear some types so that MTIME changelogs are generated
17290         changelog_chmask "-CREAT"
17291         changelog_chmask "-CLOSE"
17292
17293         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17294
17295         # Test CL_MTIME during setattr
17296         touch $DIR/$tdir/$tfile
17297         compare_mtime_changelog $DIR/$tdir/$tfile
17298
17299         # Test CL_MTIME during close
17300         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17301         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17302 }
17303 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17304
17305 test_160m() {
17306         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17307         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17308                 skip "Need MDS version at least 2.14.51"
17309         local cl_users
17310         local cl_user1
17311         local cl_user2
17312         local pid1
17313
17314         # Create a user
17315         changelog_register || error "first changelog_register failed"
17316         changelog_register || error "second changelog_register failed"
17317
17318         cl_users=(${CL_USERS[mds1]})
17319         cl_user1="${cl_users[0]}"
17320         cl_user2="${cl_users[1]}"
17321         # generate some changelog records to accumulate on MDT0
17322         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17323         createmany -m $DIR/$tdir/$tfile 50 ||
17324                 error "create $DIR/$tdir/$tfile failed"
17325         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17326         rm -f $DIR/$tdir
17327
17328         # check changelogs have been generated
17329         local nbcl=$(changelog_dump | wc -l)
17330         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17331
17332 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17333         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17334
17335         __changelog_clear mds1 $cl_user1 +10
17336         __changelog_clear mds1 $cl_user2 0 &
17337         pid1=$!
17338         sleep 2
17339         __changelog_clear mds1 $cl_user1 0 ||
17340                 error "fail to cancel record for $cl_user1"
17341         wait $pid1
17342         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17343 }
17344 run_test 160m "Changelog clear race"
17345
17346 test_160n() {
17347         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17348         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17349                 skip "Need MDS version at least 2.14.51"
17350         local cl_users
17351         local cl_user1
17352         local cl_user2
17353         local pid1
17354         local first_rec
17355         local last_rec=0
17356
17357         # Create a user
17358         changelog_register || error "first changelog_register failed"
17359
17360         cl_users=(${CL_USERS[mds1]})
17361         cl_user1="${cl_users[0]}"
17362
17363         # generate some changelog records to accumulate on MDT0
17364         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17365         first_rec=$(changelog_users $SINGLEMDS |
17366                         awk '/^current.index:/ { print $NF }')
17367         while (( last_rec < (( first_rec + 65000)) )); do
17368                 createmany -m $DIR/$tdir/$tfile 10000 ||
17369                         error "create $DIR/$tdir/$tfile failed"
17370
17371                 for i in $(seq 0 10000); do
17372                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17373                                 > /dev/null
17374                 done
17375
17376                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17377                         error "unlinkmany failed unlink"
17378                 last_rec=$(changelog_users $SINGLEMDS |
17379                         awk '/^current.index:/ { print $NF }')
17380                 echo last record $last_rec
17381                 (( last_rec == 0 )) && error "no changelog found"
17382         done
17383
17384 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17385         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17386
17387         __changelog_clear mds1 $cl_user1 0 &
17388         pid1=$!
17389         sleep 2
17390         __changelog_clear mds1 $cl_user1 0 ||
17391                 error "fail to cancel record for $cl_user1"
17392         wait $pid1
17393         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17394 }
17395 run_test 160n "Changelog destroy race"
17396
17397 test_160o() {
17398         local mdt="$(facet_svc $SINGLEMDS)"
17399
17400         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17401         remote_mds_nodsh && skip "remote MDS with nodsh"
17402         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17403                 skip "Need MDS version at least 2.14.52"
17404
17405         changelog_register --user test_160o -m unlnk+close+open ||
17406                 error "changelog_register failed"
17407
17408         do_facet $SINGLEMDS $LCTL --device $mdt \
17409                                 changelog_register -u "Tt3_-#" &&
17410                 error "bad symbols in name should fail"
17411
17412         do_facet $SINGLEMDS $LCTL --device $mdt \
17413                                 changelog_register -u test_160o &&
17414                 error "the same name registration should fail"
17415
17416         do_facet $SINGLEMDS $LCTL --device $mdt \
17417                         changelog_register -u test_160toolongname &&
17418                 error "too long name registration should fail"
17419
17420         changelog_chmask "MARK+HSM"
17421         lctl get_param mdd.*.changelog*mask
17422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17423         changelog_users $SINGLEMDS | grep -q $cl_user ||
17424                 error "User $cl_user not found in changelog_users"
17425         #verify username
17426         echo $cl_user | grep -q test_160o ||
17427                 error "User $cl_user has no specific name 'test160o'"
17428
17429         # change something
17430         changelog_clear 0 || error "changelog_clear failed"
17431         # generate some changelog records to accumulate on MDT0
17432         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17433         touch $DIR/$tdir/$tfile                 # open 1
17434
17435         OPENS=$(changelog_dump | grep -c "OPEN")
17436         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17437
17438         # must be no MKDIR it wasn't set as user mask
17439         MKDIR=$(changelog_dump | grep -c "MKDIR")
17440         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17441
17442         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17443                                 mdd.$mdt.changelog_current_mask -n)
17444         # register maskless user
17445         changelog_register || error "changelog_register failed"
17446         # effective mask should be not changed because it is not minimal
17447         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17448                                 mdd.$mdt.changelog_current_mask -n)
17449         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17450         # set server mask to minimal value
17451         changelog_chmask "MARK"
17452         # check effective mask again, should be treated as DEFMASK now
17453         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17454                                 mdd.$mdt.changelog_current_mask -n)
17455         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17456
17457         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17458                 # set server mask back to some value
17459                 changelog_chmask "CLOSE,UNLNK"
17460                 # check effective mask again, should not remain as DEFMASK
17461                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17462                                 mdd.$mdt.changelog_current_mask -n)
17463                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17464         fi
17465
17466         do_facet $SINGLEMDS $LCTL --device $mdt \
17467                                 changelog_deregister -u test_160o ||
17468                 error "cannot deregister by name"
17469 }
17470 run_test 160o "changelog user name and mask"
17471
17472 test_160p() {
17473         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17474         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17475                 skip "Need MDS version at least 2.14.51"
17476         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17477         local cl_users
17478         local cl_user1
17479         local entry_count
17480
17481         # Create a user
17482         changelog_register || error "first changelog_register failed"
17483
17484         cl_users=(${CL_USERS[mds1]})
17485         cl_user1="${cl_users[0]}"
17486
17487         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17488         createmany -m $DIR/$tdir/$tfile 50 ||
17489                 error "create $DIR/$tdir/$tfile failed"
17490         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17491         rm -rf $DIR/$tdir
17492
17493         # check changelogs have been generated
17494         entry_count=$(changelog_dump | wc -l)
17495         ((entry_count != 0)) || error "no changelog entries found"
17496
17497         # remove changelog_users and check that orphan entries are removed
17498         stop mds1
17499         local dev=$(mdsdevname 1)
17500         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17501         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17502         entry_count=$(changelog_dump | wc -l)
17503         ((entry_count == 0)) ||
17504                 error "found $entry_count changelog entries, expected none"
17505 }
17506 run_test 160p "Changelog orphan cleanup with no users"
17507
17508 test_160q() {
17509         local mdt="$(facet_svc $SINGLEMDS)"
17510         local clu
17511
17512         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17513         remote_mds_nodsh && skip "remote MDS with nodsh"
17514         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17515                 skip "Need MDS version at least 2.14.54"
17516
17517         # set server mask to minimal value like server init does
17518         changelog_chmask "MARK"
17519         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17520                 error "changelog_register failed"
17521         # check effective mask again, should be treated as DEFMASK now
17522         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17523                                 mdd.$mdt.changelog_current_mask -n)
17524         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17525                 error "changelog_deregister failed"
17526         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17527 }
17528 run_test 160q "changelog effective mask is DEFMASK if not set"
17529
17530 test_160s() {
17531         remote_mds_nodsh && skip "remote MDS with nodsh"
17532         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17533                 skip "Need MDS version at least 2.14.55"
17534
17535         local mdts=$(comma_list $(mdts_nodes))
17536
17537         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17538         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17539                                        fail_val=$((24 * 3600 * 10))
17540
17541         # Create a user which is 10 days old
17542         changelog_register || error "first changelog_register failed"
17543         local cl_users
17544         declare -A cl_user1
17545         local i
17546
17547         # generate some changelog records to accumulate on each MDT
17548         # use all_char because created files should be evenly distributed
17549         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17550                 error "test_mkdir $tdir failed"
17551         for ((i = 0; i < MDSCOUNT; i++)); do
17552                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17553                         error "create $DIR/$tdir/d$i.1 failed"
17554         done
17555
17556         # check changelogs have been generated
17557         local nbcl=$(changelog_dump | wc -l)
17558         (( nbcl > 0 )) || error "no changelogs found"
17559
17560         # reduce the max_idle_indexes value to make sure we exceed it
17561         for param in "changelog_max_idle_indexes=2097446912" \
17562                      "changelog_max_idle_time=2592000" \
17563                      "changelog_gc=1" \
17564                      "changelog_min_gc_interval=2"; do
17565                 local MDT0=$(facet_svc $SINGLEMDS)
17566                 local var="${param%=*}"
17567                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17568
17569                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17570                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17571                         error "unable to set mdd.*.$param"
17572         done
17573
17574         local start=$SECONDS
17575         for i in $(seq $MDSCOUNT); do
17576                 cl_users=(${CL_USERS[mds$i]})
17577                 cl_user1[mds$i]="${cl_users[0]}"
17578
17579                 [[ -n "${cl_user1[mds$i]}" ]] ||
17580                         error "mds$i: no user registered"
17581         done
17582
17583         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17584         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17585
17586         # ensure we are past the previous changelog_min_gc_interval set above
17587         local sleep2=$((start + 2 - SECONDS))
17588         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17589
17590         # Generate one more changelog to trigger GC
17591         for ((i = 0; i < MDSCOUNT; i++)); do
17592                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17593                         error "create $DIR/$tdir/d$i.3 failed"
17594         done
17595
17596         # ensure gc thread is done
17597         for node in $(mdts_nodes); do
17598                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17599                         error "$node: GC-thread not done"
17600         done
17601
17602         do_nodes $mdts $LCTL set_param fail_loc=0
17603
17604         for (( i = 1; i <= MDSCOUNT; i++ )); do
17605                 # check cl_user1 is purged
17606                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17607                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17608         done
17609         return 0
17610 }
17611 run_test 160s "changelog garbage collect on idle records * time"
17612
17613 test_160t() {
17614         remote_mds_nodsh && skip "remote MDS with nodsh"
17615         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17616                 skip "Need MDS version at least 2.15.50"
17617
17618         local MDT0=$(facet_svc $SINGLEMDS)
17619         local cl_users
17620         local cl_user1
17621         local cl_user2
17622         local start
17623
17624         changelog_register --user user1 -m all ||
17625                 error "user1 failed to register"
17626
17627         mkdir_on_mdt0 $DIR/$tdir
17628         # create default overstripe to maximize changelog size
17629         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17630         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17631         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17632
17633         # user2 consumes less records so less space
17634         changelog_register --user user2 || error "user2 failed to register"
17635         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17636         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17637
17638         # check changelogs have been generated
17639         local nbcl=$(changelog_dump | wc -l)
17640         (( nbcl > 0 )) || error "no changelogs found"
17641
17642         # reduce the changelog_min_gc_interval to force check
17643         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17644                 local var="${param%=*}"
17645                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17646
17647                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17648                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17649                         error "unable to set mdd.*.$param"
17650         done
17651
17652         start=$SECONDS
17653         cl_users=(${CL_USERS[mds1]})
17654         cl_user1="${cl_users[0]}"
17655         cl_user2="${cl_users[1]}"
17656
17657         [[ -n $cl_user1 ]] ||
17658                 error "mds1: user #1 isn't registered"
17659         [[ -n $cl_user2 ]] ||
17660                 error "mds1: user #2 isn't registered"
17661
17662         # ensure we are past the previous changelog_min_gc_interval set above
17663         local sleep2=$((start + 2 - SECONDS))
17664         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17665
17666         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17667         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17668                         fail_val=$(((llog_size1 + llog_size2) / 2))
17669
17670         # Generate more changelog to trigger GC
17671         createmany -o $DIR/$tdir/u3_ 4 ||
17672                 error "create failed for more files"
17673
17674         # ensure gc thread is done
17675         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17676                 error "mds1: GC-thread not done"
17677
17678         do_facet mds1 $LCTL set_param fail_loc=0
17679
17680         # check cl_user1 is purged
17681         changelog_users mds1 | grep -q "$cl_user1" &&
17682                 error "User $cl_user1 is registered"
17683         # check cl_user2 is not purged
17684         changelog_users mds1 | grep -q "$cl_user2" ||
17685                 error "User $cl_user2 is not registered"
17686 }
17687 run_test 160t "changelog garbage collect on lack of space"
17688
17689 test_161a() {
17690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17691
17692         test_mkdir -c1 $DIR/$tdir
17693         cp /etc/hosts $DIR/$tdir/$tfile
17694         test_mkdir -c1 $DIR/$tdir/foo1
17695         test_mkdir -c1 $DIR/$tdir/foo2
17696         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17697         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17698         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17699         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17700         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17701         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17702                 $LFS fid2path $DIR $FID
17703                 error "bad link ea"
17704         fi
17705         # middle
17706         rm $DIR/$tdir/foo2/zachary
17707         # last
17708         rm $DIR/$tdir/foo2/thor
17709         # first
17710         rm $DIR/$tdir/$tfile
17711         # rename
17712         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17713         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17714                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17715         rm $DIR/$tdir/foo2/maggie
17716
17717         # overflow the EA
17718         local longname=$tfile.avg_len_is_thirty_two_
17719         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17720                 error_noexit 'failed to unlink many hardlinks'" EXIT
17721         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17722                 error "failed to hardlink many files"
17723         links=$($LFS fid2path $DIR $FID | wc -l)
17724         echo -n "${links}/1000 links in link EA"
17725         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17726 }
17727 run_test 161a "link ea sanity"
17728
17729 test_161b() {
17730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17731         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17732
17733         local MDTIDX=1
17734         local remote_dir=$DIR/$tdir/remote_dir
17735
17736         mkdir -p $DIR/$tdir
17737         $LFS mkdir -i $MDTIDX $remote_dir ||
17738                 error "create remote directory failed"
17739
17740         cp /etc/hosts $remote_dir/$tfile
17741         mkdir -p $remote_dir/foo1
17742         mkdir -p $remote_dir/foo2
17743         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17744         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17745         ln $remote_dir/$tfile $remote_dir/foo1/luna
17746         ln $remote_dir/$tfile $remote_dir/foo2/thor
17747
17748         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17749                      tr -d ']')
17750         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17751                 $LFS fid2path $DIR $FID
17752                 error "bad link ea"
17753         fi
17754         # middle
17755         rm $remote_dir/foo2/zachary
17756         # last
17757         rm $remote_dir/foo2/thor
17758         # first
17759         rm $remote_dir/$tfile
17760         # rename
17761         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17762         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17763         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17764                 $LFS fid2path $DIR $FID
17765                 error "bad link rename"
17766         fi
17767         rm $remote_dir/foo2/maggie
17768
17769         # overflow the EA
17770         local longname=filename_avg_len_is_thirty_two_
17771         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17772                 error "failed to hardlink many files"
17773         links=$($LFS fid2path $DIR $FID | wc -l)
17774         echo -n "${links}/1000 links in link EA"
17775         [[ ${links} -gt 60 ]] ||
17776                 error "expected at least 60 links in link EA"
17777         unlinkmany $remote_dir/foo2/$longname 1000 ||
17778         error "failed to unlink many hardlinks"
17779 }
17780 run_test 161b "link ea sanity under remote directory"
17781
17782 test_161c() {
17783         remote_mds_nodsh && skip "remote MDS with nodsh"
17784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17785         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17786                 skip "Need MDS version at least 2.1.5"
17787
17788         # define CLF_RENAME_LAST 0x0001
17789         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17790         changelog_register || error "changelog_register failed"
17791
17792         rm -rf $DIR/$tdir
17793         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17794         touch $DIR/$tdir/foo_161c
17795         touch $DIR/$tdir/bar_161c
17796         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17797         changelog_dump | grep RENME | tail -n 5
17798         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17799         changelog_clear 0 || error "changelog_clear failed"
17800         if [ x$flags != "x0x1" ]; then
17801                 error "flag $flags is not 0x1"
17802         fi
17803
17804         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17805         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17806         touch $DIR/$tdir/foo_161c
17807         touch $DIR/$tdir/bar_161c
17808         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17809         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17810         changelog_dump | grep RENME | tail -n 5
17811         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17812         changelog_clear 0 || error "changelog_clear failed"
17813         if [ x$flags != "x0x0" ]; then
17814                 error "flag $flags is not 0x0"
17815         fi
17816         echo "rename overwrite a target having nlink > 1," \
17817                 "changelog record has flags of $flags"
17818
17819         # rename doesn't overwrite a target (changelog flag 0x0)
17820         touch $DIR/$tdir/foo_161c
17821         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17822         changelog_dump | grep RENME | tail -n 5
17823         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17824         changelog_clear 0 || error "changelog_clear failed"
17825         if [ x$flags != "x0x0" ]; then
17826                 error "flag $flags is not 0x0"
17827         fi
17828         echo "rename doesn't overwrite a target," \
17829                 "changelog record has flags of $flags"
17830
17831         # define CLF_UNLINK_LAST 0x0001
17832         # unlink a file having nlink = 1 (changelog flag 0x1)
17833         rm -f $DIR/$tdir/foo2_161c
17834         changelog_dump | grep UNLNK | tail -n 5
17835         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17836         changelog_clear 0 || error "changelog_clear failed"
17837         if [ x$flags != "x0x1" ]; then
17838                 error "flag $flags is not 0x1"
17839         fi
17840         echo "unlink a file having nlink = 1," \
17841                 "changelog record has flags of $flags"
17842
17843         # unlink a file having nlink > 1 (changelog flag 0x0)
17844         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17845         rm -f $DIR/$tdir/foobar_161c
17846         changelog_dump | grep UNLNK | tail -n 5
17847         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17848         changelog_clear 0 || error "changelog_clear failed"
17849         if [ x$flags != "x0x0" ]; then
17850                 error "flag $flags is not 0x0"
17851         fi
17852         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17853 }
17854 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17855
17856 test_161d() {
17857         remote_mds_nodsh && skip "remote MDS with nodsh"
17858         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17859
17860         local pid
17861         local fid
17862
17863         changelog_register || error "changelog_register failed"
17864
17865         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17866         # interfer with $MOUNT/.lustre/fid/ access
17867         mkdir $DIR/$tdir
17868         [[ $? -eq 0 ]] || error "mkdir failed"
17869
17870         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17871         $LCTL set_param fail_loc=0x8000140c
17872         # 5s pause
17873         $LCTL set_param fail_val=5
17874
17875         # create file
17876         echo foofoo > $DIR/$tdir/$tfile &
17877         pid=$!
17878
17879         # wait for create to be delayed
17880         sleep 2
17881
17882         ps -p $pid
17883         [[ $? -eq 0 ]] || error "create should be blocked"
17884
17885         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17886         stack_trap "rm -f $tempfile"
17887         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17888         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17889         # some delay may occur during ChangeLog publishing and file read just
17890         # above, that could allow file write to happen finally
17891         [[ -s $tempfile ]] && echo "file should be empty"
17892
17893         $LCTL set_param fail_loc=0
17894
17895         wait $pid
17896         [[ $? -eq 0 ]] || error "create failed"
17897 }
17898 run_test 161d "create with concurrent .lustre/fid access"
17899
17900 check_path() {
17901         local expected="$1"
17902         shift
17903         local fid="$2"
17904
17905         local path
17906         path=$($LFS fid2path "$@")
17907         local rc=$?
17908
17909         if [ $rc -ne 0 ]; then
17910                 error "path looked up of '$expected' failed: rc=$rc"
17911         elif [ "$path" != "$expected" ]; then
17912                 error "path looked up '$path' instead of '$expected'"
17913         else
17914                 echo "FID '$fid' resolves to path '$path' as expected"
17915         fi
17916 }
17917
17918 test_162a() { # was test_162
17919         test_mkdir -p -c1 $DIR/$tdir/d2
17920         touch $DIR/$tdir/d2/$tfile
17921         touch $DIR/$tdir/d2/x1
17922         touch $DIR/$tdir/d2/x2
17923         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17924         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17925         # regular file
17926         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17927         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17928
17929         # softlink
17930         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17931         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17932         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17933
17934         # softlink to wrong file
17935         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17936         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17937         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17938
17939         # hardlink
17940         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17941         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17942         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17943         # fid2path dir/fsname should both work
17944         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17945         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17946
17947         # hardlink count: check that there are 2 links
17948         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17949         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17950
17951         # hardlink indexing: remove the first link
17952         rm $DIR/$tdir/d2/p/q/r/hlink
17953         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17954 }
17955 run_test 162a "path lookup sanity"
17956
17957 test_162b() {
17958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17960
17961         mkdir $DIR/$tdir
17962         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17963                                 error "create striped dir failed"
17964
17965         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17966                                         tail -n 1 | awk '{print $2}')
17967         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17968
17969         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17970         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17971
17972         # regular file
17973         for ((i=0;i<5;i++)); do
17974                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17975                         error "get fid for f$i failed"
17976                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17977
17978                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17979                         error "get fid for d$i failed"
17980                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17981         done
17982
17983         return 0
17984 }
17985 run_test 162b "striped directory path lookup sanity"
17986
17987 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17988 test_162c() {
17989         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17990                 skip "Need MDS version at least 2.7.51"
17991
17992         local lpath=$tdir.local
17993         local rpath=$tdir.remote
17994
17995         test_mkdir $DIR/$lpath
17996         test_mkdir $DIR/$rpath
17997
17998         for ((i = 0; i <= 101; i++)); do
17999                 lpath="$lpath/$i"
18000                 mkdir $DIR/$lpath
18001                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18002                         error "get fid for local directory $DIR/$lpath failed"
18003                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18004
18005                 rpath="$rpath/$i"
18006                 test_mkdir $DIR/$rpath
18007                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18008                         error "get fid for remote directory $DIR/$rpath failed"
18009                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18010         done
18011
18012         return 0
18013 }
18014 run_test 162c "fid2path works with paths 100 or more directories deep"
18015
18016 oalr_event_count() {
18017         local event="${1}"
18018         local trace="${2}"
18019
18020         awk -v name="${FSNAME}-OST0000" \
18021             -v event="${event}" \
18022             '$1 == "TRACE" && $2 == event && $3 == name' \
18023             "${trace}" |
18024         wc -l
18025 }
18026
18027 oalr_expect_event_count() {
18028         local event="${1}"
18029         local trace="${2}"
18030         local expect="${3}"
18031         local count
18032
18033         count=$(oalr_event_count "${event}" "${trace}")
18034         if ((count == expect)); then
18035                 return 0
18036         fi
18037
18038         error_noexit "${event} event count was '${count}', expected ${expect}"
18039         cat "${trace}" >&2
18040         exit 1
18041 }
18042
18043 cleanup_165() {
18044         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18045         stop ost1
18046         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18047 }
18048
18049 setup_165() {
18050         sync # Flush previous IOs so we can count log entries.
18051         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18052         stack_trap cleanup_165 EXIT
18053 }
18054
18055 test_165a() {
18056         local trace="/tmp/${tfile}.trace"
18057         local rc
18058         local count
18059
18060         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18061                 skip "OFD access log unsupported"
18062
18063         setup_165
18064         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18065         sleep 5
18066
18067         do_facet ost1 ofd_access_log_reader --list
18068         stop ost1
18069
18070         do_facet ost1 killall -TERM ofd_access_log_reader
18071         wait
18072         rc=$?
18073
18074         if ((rc != 0)); then
18075                 error "ofd_access_log_reader exited with rc = '${rc}'"
18076         fi
18077
18078         # Parse trace file for discovery events:
18079         oalr_expect_event_count alr_log_add "${trace}" 1
18080         oalr_expect_event_count alr_log_eof "${trace}" 1
18081         oalr_expect_event_count alr_log_free "${trace}" 1
18082 }
18083 run_test 165a "ofd access log discovery"
18084
18085 test_165b() {
18086         local trace="/tmp/${tfile}.trace"
18087         local file="${DIR}/${tfile}"
18088         local pfid1
18089         local pfid2
18090         local -a entry
18091         local rc
18092         local count
18093         local size
18094         local flags
18095
18096         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18097                 skip "OFD access log unsupported"
18098
18099         setup_165
18100         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18101         sleep 5
18102
18103         do_facet ost1 ofd_access_log_reader --list
18104
18105         lfs setstripe -c 1 -i 0 "${file}"
18106         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18107                 error "cannot create '${file}'"
18108
18109         sleep 5
18110         do_facet ost1 killall -TERM ofd_access_log_reader
18111         wait
18112         rc=$?
18113
18114         if ((rc != 0)); then
18115                 error "ofd_access_log_reader exited with rc = '${rc}'"
18116         fi
18117
18118         oalr_expect_event_count alr_log_entry "${trace}" 1
18119
18120         pfid1=$($LFS path2fid "${file}")
18121
18122         # 1     2             3   4    5     6   7    8    9     10
18123         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18124         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18125
18126         echo "entry = '${entry[*]}'" >&2
18127
18128         pfid2=${entry[4]}
18129         if [[ "${pfid1}" != "${pfid2}" ]]; then
18130                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18131         fi
18132
18133         size=${entry[8]}
18134         if ((size != 1048576)); then
18135                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18136         fi
18137
18138         flags=${entry[10]}
18139         if [[ "${flags}" != "w" ]]; then
18140                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18141         fi
18142
18143         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18144         sleep 5
18145
18146         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18147                 error "cannot read '${file}'"
18148         sleep 5
18149
18150         do_facet ost1 killall -TERM ofd_access_log_reader
18151         wait
18152         rc=$?
18153
18154         if ((rc != 0)); then
18155                 error "ofd_access_log_reader exited with rc = '${rc}'"
18156         fi
18157
18158         oalr_expect_event_count alr_log_entry "${trace}" 1
18159
18160         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18161         echo "entry = '${entry[*]}'" >&2
18162
18163         pfid2=${entry[4]}
18164         if [[ "${pfid1}" != "${pfid2}" ]]; then
18165                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18166         fi
18167
18168         size=${entry[8]}
18169         if ((size != 524288)); then
18170                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18171         fi
18172
18173         flags=${entry[10]}
18174         if [[ "${flags}" != "r" ]]; then
18175                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18176         fi
18177 }
18178 run_test 165b "ofd access log entries are produced and consumed"
18179
18180 test_165c() {
18181         local trace="/tmp/${tfile}.trace"
18182         local file="${DIR}/${tdir}/${tfile}"
18183
18184         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18185                 skip "OFD access log unsupported"
18186
18187         test_mkdir "${DIR}/${tdir}"
18188
18189         setup_165
18190         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18191         sleep 5
18192
18193         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18194
18195         # 4096 / 64 = 64. Create twice as many entries.
18196         for ((i = 0; i < 128; i++)); do
18197                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18198                         error "cannot create file"
18199         done
18200
18201         sync
18202
18203         do_facet ost1 killall -TERM ofd_access_log_reader
18204         wait
18205         rc=$?
18206         if ((rc != 0)); then
18207                 error "ofd_access_log_reader exited with rc = '${rc}'"
18208         fi
18209
18210         unlinkmany  "${file}-%d" 128
18211 }
18212 run_test 165c "full ofd access logs do not block IOs"
18213
18214 oal_get_read_count() {
18215         local stats="$1"
18216
18217         # STATS lustre-OST0001 alr_read_count 1
18218
18219         do_facet ost1 cat "${stats}" |
18220         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18221              END { print count; }'
18222 }
18223
18224 oal_expect_read_count() {
18225         local stats="$1"
18226         local count
18227         local expect="$2"
18228
18229         # Ask ofd_access_log_reader to write stats.
18230         do_facet ost1 killall -USR1 ofd_access_log_reader
18231
18232         # Allow some time for things to happen.
18233         sleep 1
18234
18235         count=$(oal_get_read_count "${stats}")
18236         if ((count == expect)); then
18237                 return 0
18238         fi
18239
18240         error_noexit "bad read count, got ${count}, expected ${expect}"
18241         do_facet ost1 cat "${stats}" >&2
18242         exit 1
18243 }
18244
18245 test_165d() {
18246         local stats="/tmp/${tfile}.stats"
18247         local file="${DIR}/${tdir}/${tfile}"
18248         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18249
18250         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18251                 skip "OFD access log unsupported"
18252
18253         test_mkdir "${DIR}/${tdir}"
18254
18255         setup_165
18256         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18257         sleep 5
18258
18259         lfs setstripe -c 1 -i 0 "${file}"
18260
18261         do_facet ost1 lctl set_param "${param}=rw"
18262         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18263                 error "cannot create '${file}'"
18264         oal_expect_read_count "${stats}" 1
18265
18266         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18267                 error "cannot read '${file}'"
18268         oal_expect_read_count "${stats}" 2
18269
18270         do_facet ost1 lctl set_param "${param}=r"
18271         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18272                 error "cannot create '${file}'"
18273         oal_expect_read_count "${stats}" 2
18274
18275         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18276                 error "cannot read '${file}'"
18277         oal_expect_read_count "${stats}" 3
18278
18279         do_facet ost1 lctl set_param "${param}=w"
18280         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18281                 error "cannot create '${file}'"
18282         oal_expect_read_count "${stats}" 4
18283
18284         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18285                 error "cannot read '${file}'"
18286         oal_expect_read_count "${stats}" 4
18287
18288         do_facet ost1 lctl set_param "${param}=0"
18289         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18290                 error "cannot create '${file}'"
18291         oal_expect_read_count "${stats}" 4
18292
18293         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18294                 error "cannot read '${file}'"
18295         oal_expect_read_count "${stats}" 4
18296
18297         do_facet ost1 killall -TERM ofd_access_log_reader
18298         wait
18299         rc=$?
18300         if ((rc != 0)); then
18301                 error "ofd_access_log_reader exited with rc = '${rc}'"
18302         fi
18303 }
18304 run_test 165d "ofd_access_log mask works"
18305
18306 test_165e() {
18307         local stats="/tmp/${tfile}.stats"
18308         local file0="${DIR}/${tdir}-0/${tfile}"
18309         local file1="${DIR}/${tdir}-1/${tfile}"
18310
18311         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18312                 skip "OFD access log unsupported"
18313
18314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18315
18316         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18317         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18318
18319         lfs setstripe -c 1 -i 0 "${file0}"
18320         lfs setstripe -c 1 -i 0 "${file1}"
18321
18322         setup_165
18323         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18324         sleep 5
18325
18326         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18327                 error "cannot create '${file0}'"
18328         sync
18329         oal_expect_read_count "${stats}" 0
18330
18331         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18332                 error "cannot create '${file1}'"
18333         sync
18334         oal_expect_read_count "${stats}" 1
18335
18336         do_facet ost1 killall -TERM ofd_access_log_reader
18337         wait
18338         rc=$?
18339         if ((rc != 0)); then
18340                 error "ofd_access_log_reader exited with rc = '${rc}'"
18341         fi
18342 }
18343 run_test 165e "ofd_access_log MDT index filter works"
18344
18345 test_165f() {
18346         local trace="/tmp/${tfile}.trace"
18347         local rc
18348         local count
18349
18350         setup_165
18351         do_facet ost1 timeout 60 ofd_access_log_reader \
18352                 --exit-on-close --debug=- --trace=- > "${trace}" &
18353         sleep 5
18354         stop ost1
18355
18356         wait
18357         rc=$?
18358
18359         if ((rc != 0)); then
18360                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18361                 cat "${trace}"
18362                 exit 1
18363         fi
18364 }
18365 run_test 165f "ofd_access_log_reader --exit-on-close works"
18366
18367 test_169() {
18368         # do directio so as not to populate the page cache
18369         log "creating a 10 Mb file"
18370         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18371                 error "multiop failed while creating a file"
18372         log "starting reads"
18373         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18374         log "truncating the file"
18375         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18376                 error "multiop failed while truncating the file"
18377         log "killing dd"
18378         kill %+ || true # reads might have finished
18379         echo "wait until dd is finished"
18380         wait
18381         log "removing the temporary file"
18382         rm -rf $DIR/$tfile || error "tmp file removal failed"
18383 }
18384 run_test 169 "parallel read and truncate should not deadlock"
18385
18386 test_170() {
18387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18388
18389         $LCTL clear     # bug 18514
18390         $LCTL debug_daemon start $TMP/${tfile}_log_good
18391         touch $DIR/$tfile
18392         $LCTL debug_daemon stop
18393         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18394                 error "sed failed to read log_good"
18395
18396         $LCTL debug_daemon start $TMP/${tfile}_log_good
18397         rm -rf $DIR/$tfile
18398         $LCTL debug_daemon stop
18399
18400         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18401                error "lctl df log_bad failed"
18402
18403         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18404         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18405
18406         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18407         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18408
18409         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18410                 error "bad_line good_line1 good_line2 are empty"
18411
18412         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18413         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18414         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18415
18416         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18417         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18418         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18419
18420         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18421                 error "bad_line_new good_line_new are empty"
18422
18423         local expected_good=$((good_line1 + good_line2*2))
18424
18425         rm -f $TMP/${tfile}*
18426         # LU-231, short malformed line may not be counted into bad lines
18427         if [ $bad_line -ne $bad_line_new ] &&
18428                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18429                 error "expected $bad_line bad lines, but got $bad_line_new"
18430                 return 1
18431         fi
18432
18433         if [ $expected_good -ne $good_line_new ]; then
18434                 error "expected $expected_good good lines, but got $good_line_new"
18435                 return 2
18436         fi
18437         true
18438 }
18439 run_test 170 "test lctl df to handle corrupted log ====================="
18440
18441 test_171() { # bug20592
18442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18443
18444         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18445         $LCTL set_param fail_loc=0x50e
18446         $LCTL set_param fail_val=3000
18447         multiop_bg_pause $DIR/$tfile O_s || true
18448         local MULTIPID=$!
18449         kill -USR1 $MULTIPID
18450         # cause log dump
18451         sleep 3
18452         wait $MULTIPID
18453         if dmesg | grep "recursive fault"; then
18454                 error "caught a recursive fault"
18455         fi
18456         $LCTL set_param fail_loc=0
18457         true
18458 }
18459 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18460
18461 test_172() {
18462
18463         #define OBD_FAIL_OBD_CLEANUP  0x60e
18464         $LCTL set_param fail_loc=0x60e
18465         umount $MOUNT || error "umount $MOUNT failed"
18466         stack_trap "mount_client $MOUNT"
18467
18468         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18469                 error "no client OBDs are remained"
18470
18471         $LCTL dl | while read devno state type name foo; do
18472                 case $type in
18473                 lov|osc|lmv|mdc)
18474                         $LCTL --device $name cleanup
18475                         $LCTL --device $name detach
18476                         ;;
18477                 *)
18478                         # skip server devices
18479                         ;;
18480                 esac
18481         done
18482
18483         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18484                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18485                 error "some client OBDs are still remained"
18486         fi
18487
18488 }
18489 run_test 172 "manual device removal with lctl cleanup/detach ======"
18490
18491 # it would be good to share it with obdfilter-survey/iokit-libecho code
18492 setup_obdecho_osc () {
18493         local rc=0
18494         local ost_nid=$1
18495         local obdfilter_name=$2
18496         echo "Creating new osc for $obdfilter_name on $ost_nid"
18497         # make sure we can find loopback nid
18498         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18499
18500         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18501                            ${obdfilter_name}_osc_UUID || rc=2; }
18502         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18503                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18504         return $rc
18505 }
18506
18507 cleanup_obdecho_osc () {
18508         local obdfilter_name=$1
18509         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18510         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18511         return 0
18512 }
18513
18514 obdecho_test() {
18515         local OBD=$1
18516         local node=$2
18517         local pages=${3:-64}
18518         local rc=0
18519         local id
18520
18521         local count=10
18522         local obd_size=$(get_obd_size $node $OBD)
18523         local page_size=$(get_page_size $node)
18524         if [[ -n "$obd_size" ]]; then
18525                 local new_count=$((obd_size / (pages * page_size / 1024)))
18526                 [[ $new_count -ge $count ]] || count=$new_count
18527         fi
18528
18529         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18530         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18531                            rc=2; }
18532         if [ $rc -eq 0 ]; then
18533             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18534             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18535         fi
18536         echo "New object id is $id"
18537         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18538                            rc=4; }
18539         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18540                            "test_brw $count w v $pages $id" || rc=4; }
18541         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18542                            rc=4; }
18543         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18544                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18545         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18546                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18547         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18548         return $rc
18549 }
18550
18551 test_180a() {
18552         skip "obdecho on osc is no longer supported"
18553 }
18554 run_test 180a "test obdecho on osc"
18555
18556 test_180b() {
18557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18558         remote_ost_nodsh && skip "remote OST with nodsh"
18559
18560         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18561                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18562                 error "failed to load module obdecho"
18563
18564         local target=$(do_facet ost1 $LCTL dl |
18565                        awk '/obdfilter/ { print $4; exit; }')
18566
18567         if [ -n "$target" ]; then
18568                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18569         else
18570                 do_facet ost1 $LCTL dl
18571                 error "there is no obdfilter target on ost1"
18572         fi
18573 }
18574 run_test 180b "test obdecho directly on obdfilter"
18575
18576 test_180c() { # LU-2598
18577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18578         remote_ost_nodsh && skip "remote OST with nodsh"
18579         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18580                 skip "Need MDS version at least 2.4.0"
18581
18582         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18583                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18584                 error "failed to load module obdecho"
18585
18586         local target=$(do_facet ost1 $LCTL dl |
18587                        awk '/obdfilter/ { print $4; exit; }')
18588
18589         if [ -n "$target" ]; then
18590                 local pages=16384 # 64MB bulk I/O RPC size
18591
18592                 obdecho_test "$target" ost1 "$pages" ||
18593                         error "obdecho_test with pages=$pages failed with $?"
18594         else
18595                 do_facet ost1 $LCTL dl
18596                 error "there is no obdfilter target on ost1"
18597         fi
18598 }
18599 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18600
18601 test_181() { # bug 22177
18602         test_mkdir $DIR/$tdir
18603         # create enough files to index the directory
18604         createmany -o $DIR/$tdir/foobar 4000
18605         # print attributes for debug purpose
18606         lsattr -d .
18607         # open dir
18608         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18609         MULTIPID=$!
18610         # remove the files & current working dir
18611         unlinkmany $DIR/$tdir/foobar 4000
18612         rmdir $DIR/$tdir
18613         kill -USR1 $MULTIPID
18614         wait $MULTIPID
18615         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18616         return 0
18617 }
18618 run_test 181 "Test open-unlinked dir ========================"
18619
18620 test_182a() {
18621         local fcount=1000
18622         local tcount=10
18623
18624         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18625
18626         $LCTL set_param mdc.*.rpc_stats=clear
18627
18628         for (( i = 0; i < $tcount; i++ )) ; do
18629                 mkdir $DIR/$tdir/$i
18630         done
18631
18632         for (( i = 0; i < $tcount; i++ )) ; do
18633                 createmany -o $DIR/$tdir/$i/f- $fcount &
18634         done
18635         wait
18636
18637         for (( i = 0; i < $tcount; i++ )) ; do
18638                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18639         done
18640         wait
18641
18642         $LCTL get_param mdc.*.rpc_stats
18643
18644         rm -rf $DIR/$tdir
18645 }
18646 run_test 182a "Test parallel modify metadata operations from mdc"
18647
18648 test_182b() {
18649         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18650         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18651         local dcount=1000
18652         local tcount=10
18653         local stime
18654         local etime
18655         local delta
18656
18657         do_facet mds1 $LCTL list_param \
18658                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18659                 skip "MDS lacks parallel RPC handling"
18660
18661         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18662
18663         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18664                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18665
18666         stime=$(date +%s)
18667         createmany -i 0 -d $DIR/$tdir/t- $tcount
18668
18669         for (( i = 0; i < $tcount; i++ )) ; do
18670                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18671         done
18672         wait
18673         etime=$(date +%s)
18674         delta=$((etime - stime))
18675         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18676
18677         stime=$(date +%s)
18678         for (( i = 0; i < $tcount; i++ )) ; do
18679                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18680         done
18681         wait
18682         etime=$(date +%s)
18683         delta=$((etime - stime))
18684         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18685
18686         rm -rf $DIR/$tdir
18687
18688         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18689
18690         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18691
18692         stime=$(date +%s)
18693         createmany -i 0 -d $DIR/$tdir/t- $tcount
18694
18695         for (( i = 0; i < $tcount; i++ )) ; do
18696                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18697         done
18698         wait
18699         etime=$(date +%s)
18700         delta=$((etime - stime))
18701         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18702
18703         stime=$(date +%s)
18704         for (( i = 0; i < $tcount; i++ )) ; do
18705                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18706         done
18707         wait
18708         etime=$(date +%s)
18709         delta=$((etime - stime))
18710         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18711
18712         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18713 }
18714 run_test 182b "Test parallel modify metadata operations from osp"
18715
18716 test_183() { # LU-2275
18717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18718         remote_mds_nodsh && skip "remote MDS with nodsh"
18719         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18720                 skip "Need MDS version at least 2.3.56"
18721
18722         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18723         echo aaa > $DIR/$tdir/$tfile
18724
18725 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18726         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18727
18728         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18729         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18730
18731         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18732
18733         # Flush negative dentry cache
18734         touch $DIR/$tdir/$tfile
18735
18736         # We are not checking for any leaked references here, they'll
18737         # become evident next time we do cleanup with module unload.
18738         rm -rf $DIR/$tdir
18739 }
18740 run_test 183 "No crash or request leak in case of strange dispositions ========"
18741
18742 # test suite 184 is for LU-2016, LU-2017
18743 test_184a() {
18744         check_swap_layouts_support
18745
18746         dir0=$DIR/$tdir/$testnum
18747         test_mkdir -p -c1 $dir0
18748         ref1=/etc/passwd
18749         ref2=/etc/group
18750         file1=$dir0/f1
18751         file2=$dir0/f2
18752         $LFS setstripe -c1 $file1
18753         cp $ref1 $file1
18754         $LFS setstripe -c2 $file2
18755         cp $ref2 $file2
18756         gen1=$($LFS getstripe -g $file1)
18757         gen2=$($LFS getstripe -g $file2)
18758
18759         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18760         gen=$($LFS getstripe -g $file1)
18761         [[ $gen1 != $gen ]] ||
18762                 error "Layout generation on $file1 does not change"
18763         gen=$($LFS getstripe -g $file2)
18764         [[ $gen2 != $gen ]] ||
18765                 error "Layout generation on $file2 does not change"
18766
18767         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18768         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18769
18770         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18771 }
18772 run_test 184a "Basic layout swap"
18773
18774 test_184b() {
18775         check_swap_layouts_support
18776
18777         dir0=$DIR/$tdir/$testnum
18778         mkdir -p $dir0 || error "creating dir $dir0"
18779         file1=$dir0/f1
18780         file2=$dir0/f2
18781         file3=$dir0/f3
18782         dir1=$dir0/d1
18783         dir2=$dir0/d2
18784         mkdir $dir1 $dir2
18785         $LFS setstripe -c1 $file1
18786         $LFS setstripe -c2 $file2
18787         $LFS setstripe -c1 $file3
18788         chown $RUNAS_ID $file3
18789         gen1=$($LFS getstripe -g $file1)
18790         gen2=$($LFS getstripe -g $file2)
18791
18792         $LFS swap_layouts $dir1 $dir2 &&
18793                 error "swap of directories layouts should fail"
18794         $LFS swap_layouts $dir1 $file1 &&
18795                 error "swap of directory and file layouts should fail"
18796         $RUNAS $LFS swap_layouts $file1 $file2 &&
18797                 error "swap of file we cannot write should fail"
18798         $LFS swap_layouts $file1 $file3 &&
18799                 error "swap of file with different owner should fail"
18800         /bin/true # to clear error code
18801 }
18802 run_test 184b "Forbidden layout swap (will generate errors)"
18803
18804 test_184c() {
18805         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18806         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18807         check_swap_layouts_support
18808         check_swap_layout_no_dom $DIR
18809
18810         local dir0=$DIR/$tdir/$testnum
18811         mkdir -p $dir0 || error "creating dir $dir0"
18812
18813         local ref1=$dir0/ref1
18814         local ref2=$dir0/ref2
18815         local file1=$dir0/file1
18816         local file2=$dir0/file2
18817         # create a file large enough for the concurrent test
18818         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18819         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18820         echo "ref file size: ref1($(stat -c %s $ref1))," \
18821              "ref2($(stat -c %s $ref2))"
18822
18823         cp $ref2 $file2
18824         dd if=$ref1 of=$file1 bs=16k &
18825         local DD_PID=$!
18826
18827         # Make sure dd starts to copy file, but wait at most 5 seconds
18828         local loops=0
18829         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18830
18831         $LFS swap_layouts $file1 $file2
18832         local rc=$?
18833         wait $DD_PID
18834         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18835         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18836
18837         # how many bytes copied before swapping layout
18838         local copied=$(stat -c %s $file2)
18839         local remaining=$(stat -c %s $ref1)
18840         remaining=$((remaining - copied))
18841         echo "Copied $copied bytes before swapping layout..."
18842
18843         cmp -n $copied $file1 $ref2 | grep differ &&
18844                 error "Content mismatch [0, $copied) of ref2 and file1"
18845         cmp -n $copied $file2 $ref1 ||
18846                 error "Content mismatch [0, $copied) of ref1 and file2"
18847         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18848                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18849
18850         # clean up
18851         rm -f $ref1 $ref2 $file1 $file2
18852 }
18853 run_test 184c "Concurrent write and layout swap"
18854
18855 test_184d() {
18856         check_swap_layouts_support
18857         check_swap_layout_no_dom $DIR
18858         [ -z "$(which getfattr 2>/dev/null)" ] &&
18859                 skip_env "no getfattr command"
18860
18861         local file1=$DIR/$tdir/$tfile-1
18862         local file2=$DIR/$tdir/$tfile-2
18863         local file3=$DIR/$tdir/$tfile-3
18864         local lovea1
18865         local lovea2
18866
18867         mkdir -p $DIR/$tdir
18868         touch $file1 || error "create $file1 failed"
18869         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18870                 error "create $file2 failed"
18871         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18872                 error "create $file3 failed"
18873         lovea1=$(get_layout_param $file1)
18874
18875         $LFS swap_layouts $file2 $file3 ||
18876                 error "swap $file2 $file3 layouts failed"
18877         $LFS swap_layouts $file1 $file2 ||
18878                 error "swap $file1 $file2 layouts failed"
18879
18880         lovea2=$(get_layout_param $file2)
18881         echo "$lovea1"
18882         echo "$lovea2"
18883         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18884
18885         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18886         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18887 }
18888 run_test 184d "allow stripeless layouts swap"
18889
18890 test_184e() {
18891         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18892                 skip "Need MDS version at least 2.6.94"
18893         check_swap_layouts_support
18894         check_swap_layout_no_dom $DIR
18895         [ -z "$(which getfattr 2>/dev/null)" ] &&
18896                 skip_env "no getfattr command"
18897
18898         local file1=$DIR/$tdir/$tfile-1
18899         local file2=$DIR/$tdir/$tfile-2
18900         local file3=$DIR/$tdir/$tfile-3
18901         local lovea
18902
18903         mkdir -p $DIR/$tdir
18904         touch $file1 || error "create $file1 failed"
18905         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18906                 error "create $file2 failed"
18907         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18908                 error "create $file3 failed"
18909
18910         $LFS swap_layouts $file1 $file2 ||
18911                 error "swap $file1 $file2 layouts failed"
18912
18913         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18914         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18915
18916         echo 123 > $file1 || error "Should be able to write into $file1"
18917
18918         $LFS swap_layouts $file1 $file3 ||
18919                 error "swap $file1 $file3 layouts failed"
18920
18921         echo 123 > $file1 || error "Should be able to write into $file1"
18922
18923         rm -rf $file1 $file2 $file3
18924 }
18925 run_test 184e "Recreate layout after stripeless layout swaps"
18926
18927 test_184f() {
18928         # Create a file with name longer than sizeof(struct stat) ==
18929         # 144 to see if we can get chars from the file name to appear
18930         # in the returned striping. Note that 'f' == 0x66.
18931         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18932
18933         mkdir -p $DIR/$tdir
18934         mcreate $DIR/$tdir/$file
18935         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18936                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18937         fi
18938 }
18939 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18940
18941 test_185() { # LU-2441
18942         # LU-3553 - no volatile file support in old servers
18943         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18944                 skip "Need MDS version at least 2.3.60"
18945
18946         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18947         touch $DIR/$tdir/spoo
18948         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18949         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18950                 error "cannot create/write a volatile file"
18951         [ "$FILESET" == "" ] &&
18952         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18953                 error "FID is still valid after close"
18954
18955         multiop_bg_pause $DIR/$tdir vVw4096_c
18956         local multi_pid=$!
18957
18958         local OLD_IFS=$IFS
18959         IFS=":"
18960         local fidv=($fid)
18961         IFS=$OLD_IFS
18962         # assume that the next FID for this client is sequential, since stdout
18963         # is unfortunately eaten by multiop_bg_pause
18964         local n=$((${fidv[1]} + 1))
18965         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18966         if [ "$FILESET" == "" ]; then
18967                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18968                         error "FID is missing before close"
18969         fi
18970         kill -USR1 $multi_pid
18971         # 1 second delay, so if mtime change we will see it
18972         sleep 1
18973         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18974         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18975 }
18976 run_test 185 "Volatile file support"
18977
18978 function create_check_volatile() {
18979         local idx=$1
18980         local tgt
18981
18982         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18983         local PID=$!
18984         sleep 1
18985         local FID=$(cat /tmp/${tfile}.fid)
18986         [ "$FID" == "" ] && error "can't get FID for volatile"
18987         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18988         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18989         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18990         kill -USR1 $PID
18991         wait
18992         sleep 1
18993         cancel_lru_locks mdc # flush opencache
18994         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18995         return 0
18996 }
18997
18998 test_185a(){
18999         # LU-12516 - volatile creation via .lustre
19000         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19001                 skip "Need MDS version at least 2.3.55"
19002
19003         create_check_volatile 0
19004         [ $MDSCOUNT -lt 2 ] && return 0
19005
19006         # DNE case
19007         create_check_volatile 1
19008
19009         return 0
19010 }
19011 run_test 185a "Volatile file creation in .lustre/fid/"
19012
19013 test_187a() {
19014         remote_mds_nodsh && skip "remote MDS with nodsh"
19015         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19016                 skip "Need MDS version at least 2.3.0"
19017
19018         local dir0=$DIR/$tdir/$testnum
19019         mkdir -p $dir0 || error "creating dir $dir0"
19020
19021         local file=$dir0/file1
19022         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19023         local dv1=$($LFS data_version $file)
19024         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19025         local dv2=$($LFS data_version $file)
19026         [[ $dv1 != $dv2 ]] ||
19027                 error "data version did not change on write $dv1 == $dv2"
19028
19029         # clean up
19030         rm -f $file1
19031 }
19032 run_test 187a "Test data version change"
19033
19034 test_187b() {
19035         remote_mds_nodsh && skip "remote MDS with nodsh"
19036         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19037                 skip "Need MDS version at least 2.3.0"
19038
19039         local dir0=$DIR/$tdir/$testnum
19040         mkdir -p $dir0 || error "creating dir $dir0"
19041
19042         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19043         [[ ${DV[0]} != ${DV[1]} ]] ||
19044                 error "data version did not change on write"\
19045                       " ${DV[0]} == ${DV[1]}"
19046
19047         # clean up
19048         rm -f $file1
19049 }
19050 run_test 187b "Test data version change on volatile file"
19051
19052 test_200() {
19053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19054         remote_mgs_nodsh && skip "remote MGS with nodsh"
19055         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19056
19057         local POOL=${POOL:-cea1}
19058         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19059         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19060         # Pool OST targets
19061         local first_ost=0
19062         local last_ost=$(($OSTCOUNT - 1))
19063         local ost_step=2
19064         local ost_list=$(seq $first_ost $ost_step $last_ost)
19065         local ost_range="$first_ost $last_ost $ost_step"
19066         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19067         local file_dir=$POOL_ROOT/file_tst
19068         local subdir=$test_path/subdir
19069         local rc=0
19070
19071         while : ; do
19072                 # former test_200a test_200b
19073                 pool_add $POOL                          || { rc=$? ; break; }
19074                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19075                 # former test_200c test_200d
19076                 mkdir -p $test_path
19077                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19078                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19079                 mkdir -p $subdir
19080                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19081                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19082                                                         || { rc=$? ; break; }
19083                 # former test_200e test_200f
19084                 local files=$((OSTCOUNT*3))
19085                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19086                                                         || { rc=$? ; break; }
19087                 pool_create_files $POOL $file_dir $files "$ost_list" \
19088                                                         || { rc=$? ; break; }
19089                 # former test_200g test_200h
19090                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19091                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19092
19093                 # former test_201a test_201b test_201c
19094                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19095
19096                 local f=$test_path/$tfile
19097                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19098                 pool_remove $POOL $f                    || { rc=$? ; break; }
19099                 break
19100         done
19101
19102         destroy_test_pools
19103
19104         return $rc
19105 }
19106 run_test 200 "OST pools"
19107
19108 # usage: default_attr <count | size | offset>
19109 default_attr() {
19110         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19111 }
19112
19113 # usage: check_default_stripe_attr
19114 check_default_stripe_attr() {
19115         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19116         case $1 in
19117         --stripe-count|-c)
19118                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19119         --stripe-size|-S)
19120                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19121         --stripe-index|-i)
19122                 EXPECTED=-1;;
19123         *)
19124                 error "unknown getstripe attr '$1'"
19125         esac
19126
19127         [ $ACTUAL == $EXPECTED ] ||
19128                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19129 }
19130
19131 test_204a() {
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19134
19135         check_default_stripe_attr --stripe-count
19136         check_default_stripe_attr --stripe-size
19137         check_default_stripe_attr --stripe-index
19138 }
19139 run_test 204a "Print default stripe attributes"
19140
19141 test_204b() {
19142         test_mkdir $DIR/$tdir
19143         $LFS setstripe --stripe-count 1 $DIR/$tdir
19144
19145         check_default_stripe_attr --stripe-size
19146         check_default_stripe_attr --stripe-index
19147 }
19148 run_test 204b "Print default stripe size and offset"
19149
19150 test_204c() {
19151         test_mkdir $DIR/$tdir
19152         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19153
19154         check_default_stripe_attr --stripe-count
19155         check_default_stripe_attr --stripe-index
19156 }
19157 run_test 204c "Print default stripe count and offset"
19158
19159 test_204d() {
19160         test_mkdir $DIR/$tdir
19161         $LFS setstripe --stripe-index 0 $DIR/$tdir
19162
19163         check_default_stripe_attr --stripe-count
19164         check_default_stripe_attr --stripe-size
19165 }
19166 run_test 204d "Print default stripe count and size"
19167
19168 test_204e() {
19169         test_mkdir $DIR/$tdir
19170         $LFS setstripe -d $DIR/$tdir
19171
19172         check_default_stripe_attr --stripe-count --raw
19173         check_default_stripe_attr --stripe-size --raw
19174         check_default_stripe_attr --stripe-index --raw
19175 }
19176 run_test 204e "Print raw stripe attributes"
19177
19178 test_204f() {
19179         test_mkdir $DIR/$tdir
19180         $LFS setstripe --stripe-count 1 $DIR/$tdir
19181
19182         check_default_stripe_attr --stripe-size --raw
19183         check_default_stripe_attr --stripe-index --raw
19184 }
19185 run_test 204f "Print raw stripe size and offset"
19186
19187 test_204g() {
19188         test_mkdir $DIR/$tdir
19189         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19190
19191         check_default_stripe_attr --stripe-count --raw
19192         check_default_stripe_attr --stripe-index --raw
19193 }
19194 run_test 204g "Print raw stripe count and offset"
19195
19196 test_204h() {
19197         test_mkdir $DIR/$tdir
19198         $LFS setstripe --stripe-index 0 $DIR/$tdir
19199
19200         check_default_stripe_attr --stripe-count --raw
19201         check_default_stripe_attr --stripe-size --raw
19202 }
19203 run_test 204h "Print raw stripe count and size"
19204
19205 # Figure out which job scheduler is being used, if any,
19206 # or use a fake one
19207 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19208         JOBENV=SLURM_JOB_ID
19209 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19210         JOBENV=LSB_JOBID
19211 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19212         JOBENV=PBS_JOBID
19213 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19214         JOBENV=LOADL_STEP_ID
19215 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19216         JOBENV=JOB_ID
19217 else
19218         $LCTL list_param jobid_name > /dev/null 2>&1
19219         if [ $? -eq 0 ]; then
19220                 JOBENV=nodelocal
19221         else
19222                 JOBENV=FAKE_JOBID
19223         fi
19224 fi
19225 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19226
19227 verify_jobstats() {
19228         local cmd=($1)
19229         shift
19230         local facets="$@"
19231
19232 # we don't really need to clear the stats for this test to work, since each
19233 # command has a unique jobid, but it makes debugging easier if needed.
19234 #       for facet in $facets; do
19235 #               local dev=$(convert_facet2label $facet)
19236 #               # clear old jobstats
19237 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19238 #       done
19239
19240         # use a new JobID for each test, or we might see an old one
19241         [ "$JOBENV" = "FAKE_JOBID" ] &&
19242                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19243
19244         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19245
19246         [ "$JOBENV" = "nodelocal" ] && {
19247                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19248                 $LCTL set_param jobid_name=$FAKE_JOBID
19249                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19250         }
19251
19252         log "Test: ${cmd[*]}"
19253         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19254
19255         if [ $JOBENV = "FAKE_JOBID" ]; then
19256                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19257         else
19258                 ${cmd[*]}
19259         fi
19260
19261         # all files are created on OST0000
19262         for facet in $facets; do
19263                 local stats="*.$(convert_facet2label $facet).job_stats"
19264
19265                 # strip out libtool wrappers for in-tree executables
19266                 if (( $(do_facet $facet lctl get_param $stats |
19267                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19268                         do_facet $facet lctl get_param $stats
19269                         error "No jobstats for $JOBVAL found on $facet::$stats"
19270                 fi
19271         done
19272 }
19273
19274 jobstats_set() {
19275         local new_jobenv=$1
19276
19277         set_persistent_param_and_check client "jobid_var" \
19278                 "$FSNAME.sys.jobid_var" $new_jobenv
19279 }
19280
19281 test_205a() { # Job stats
19282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19283         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19284                 skip "Need MDS version with at least 2.7.1"
19285         remote_mgs_nodsh && skip "remote MGS with nodsh"
19286         remote_mds_nodsh && skip "remote MDS with nodsh"
19287         remote_ost_nodsh && skip "remote OST with nodsh"
19288         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19289                 skip "Server doesn't support jobstats"
19290         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19291
19292         local old_jobenv=$($LCTL get_param -n jobid_var)
19293         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19294
19295         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19296                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19297         else
19298                 stack_trap "do_facet mgs $PERM_CMD \
19299                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19300         fi
19301         changelog_register
19302
19303         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19304                                 mdt.*.job_cleanup_interval | head -n 1)
19305         local new_interval=5
19306         do_facet $SINGLEMDS \
19307                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19308         stack_trap "do_facet $SINGLEMDS \
19309                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19310         local start=$SECONDS
19311
19312         local cmd
19313         # mkdir
19314         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19315         verify_jobstats "$cmd" "$SINGLEMDS"
19316         # rmdir
19317         cmd="rmdir $DIR/$tdir"
19318         verify_jobstats "$cmd" "$SINGLEMDS"
19319         # mkdir on secondary MDT
19320         if [ $MDSCOUNT -gt 1 ]; then
19321                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19322                 verify_jobstats "$cmd" "mds2"
19323         fi
19324         # mknod
19325         cmd="mknod $DIR/$tfile c 1 3"
19326         verify_jobstats "$cmd" "$SINGLEMDS"
19327         # unlink
19328         cmd="rm -f $DIR/$tfile"
19329         verify_jobstats "$cmd" "$SINGLEMDS"
19330         # create all files on OST0000 so verify_jobstats can find OST stats
19331         # open & close
19332         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19333         verify_jobstats "$cmd" "$SINGLEMDS"
19334         # setattr
19335         cmd="touch $DIR/$tfile"
19336         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19337         # write
19338         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19339         verify_jobstats "$cmd" "ost1"
19340         # read
19341         cancel_lru_locks osc
19342         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19343         verify_jobstats "$cmd" "ost1"
19344         # truncate
19345         cmd="$TRUNCATE $DIR/$tfile 0"
19346         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19347         # rename
19348         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19349         verify_jobstats "$cmd" "$SINGLEMDS"
19350         # jobstats expiry - sleep until old stats should be expired
19351         local left=$((new_interval + 5 - (SECONDS - start)))
19352         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19353                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19354                         "0" $left
19355         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19356         verify_jobstats "$cmd" "$SINGLEMDS"
19357         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19358             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19359
19360         # Ensure that jobid are present in changelog (if supported by MDS)
19361         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19362                 changelog_dump | tail -10
19363                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19364                 [ $jobids -eq 9 ] ||
19365                         error "Wrong changelog jobid count $jobids != 9"
19366
19367                 # LU-5862
19368                 JOBENV="disable"
19369                 jobstats_set $JOBENV
19370                 touch $DIR/$tfile
19371                 changelog_dump | grep $tfile
19372                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19373                 [ $jobids -eq 0 ] ||
19374                         error "Unexpected jobids when jobid_var=$JOBENV"
19375         fi
19376
19377         # test '%j' access to environment variable - if supported
19378         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19379                 JOBENV="JOBCOMPLEX"
19380                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19381
19382                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19383         fi
19384
19385         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19386                 JOBENV="JOBCOMPLEX"
19387                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19388
19389                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19390         fi
19391
19392         # test '%j' access to per-session jobid - if supported
19393         if lctl list_param jobid_this_session > /dev/null 2>&1
19394         then
19395                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19396                 lctl set_param jobid_this_session=$USER
19397
19398                 JOBENV="JOBCOMPLEX"
19399                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19400
19401                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19402         fi
19403 }
19404 run_test 205a "Verify job stats"
19405
19406 # LU-13117, LU-13597
19407 test_205b() {
19408         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19409                 skip "Need MDS version at least 2.13.54.91"
19410
19411         local job_stats="mdt.*.job_stats"
19412         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19413
19414         do_facet mds1 $LCTL set_param $job_stats=clear
19415
19416         # Setting jobid_var to USER might not be supported
19417         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19418         $LCTL set_param jobid_var=USER || true
19419         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19420         $LCTL set_param jobid_name="%j.%e.%u"
19421
19422         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19423         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19424                 { do_facet mds1 $LCTL get_param $job_stats;
19425                   error "Unexpected jobid found"; }
19426         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19427                 { do_facet mds1 $LCTL get_param $job_stats;
19428                   error "wrong job_stats format found"; }
19429
19430         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19431                 echo "MDS does not yet escape jobid" && return 0
19432         $LCTL set_param jobid_var=TEST205b
19433         env -i TEST205b="has sp" touch $DIR/$tfile.2
19434         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19435                 { do_facet mds1 $LCTL get_param $job_stats;
19436                   error "jobid not escaped"; }
19437 }
19438 run_test 205b "Verify job stats jobid and output format"
19439
19440 # LU-13733
19441 test_205c() {
19442         $LCTL set_param llite.*.stats=0
19443         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19444         $LCTL get_param llite.*.stats
19445         $LCTL get_param llite.*.stats | grep \
19446                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19447                         error "wrong client stats format found"
19448 }
19449 run_test 205c "Verify client stats format"
19450
19451 test_205d() {
19452         local file=$DIR/$tdir/$tfile
19453
19454         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19455                 skip "need lustre >= 2.15.53 for lljobstat"
19456         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19457                 skip "need lustre >= 2.15.53 for lljobstat"
19458         verify_yaml_available || skip_env "YAML verification not installed"
19459
19460         test_mkdir -i 0 $DIR/$tdir
19461         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19462
19463         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19464                 error "failed to write data to $file"
19465         mv $file $file.2
19466
19467         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19468         echo -n 'verify rename_stats...'
19469         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19470                 verify_yaml || error "rename_stats is not valid YAML"
19471         echo " OK"
19472
19473         echo -n 'verify mdt job_stats...'
19474         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19475                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19476         echo " OK"
19477
19478         echo -n 'verify ost job_stats...'
19479         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19480                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19481         echo " OK"
19482 }
19483 run_test 205d "verify the format of some stats files"
19484
19485 test_205e() {
19486         local ops_comma
19487         local file=$DIR/$tdir/$tfile
19488
19489         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19490                 skip "need lustre >= 2.15.53 for lljobstat"
19491         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19492                 skip "need lustre >= 2.15.53 for lljobstat"
19493         verify_yaml_available || skip_env "YAML verification not installed"
19494
19495         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19496
19497         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19498                 error "failed to create $file on ost1"
19499         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19500                 error "failed to write data to $file"
19501
19502         do_facet mds1 "$LCTL get_param *.*.job_stats"
19503         do_facet ost1 "$LCTL get_param *.*.job_stats"
19504
19505         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19506         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19507                 error "The output of lljobstat is not an valid YAML"
19508
19509         # verify that job dd.0 does exist and has some ops on ost1
19510         # typically this line is like:
19511         # - dd.0:            {ops: 20, ...}
19512         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19513                     awk '$2=="dd.0:" {print $4}')
19514
19515         (( ${ops_comma%,} >= 10 )) ||
19516                 error "cannot find job dd.0 with ops >= 10"
19517 }
19518 run_test 205e "verify the output of lljobstat"
19519
19520 test_205f() {
19521         verify_yaml_available || skip_env "YAML verification not installed"
19522
19523         # check both qos_ost_weights and qos_mdt_weights
19524         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19525         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19526                 error "qos_ost_weights is not valid YAML"
19527 }
19528 run_test 205f "verify qos_ost_weights YAML format "
19529
19530 # LU-1480, LU-1773 and LU-1657
19531 test_206() {
19532         mkdir -p $DIR/$tdir
19533         $LFS setstripe -c -1 $DIR/$tdir
19534 #define OBD_FAIL_LOV_INIT 0x1403
19535         $LCTL set_param fail_loc=0xa0001403
19536         $LCTL set_param fail_val=1
19537         touch $DIR/$tdir/$tfile || true
19538 }
19539 run_test 206 "fail lov_init_raid0() doesn't lbug"
19540
19541 test_207a() {
19542         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19543         local fsz=`stat -c %s $DIR/$tfile`
19544         cancel_lru_locks mdc
19545
19546         # do not return layout in getattr intent
19547 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19548         $LCTL set_param fail_loc=0x170
19549         local sz=`stat -c %s $DIR/$tfile`
19550
19551         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19552
19553         rm -rf $DIR/$tfile
19554 }
19555 run_test 207a "can refresh layout at glimpse"
19556
19557 test_207b() {
19558         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19559         local cksum=`md5sum $DIR/$tfile`
19560         local fsz=`stat -c %s $DIR/$tfile`
19561         cancel_lru_locks mdc
19562         cancel_lru_locks osc
19563
19564         # do not return layout in getattr intent
19565 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19566         $LCTL set_param fail_loc=0x171
19567
19568         # it will refresh layout after the file is opened but before read issues
19569         echo checksum is "$cksum"
19570         echo "$cksum" |md5sum -c --quiet || error "file differs"
19571
19572         rm -rf $DIR/$tfile
19573 }
19574 run_test 207b "can refresh layout at open"
19575
19576 test_208() {
19577         # FIXME: in this test suite, only RD lease is used. This is okay
19578         # for now as only exclusive open is supported. After generic lease
19579         # is done, this test suite should be revised. - Jinshan
19580
19581         remote_mds_nodsh && skip "remote MDS with nodsh"
19582         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19583                 skip "Need MDS version at least 2.4.52"
19584
19585         echo "==== test 1: verify get lease work"
19586         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19587
19588         echo "==== test 2: verify lease can be broken by upcoming open"
19589         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19590         local PID=$!
19591         sleep 2
19592
19593         $MULTIOP $DIR/$tfile oO_RDWR:c
19594         kill -USR1 $PID && wait $PID || error "break lease error"
19595
19596         echo "==== test 3: verify lease can't be granted if an open already exists"
19597         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19598         local PID=$!
19599         sleep 2
19600
19601         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19602         kill -USR1 $PID && wait $PID || error "open file error"
19603
19604         echo "==== test 4: lease can sustain over recovery"
19605         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19606         PID=$!
19607         sleep 2
19608
19609         fail mds1
19610
19611         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19612
19613         echo "==== test 5: lease broken can't be regained by replay"
19614         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19615         PID=$!
19616         sleep 2
19617
19618         # open file to break lease and then recovery
19619         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19620         fail mds1
19621
19622         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19623
19624         rm -f $DIR/$tfile
19625 }
19626 run_test 208 "Exclusive open"
19627
19628 test_209() {
19629         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19630                 skip_env "must have disp_stripe"
19631
19632         touch $DIR/$tfile
19633         sync; sleep 5; sync;
19634
19635         echo 3 > /proc/sys/vm/drop_caches
19636         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19637                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19638         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19639
19640         # open/close 500 times
19641         for i in $(seq 500); do
19642                 cat $DIR/$tfile
19643         done
19644
19645         echo 3 > /proc/sys/vm/drop_caches
19646         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19647                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19648         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19649
19650         echo "before: $req_before, after: $req_after"
19651         [ $((req_after - req_before)) -ge 300 ] &&
19652                 error "open/close requests are not freed"
19653         return 0
19654 }
19655 run_test 209 "read-only open/close requests should be freed promptly"
19656
19657 test_210() {
19658         local pid
19659
19660         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19661         pid=$!
19662         sleep 1
19663
19664         $LFS getstripe $DIR/$tfile
19665         kill -USR1 $pid
19666         wait $pid || error "multiop failed"
19667
19668         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19669         pid=$!
19670         sleep 1
19671
19672         $LFS getstripe $DIR/$tfile
19673         kill -USR1 $pid
19674         wait $pid || error "multiop failed"
19675 }
19676 run_test 210 "lfs getstripe does not break leases"
19677
19678 test_212() {
19679         size=`date +%s`
19680         size=$((size % 8192 + 1))
19681         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19682         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19683         rm -f $DIR/f212 $DIR/f212.xyz
19684 }
19685 run_test 212 "Sendfile test ============================================"
19686
19687 test_213() {
19688         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19689         cancel_lru_locks osc
19690         lctl set_param fail_loc=0x8000040f
19691         # generate a read lock
19692         cat $DIR/$tfile > /dev/null
19693         # write to the file, it will try to cancel the above read lock.
19694         cat /etc/hosts >> $DIR/$tfile
19695 }
19696 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19697
19698 test_214() { # for bug 20133
19699         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19700         for (( i=0; i < 340; i++ )) ; do
19701                 touch $DIR/$tdir/d214c/a$i
19702         done
19703
19704         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19705         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19706         ls $DIR/d214c || error "ls $DIR/d214c failed"
19707         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19708         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19709 }
19710 run_test 214 "hash-indexed directory test - bug 20133"
19711
19712 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19713 create_lnet_proc_files() {
19714         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19715 }
19716
19717 # counterpart of create_lnet_proc_files
19718 remove_lnet_proc_files() {
19719         rm -f $TMP/lnet_$1.sys
19720 }
19721
19722 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19723 # 3rd arg as regexp for body
19724 check_lnet_proc_stats() {
19725         local l=$(cat "$TMP/lnet_$1" |wc -l)
19726         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19727
19728         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19729 }
19730
19731 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19732 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19733 # optional and can be regexp for 2nd line (lnet.routes case)
19734 check_lnet_proc_entry() {
19735         local blp=2          # blp stands for 'position of 1st line of body'
19736         [ -z "$5" ] || blp=3 # lnet.routes case
19737
19738         local l=$(cat "$TMP/lnet_$1" |wc -l)
19739         # subtracting one from $blp because the body can be empty
19740         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19741
19742         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19743                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19744
19745         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19746                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19747
19748         # bail out if any unexpected line happened
19749         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19750         [ "$?" != 0 ] || error "$2 misformatted"
19751 }
19752
19753 test_215() { # for bugs 18102, 21079, 21517
19754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19755
19756         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19757         local P='[1-9][0-9]*'           # positive numeric
19758         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19759         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19760         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19761         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19762
19763         local L1 # regexp for 1st line
19764         local L2 # regexp for 2nd line (optional)
19765         local BR # regexp for the rest (body)
19766
19767         # lnet.stats should look as 11 space-separated non-negative numerics
19768         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19769         create_lnet_proc_files "stats"
19770         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19771         remove_lnet_proc_files "stats"
19772
19773         # lnet.routes should look like this:
19774         # Routing disabled/enabled
19775         # net hops priority state router
19776         # where net is a string like tcp0, hops > 0, priority >= 0,
19777         # state is up/down,
19778         # router is a string like 192.168.1.1@tcp2
19779         L1="^Routing (disabled|enabled)$"
19780         L2="^net +hops +priority +state +router$"
19781         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19782         create_lnet_proc_files "routes"
19783         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19784         remove_lnet_proc_files "routes"
19785
19786         # lnet.routers should look like this:
19787         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19788         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19789         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19790         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19791         L1="^ref +rtr_ref +alive +router$"
19792         BR="^$P +$P +(up|down) +$NID$"
19793         create_lnet_proc_files "routers"
19794         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19795         remove_lnet_proc_files "routers"
19796
19797         # lnet.peers should look like this:
19798         # nid refs state last max rtr min tx min queue
19799         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19800         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19801         # numeric (0 or >0 or <0), queue >= 0.
19802         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19803         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19804         create_lnet_proc_files "peers"
19805         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19806         remove_lnet_proc_files "peers"
19807
19808         # lnet.buffers  should look like this:
19809         # pages count credits min
19810         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19811         L1="^pages +count +credits +min$"
19812         BR="^ +$N +$N +$I +$I$"
19813         create_lnet_proc_files "buffers"
19814         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19815         remove_lnet_proc_files "buffers"
19816
19817         # lnet.nis should look like this:
19818         # nid status alive refs peer rtr max tx min
19819         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19820         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19821         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19822         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19823         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19824         create_lnet_proc_files "nis"
19825         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19826         remove_lnet_proc_files "nis"
19827
19828         # can we successfully write to lnet.stats?
19829         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19830 }
19831 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19832
19833 test_216() { # bug 20317
19834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19835         remote_ost_nodsh && skip "remote OST with nodsh"
19836
19837         local node
19838         local facets=$(get_facets OST)
19839         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19840
19841         save_lustre_params client "osc.*.contention_seconds" > $p
19842         save_lustre_params $facets \
19843                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19844         save_lustre_params $facets \
19845                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19846         save_lustre_params $facets \
19847                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19848         clear_stats osc.*.osc_stats
19849
19850         # agressive lockless i/o settings
19851         do_nodes $(comma_list $(osts_nodes)) \
19852                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19853                         ldlm.namespaces.filter-*.contended_locks=0 \
19854                         ldlm.namespaces.filter-*.contention_seconds=60"
19855         lctl set_param -n osc.*.contention_seconds=60
19856
19857         $DIRECTIO write $DIR/$tfile 0 10 4096
19858         $CHECKSTAT -s 40960 $DIR/$tfile
19859
19860         # disable lockless i/o
19861         do_nodes $(comma_list $(osts_nodes)) \
19862                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19863                         ldlm.namespaces.filter-*.contended_locks=32 \
19864                         ldlm.namespaces.filter-*.contention_seconds=0"
19865         lctl set_param -n osc.*.contention_seconds=0
19866         clear_stats osc.*.osc_stats
19867
19868         dd if=/dev/zero of=$DIR/$tfile count=0
19869         $CHECKSTAT -s 0 $DIR/$tfile
19870
19871         restore_lustre_params <$p
19872         rm -f $p
19873         rm $DIR/$tfile
19874 }
19875 run_test 216 "check lockless direct write updates file size and kms correctly"
19876
19877 test_217() { # bug 22430
19878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19879
19880         local node
19881         local nid
19882
19883         for node in $(nodes_list); do
19884                 nid=$(host_nids_address $node $NETTYPE)
19885                 if [[ $nid = *-* ]] ; then
19886                         echo "lctl ping $(h2nettype $nid)"
19887                         lctl ping $(h2nettype $nid)
19888                 else
19889                         echo "skipping $node (no hyphen detected)"
19890                 fi
19891         done
19892 }
19893 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19894
19895 test_218() {
19896        # do directio so as not to populate the page cache
19897        log "creating a 10 Mb file"
19898        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19899        log "starting reads"
19900        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19901        log "truncating the file"
19902        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19903        log "killing dd"
19904        kill %+ || true # reads might have finished
19905        echo "wait until dd is finished"
19906        wait
19907        log "removing the temporary file"
19908        rm -rf $DIR/$tfile || error "tmp file removal failed"
19909 }
19910 run_test 218 "parallel read and truncate should not deadlock"
19911
19912 test_219() {
19913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19914
19915         # write one partial page
19916         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19917         # set no grant so vvp_io_commit_write will do sync write
19918         $LCTL set_param fail_loc=0x411
19919         # write a full page at the end of file
19920         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19921
19922         $LCTL set_param fail_loc=0
19923         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19924         $LCTL set_param fail_loc=0x411
19925         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19926
19927         # LU-4201
19928         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19929         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19930 }
19931 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19932
19933 test_220() { #LU-325
19934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19935         remote_ost_nodsh && skip "remote OST with nodsh"
19936         remote_mds_nodsh && skip "remote MDS with nodsh"
19937         remote_mgs_nodsh && skip "remote MGS with nodsh"
19938
19939         local OSTIDX=0
19940
19941         # create on MDT0000 so the last_id and next_id are correct
19942         mkdir_on_mdt0 $DIR/$tdir
19943         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19944         OST=${OST%_UUID}
19945
19946         # on the mdt's osc
19947         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19948         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19949                         osp.$mdtosc_proc1.prealloc_last_id)
19950         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19951                         osp.$mdtosc_proc1.prealloc_next_id)
19952
19953         $LFS df -i
19954
19955         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19956         #define OBD_FAIL_OST_ENOINO              0x229
19957         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19958         create_pool $FSNAME.$TESTNAME || return 1
19959         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19960
19961         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19962
19963         MDSOBJS=$((last_id - next_id))
19964         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19965
19966         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19967         echo "OST still has $count kbytes free"
19968
19969         echo "create $MDSOBJS files @next_id..."
19970         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19971
19972         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19973                         osp.$mdtosc_proc1.prealloc_last_id)
19974         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19975                         osp.$mdtosc_proc1.prealloc_next_id)
19976
19977         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19978         $LFS df -i
19979
19980         echo "cleanup..."
19981
19982         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19983         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19984
19985         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19986                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19987         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19988                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19989         echo "unlink $MDSOBJS files @$next_id..."
19990         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19991 }
19992 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19993
19994 test_221() {
19995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19996
19997         dd if=`which date` of=$MOUNT/date oflag=sync
19998         chmod +x $MOUNT/date
19999
20000         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20001         $LCTL set_param fail_loc=0x80001401
20002
20003         $MOUNT/date > /dev/null
20004         rm -f $MOUNT/date
20005 }
20006 run_test 221 "make sure fault and truncate race to not cause OOM"
20007
20008 test_222a () {
20009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20010
20011         rm -rf $DIR/$tdir
20012         test_mkdir $DIR/$tdir
20013         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20014         createmany -o $DIR/$tdir/$tfile 10
20015         cancel_lru_locks mdc
20016         cancel_lru_locks osc
20017         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20018         $LCTL set_param fail_loc=0x31a
20019         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20020         $LCTL set_param fail_loc=0
20021         rm -r $DIR/$tdir
20022 }
20023 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20024
20025 test_222b () {
20026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20027
20028         rm -rf $DIR/$tdir
20029         test_mkdir $DIR/$tdir
20030         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20031         createmany -o $DIR/$tdir/$tfile 10
20032         cancel_lru_locks mdc
20033         cancel_lru_locks osc
20034         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20035         $LCTL set_param fail_loc=0x31a
20036         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20037         $LCTL set_param fail_loc=0
20038 }
20039 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20040
20041 test_223 () {
20042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20043
20044         rm -rf $DIR/$tdir
20045         test_mkdir $DIR/$tdir
20046         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20047         createmany -o $DIR/$tdir/$tfile 10
20048         cancel_lru_locks mdc
20049         cancel_lru_locks osc
20050         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20051         $LCTL set_param fail_loc=0x31b
20052         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20053         $LCTL set_param fail_loc=0
20054         rm -r $DIR/$tdir
20055 }
20056 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20057
20058 test_224a() { # LU-1039, MRP-303
20059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20060         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20061         $LCTL set_param fail_loc=0x508
20062         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20063         $LCTL set_param fail_loc=0
20064         df $DIR
20065 }
20066 run_test 224a "Don't panic on bulk IO failure"
20067
20068 test_224bd_sub() { # LU-1039, MRP-303
20069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20070         local timeout=$1
20071
20072         shift
20073         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20074
20075         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20076
20077         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20078         cancel_lru_locks osc
20079         set_checksums 0
20080         stack_trap "set_checksums $ORIG_CSUM" EXIT
20081         local at_max_saved=0
20082
20083         # adaptive timeouts may prevent seeing the issue
20084         if at_is_enabled; then
20085                 at_max_saved=$(at_max_get mds)
20086                 at_max_set 0 mds client
20087                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20088         fi
20089
20090         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20091         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20092         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20093
20094         do_facet ost1 $LCTL set_param fail_loc=0
20095         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20096         df $DIR
20097 }
20098
20099 test_224b() {
20100         test_224bd_sub 3 error "dd failed"
20101 }
20102 run_test 224b "Don't panic on bulk IO failure"
20103
20104 test_224c() { # LU-6441
20105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20106         remote_mds_nodsh && skip "remote MDS with nodsh"
20107
20108         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20109         save_writethrough $p
20110         set_cache writethrough on
20111
20112         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20113         local at_max=$($LCTL get_param -n at_max)
20114         local timeout=$($LCTL get_param -n timeout)
20115         local test_at="at_max"
20116         local param_at="$FSNAME.sys.at_max"
20117         local test_timeout="timeout"
20118         local param_timeout="$FSNAME.sys.timeout"
20119
20120         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20121
20122         set_persistent_param_and_check client "$test_at" "$param_at" 0
20123         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20124
20125         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20126         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20127         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20128         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20129         sync
20130         do_facet ost1 "$LCTL set_param fail_loc=0"
20131
20132         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20133         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20134                 $timeout
20135
20136         $LCTL set_param -n $pages_per_rpc
20137         restore_lustre_params < $p
20138         rm -f $p
20139 }
20140 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20141
20142 test_224d() { # LU-11169
20143         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20144 }
20145 run_test 224d "Don't corrupt data on bulk IO timeout"
20146
20147 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20148 test_225a () {
20149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20150         if [ -z ${MDSSURVEY} ]; then
20151                 skip_env "mds-survey not found"
20152         fi
20153         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20154                 skip "Need MDS version at least 2.2.51"
20155
20156         local mds=$(facet_host $SINGLEMDS)
20157         local target=$(do_nodes $mds 'lctl dl' |
20158                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20159
20160         local cmd1="file_count=1000 thrhi=4"
20161         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20162         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20163         local cmd="$cmd1 $cmd2 $cmd3"
20164
20165         rm -f ${TMP}/mds_survey*
20166         echo + $cmd
20167         eval $cmd || error "mds-survey with zero-stripe failed"
20168         cat ${TMP}/mds_survey*
20169         rm -f ${TMP}/mds_survey*
20170 }
20171 run_test 225a "Metadata survey sanity with zero-stripe"
20172
20173 test_225b () {
20174         if [ -z ${MDSSURVEY} ]; then
20175                 skip_env "mds-survey not found"
20176         fi
20177         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20178                 skip "Need MDS version at least 2.2.51"
20179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20180         remote_mds_nodsh && skip "remote MDS with nodsh"
20181         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20182                 skip_env "Need to mount OST to test"
20183         fi
20184
20185         local mds=$(facet_host $SINGLEMDS)
20186         local target=$(do_nodes $mds 'lctl dl' |
20187                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20188
20189         local cmd1="file_count=1000 thrhi=4"
20190         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20191         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20192         local cmd="$cmd1 $cmd2 $cmd3"
20193
20194         rm -f ${TMP}/mds_survey*
20195         echo + $cmd
20196         eval $cmd || error "mds-survey with stripe_count failed"
20197         cat ${TMP}/mds_survey*
20198         rm -f ${TMP}/mds_survey*
20199 }
20200 run_test 225b "Metadata survey sanity with stripe_count = 1"
20201
20202 mcreate_path2fid () {
20203         local mode=$1
20204         local major=$2
20205         local minor=$3
20206         local name=$4
20207         local desc=$5
20208         local path=$DIR/$tdir/$name
20209         local fid
20210         local rc
20211         local fid_path
20212
20213         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20214                 error "cannot create $desc"
20215
20216         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20217         rc=$?
20218         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20219
20220         fid_path=$($LFS fid2path $MOUNT $fid)
20221         rc=$?
20222         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20223
20224         [ "$path" == "$fid_path" ] ||
20225                 error "fid2path returned $fid_path, expected $path"
20226
20227         echo "pass with $path and $fid"
20228 }
20229
20230 test_226a () {
20231         rm -rf $DIR/$tdir
20232         mkdir -p $DIR/$tdir
20233
20234         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20235         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20236         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20237         mcreate_path2fid 0040666 0 0 dir "directory"
20238         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20239         mcreate_path2fid 0100666 0 0 file "regular file"
20240         mcreate_path2fid 0120666 0 0 link "symbolic link"
20241         mcreate_path2fid 0140666 0 0 sock "socket"
20242 }
20243 run_test 226a "call path2fid and fid2path on files of all type"
20244
20245 test_226b () {
20246         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20247
20248         local MDTIDX=1
20249
20250         rm -rf $DIR/$tdir
20251         mkdir -p $DIR/$tdir
20252         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20253                 error "create remote directory failed"
20254         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20255         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20256                                 "character special file (null)"
20257         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20258                                 "character special file (no device)"
20259         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20260         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20261                                 "block special file (loop)"
20262         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20263         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20264         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20265 }
20266 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20267
20268 test_226c () {
20269         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20270         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20271                 skip "Need MDS version at least 2.13.55"
20272
20273         local submnt=/mnt/submnt
20274         local srcfile=/etc/passwd
20275         local dstfile=$submnt/passwd
20276         local path
20277         local fid
20278
20279         rm -rf $DIR/$tdir
20280         rm -rf $submnt
20281         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20282                 error "create remote directory failed"
20283         mkdir -p $submnt || error "create $submnt failed"
20284         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20285                 error "mount $submnt failed"
20286         stack_trap "umount $submnt" EXIT
20287
20288         cp $srcfile $dstfile
20289         fid=$($LFS path2fid $dstfile)
20290         path=$($LFS fid2path $submnt "$fid")
20291         [ "$path" = "$dstfile" ] ||
20292                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20293 }
20294 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20295
20296 # LU-1299 Executing or running ldd on a truncated executable does not
20297 # cause an out-of-memory condition.
20298 test_227() {
20299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20300         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20301
20302         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20303         chmod +x $MOUNT/date
20304
20305         $MOUNT/date > /dev/null
20306         ldd $MOUNT/date > /dev/null
20307         rm -f $MOUNT/date
20308 }
20309 run_test 227 "running truncated executable does not cause OOM"
20310
20311 # LU-1512 try to reuse idle OI blocks
20312 test_228a() {
20313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20314         remote_mds_nodsh && skip "remote MDS with nodsh"
20315         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20316
20317         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20318         local myDIR=$DIR/$tdir
20319
20320         mkdir -p $myDIR
20321         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20322         $LCTL set_param fail_loc=0x80001002
20323         createmany -o $myDIR/t- 10000
20324         $LCTL set_param fail_loc=0
20325         # The guard is current the largest FID holder
20326         touch $myDIR/guard
20327         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20328                     tr -d '[')
20329         local IDX=$(($SEQ % 64))
20330
20331         do_facet $SINGLEMDS sync
20332         # Make sure journal flushed.
20333         sleep 6
20334         local blk1=$(do_facet $SINGLEMDS \
20335                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20336                      grep Blockcount | awk '{print $4}')
20337
20338         # Remove old files, some OI blocks will become idle.
20339         unlinkmany $myDIR/t- 10000
20340         # Create new files, idle OI blocks should be reused.
20341         createmany -o $myDIR/t- 2000
20342         do_facet $SINGLEMDS sync
20343         # Make sure journal flushed.
20344         sleep 6
20345         local blk2=$(do_facet $SINGLEMDS \
20346                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20347                      grep Blockcount | awk '{print $4}')
20348
20349         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20350 }
20351 run_test 228a "try to reuse idle OI blocks"
20352
20353 test_228b() {
20354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20355         remote_mds_nodsh && skip "remote MDS with nodsh"
20356         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20357
20358         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20359         local myDIR=$DIR/$tdir
20360
20361         mkdir -p $myDIR
20362         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20363         $LCTL set_param fail_loc=0x80001002
20364         createmany -o $myDIR/t- 10000
20365         $LCTL set_param fail_loc=0
20366         # The guard is current the largest FID holder
20367         touch $myDIR/guard
20368         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20369                     tr -d '[')
20370         local IDX=$(($SEQ % 64))
20371
20372         do_facet $SINGLEMDS sync
20373         # Make sure journal flushed.
20374         sleep 6
20375         local blk1=$(do_facet $SINGLEMDS \
20376                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20377                      grep Blockcount | awk '{print $4}')
20378
20379         # Remove old files, some OI blocks will become idle.
20380         unlinkmany $myDIR/t- 10000
20381
20382         # stop the MDT
20383         stop $SINGLEMDS || error "Fail to stop MDT."
20384         # remount the MDT
20385         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20386                 error "Fail to start MDT."
20387
20388         client_up || error "Fail to df."
20389         # Create new files, idle OI blocks should be reused.
20390         createmany -o $myDIR/t- 2000
20391         do_facet $SINGLEMDS sync
20392         # Make sure journal flushed.
20393         sleep 6
20394         local blk2=$(do_facet $SINGLEMDS \
20395                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20396                      grep Blockcount | awk '{print $4}')
20397
20398         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20399 }
20400 run_test 228b "idle OI blocks can be reused after MDT restart"
20401
20402 #LU-1881
20403 test_228c() {
20404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20405         remote_mds_nodsh && skip "remote MDS with nodsh"
20406         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20407
20408         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20409         local myDIR=$DIR/$tdir
20410
20411         mkdir -p $myDIR
20412         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20413         $LCTL set_param fail_loc=0x80001002
20414         # 20000 files can guarantee there are index nodes in the OI file
20415         createmany -o $myDIR/t- 20000
20416         $LCTL set_param fail_loc=0
20417         # The guard is current the largest FID holder
20418         touch $myDIR/guard
20419         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20420                     tr -d '[')
20421         local IDX=$(($SEQ % 64))
20422
20423         do_facet $SINGLEMDS sync
20424         # Make sure journal flushed.
20425         sleep 6
20426         local blk1=$(do_facet $SINGLEMDS \
20427                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20428                      grep Blockcount | awk '{print $4}')
20429
20430         # Remove old files, some OI blocks will become idle.
20431         unlinkmany $myDIR/t- 20000
20432         rm -f $myDIR/guard
20433         # The OI file should become empty now
20434
20435         # Create new files, idle OI blocks should be reused.
20436         createmany -o $myDIR/t- 2000
20437         do_facet $SINGLEMDS sync
20438         # Make sure journal flushed.
20439         sleep 6
20440         local blk2=$(do_facet $SINGLEMDS \
20441                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20442                      grep Blockcount | awk '{print $4}')
20443
20444         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20445 }
20446 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20447
20448 test_229() { # LU-2482, LU-3448
20449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20451         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20452                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20453
20454         rm -f $DIR/$tfile
20455
20456         # Create a file with a released layout and stripe count 2.
20457         $MULTIOP $DIR/$tfile H2c ||
20458                 error "failed to create file with released layout"
20459
20460         $LFS getstripe -v $DIR/$tfile
20461
20462         local pattern=$($LFS getstripe -L $DIR/$tfile)
20463         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20464
20465         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20466                 error "getstripe"
20467         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20468         stat $DIR/$tfile || error "failed to stat released file"
20469
20470         chown $RUNAS_ID $DIR/$tfile ||
20471                 error "chown $RUNAS_ID $DIR/$tfile failed"
20472
20473         chgrp $RUNAS_ID $DIR/$tfile ||
20474                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20475
20476         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20477         rm $DIR/$tfile || error "failed to remove released file"
20478 }
20479 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20480
20481 test_230a() {
20482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20484         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20485                 skip "Need MDS version at least 2.11.52"
20486
20487         local MDTIDX=1
20488
20489         test_mkdir $DIR/$tdir
20490         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20491         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20492         [ $mdt_idx -ne 0 ] &&
20493                 error "create local directory on wrong MDT $mdt_idx"
20494
20495         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20496                         error "create remote directory failed"
20497         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20498         [ $mdt_idx -ne $MDTIDX ] &&
20499                 error "create remote directory on wrong MDT $mdt_idx"
20500
20501         createmany -o $DIR/$tdir/test_230/t- 10 ||
20502                 error "create files on remote directory failed"
20503         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20504         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20505         rm -r $DIR/$tdir || error "unlink remote directory failed"
20506 }
20507 run_test 230a "Create remote directory and files under the remote directory"
20508
20509 test_230b() {
20510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20512         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20513                 skip "Need MDS version at least 2.11.52"
20514
20515         local MDTIDX=1
20516         local mdt_index
20517         local i
20518         local file
20519         local pid
20520         local stripe_count
20521         local migrate_dir=$DIR/$tdir/migrate_dir
20522         local other_dir=$DIR/$tdir/other_dir
20523
20524         test_mkdir $DIR/$tdir
20525         test_mkdir -i0 -c1 $migrate_dir
20526         test_mkdir -i0 -c1 $other_dir
20527         for ((i=0; i<10; i++)); do
20528                 mkdir -p $migrate_dir/dir_${i}
20529                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20530                         error "create files under remote dir failed $i"
20531         done
20532
20533         cp /etc/passwd $migrate_dir/$tfile
20534         cp /etc/passwd $other_dir/$tfile
20535         chattr +SAD $migrate_dir
20536         chattr +SAD $migrate_dir/$tfile
20537
20538         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20539         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20540         local old_dir_mode=$(stat -c%f $migrate_dir)
20541         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20542
20543         mkdir -p $migrate_dir/dir_default_stripe2
20544         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20545         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20546
20547         mkdir -p $other_dir
20548         ln $migrate_dir/$tfile $other_dir/luna
20549         ln $migrate_dir/$tfile $migrate_dir/sofia
20550         ln $other_dir/$tfile $migrate_dir/david
20551         ln -s $migrate_dir/$tfile $other_dir/zachary
20552         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20553         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20554
20555         local len
20556         local lnktgt
20557
20558         # inline symlink
20559         for len in 58 59 60; do
20560                 lnktgt=$(str_repeat 'l' $len)
20561                 touch $migrate_dir/$lnktgt
20562                 ln -s $lnktgt $migrate_dir/${len}char_ln
20563         done
20564
20565         # PATH_MAX
20566         for len in 4094 4095; do
20567                 lnktgt=$(str_repeat 'l' $len)
20568                 ln -s $lnktgt $migrate_dir/${len}char_ln
20569         done
20570
20571         # NAME_MAX
20572         for len in 254 255; do
20573                 touch $migrate_dir/$(str_repeat 'l' $len)
20574         done
20575
20576         $LFS migrate -m $MDTIDX $migrate_dir ||
20577                 error "fails on migrating remote dir to MDT1"
20578
20579         echo "migratate to MDT1, then checking.."
20580         for ((i = 0; i < 10; i++)); do
20581                 for file in $(find $migrate_dir/dir_${i}); do
20582                         mdt_index=$($LFS getstripe -m $file)
20583                         # broken symlink getstripe will fail
20584                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20585                                 error "$file is not on MDT${MDTIDX}"
20586                 done
20587         done
20588
20589         # the multiple link file should still in MDT0
20590         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20591         [ $mdt_index == 0 ] ||
20592                 error "$file is not on MDT${MDTIDX}"
20593
20594         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20595         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20596                 error " expect $old_dir_flag get $new_dir_flag"
20597
20598         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20599         [ "$old_file_flag" = "$new_file_flag" ] ||
20600                 error " expect $old_file_flag get $new_file_flag"
20601
20602         local new_dir_mode=$(stat -c%f $migrate_dir)
20603         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20604                 error "expect mode $old_dir_mode get $new_dir_mode"
20605
20606         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20607         [ "$old_file_mode" = "$new_file_mode" ] ||
20608                 error "expect mode $old_file_mode get $new_file_mode"
20609
20610         diff /etc/passwd $migrate_dir/$tfile ||
20611                 error "$tfile different after migration"
20612
20613         diff /etc/passwd $other_dir/luna ||
20614                 error "luna different after migration"
20615
20616         diff /etc/passwd $migrate_dir/sofia ||
20617                 error "sofia different after migration"
20618
20619         diff /etc/passwd $migrate_dir/david ||
20620                 error "david different after migration"
20621
20622         diff /etc/passwd $other_dir/zachary ||
20623                 error "zachary different after migration"
20624
20625         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20626                 error "${tfile}_ln different after migration"
20627
20628         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20629                 error "${tfile}_ln_other different after migration"
20630
20631         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20632         [ $stripe_count = 2 ] ||
20633                 error "dir strpe_count $d != 2 after migration."
20634
20635         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20636         [ $stripe_count = 2 ] ||
20637                 error "file strpe_count $d != 2 after migration."
20638
20639         #migrate back to MDT0
20640         MDTIDX=0
20641
20642         $LFS migrate -m $MDTIDX $migrate_dir ||
20643                 error "fails on migrating remote dir to MDT0"
20644
20645         echo "migrate back to MDT0, checking.."
20646         for file in $(find $migrate_dir); do
20647                 mdt_index=$($LFS getstripe -m $file)
20648                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20649                         error "$file is not on MDT${MDTIDX}"
20650         done
20651
20652         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20653         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20654                 error " expect $old_dir_flag get $new_dir_flag"
20655
20656         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20657         [ "$old_file_flag" = "$new_file_flag" ] ||
20658                 error " expect $old_file_flag get $new_file_flag"
20659
20660         local new_dir_mode=$(stat -c%f $migrate_dir)
20661         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20662                 error "expect mode $old_dir_mode get $new_dir_mode"
20663
20664         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20665         [ "$old_file_mode" = "$new_file_mode" ] ||
20666                 error "expect mode $old_file_mode get $new_file_mode"
20667
20668         diff /etc/passwd ${migrate_dir}/$tfile ||
20669                 error "$tfile different after migration"
20670
20671         diff /etc/passwd ${other_dir}/luna ||
20672                 error "luna different after migration"
20673
20674         diff /etc/passwd ${migrate_dir}/sofia ||
20675                 error "sofia different after migration"
20676
20677         diff /etc/passwd ${other_dir}/zachary ||
20678                 error "zachary different after migration"
20679
20680         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20681                 error "${tfile}_ln different after migration"
20682
20683         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20684                 error "${tfile}_ln_other different after migration"
20685
20686         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20687         [ $stripe_count = 2 ] ||
20688                 error "dir strpe_count $d != 2 after migration."
20689
20690         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20691         [ $stripe_count = 2 ] ||
20692                 error "file strpe_count $d != 2 after migration."
20693
20694         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20695 }
20696 run_test 230b "migrate directory"
20697
20698 test_230c() {
20699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20700         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20701         remote_mds_nodsh && skip "remote MDS with nodsh"
20702         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20703                 skip "Need MDS version at least 2.11.52"
20704
20705         local MDTIDX=1
20706         local total=3
20707         local mdt_index
20708         local file
20709         local migrate_dir=$DIR/$tdir/migrate_dir
20710
20711         #If migrating directory fails in the middle, all entries of
20712         #the directory is still accessiable.
20713         test_mkdir $DIR/$tdir
20714         test_mkdir -i0 -c1 $migrate_dir
20715         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20716         stat $migrate_dir
20717         createmany -o $migrate_dir/f $total ||
20718                 error "create files under ${migrate_dir} failed"
20719
20720         # fail after migrating top dir, and this will fail only once, so the
20721         # first sub file migration will fail (currently f3), others succeed.
20722         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20723         do_facet mds1 lctl set_param fail_loc=0x1801
20724         local t=$(ls $migrate_dir | wc -l)
20725         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20726                 error "migrate should fail"
20727         local u=$(ls $migrate_dir | wc -l)
20728         [ "$u" == "$t" ] || error "$u != $t during migration"
20729
20730         # add new dir/file should succeed
20731         mkdir $migrate_dir/dir ||
20732                 error "mkdir failed under migrating directory"
20733         touch $migrate_dir/file ||
20734                 error "create file failed under migrating directory"
20735
20736         # add file with existing name should fail
20737         for file in $migrate_dir/f*; do
20738                 stat $file > /dev/null || error "stat $file failed"
20739                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20740                         error "open(O_CREAT|O_EXCL) $file should fail"
20741                 $MULTIOP $file m && error "create $file should fail"
20742                 touch $DIR/$tdir/remote_dir/$tfile ||
20743                         error "touch $tfile failed"
20744                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20745                         error "link $file should fail"
20746                 mdt_index=$($LFS getstripe -m $file)
20747                 if [ $mdt_index == 0 ]; then
20748                         # file failed to migrate is not allowed to rename to
20749                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20750                                 error "rename to $file should fail"
20751                 else
20752                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20753                                 error "rename to $file failed"
20754                 fi
20755                 echo hello >> $file || error "write $file failed"
20756         done
20757
20758         # resume migration with different options should fail
20759         $LFS migrate -m 0 $migrate_dir &&
20760                 error "migrate -m 0 $migrate_dir should fail"
20761
20762         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20763                 error "migrate -c 2 $migrate_dir should fail"
20764
20765         # resume migration should succeed
20766         $LFS migrate -m $MDTIDX $migrate_dir ||
20767                 error "migrate $migrate_dir failed"
20768
20769         echo "Finish migration, then checking.."
20770         for file in $(find $migrate_dir); do
20771                 mdt_index=$($LFS getstripe -m $file)
20772                 [ $mdt_index == $MDTIDX ] ||
20773                         error "$file is not on MDT${MDTIDX}"
20774         done
20775
20776         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20777 }
20778 run_test 230c "check directory accessiblity if migration failed"
20779
20780 test_230d() {
20781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20783         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20784                 skip "Need MDS version at least 2.11.52"
20785         # LU-11235
20786         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20787
20788         local migrate_dir=$DIR/$tdir/migrate_dir
20789         local old_index
20790         local new_index
20791         local old_count
20792         local new_count
20793         local new_hash
20794         local mdt_index
20795         local i
20796         local j
20797
20798         old_index=$((RANDOM % MDSCOUNT))
20799         old_count=$((MDSCOUNT - old_index))
20800         new_index=$((RANDOM % MDSCOUNT))
20801         new_count=$((MDSCOUNT - new_index))
20802         new_hash=1 # for all_char
20803
20804         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20805         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20806
20807         test_mkdir $DIR/$tdir
20808         test_mkdir -i $old_index -c $old_count $migrate_dir
20809
20810         for ((i=0; i<100; i++)); do
20811                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20812                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20813                         error "create files under remote dir failed $i"
20814         done
20815
20816         echo -n "Migrate from MDT$old_index "
20817         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20818         echo -n "to MDT$new_index"
20819         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20820         echo
20821
20822         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20823         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20824                 error "migrate remote dir error"
20825
20826         echo "Finish migration, then checking.."
20827         for file in $(find $migrate_dir -maxdepth 1); do
20828                 mdt_index=$($LFS getstripe -m $file)
20829                 if [ $mdt_index -lt $new_index ] ||
20830                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20831                         error "$file is on MDT$mdt_index"
20832                 fi
20833         done
20834
20835         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20836 }
20837 run_test 230d "check migrate big directory"
20838
20839 test_230e() {
20840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20842         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20843                 skip "Need MDS version at least 2.11.52"
20844
20845         local i
20846         local j
20847         local a_fid
20848         local b_fid
20849
20850         mkdir_on_mdt0 $DIR/$tdir
20851         mkdir $DIR/$tdir/migrate_dir
20852         mkdir $DIR/$tdir/other_dir
20853         touch $DIR/$tdir/migrate_dir/a
20854         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20855         ls $DIR/$tdir/other_dir
20856
20857         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20858                 error "migrate dir fails"
20859
20860         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20861         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20862
20863         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20864         [ $mdt_index == 0 ] || error "a is not on MDT0"
20865
20866         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20867                 error "migrate dir fails"
20868
20869         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20870         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20871
20872         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20873         [ $mdt_index == 1 ] || error "a is not on MDT1"
20874
20875         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20876         [ $mdt_index == 1 ] || error "b is not on MDT1"
20877
20878         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20879         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20880
20881         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20882
20883         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20884 }
20885 run_test 230e "migrate mulitple local link files"
20886
20887 test_230f() {
20888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20890         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20891                 skip "Need MDS version at least 2.11.52"
20892
20893         local a_fid
20894         local ln_fid
20895
20896         mkdir -p $DIR/$tdir
20897         mkdir $DIR/$tdir/migrate_dir
20898         $LFS mkdir -i1 $DIR/$tdir/other_dir
20899         touch $DIR/$tdir/migrate_dir/a
20900         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20901         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20902         ls $DIR/$tdir/other_dir
20903
20904         # a should be migrated to MDT1, since no other links on MDT0
20905         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20906                 error "#1 migrate dir fails"
20907         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20908         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20909         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20910         [ $mdt_index == 1 ] || error "a is not on MDT1"
20911
20912         # a should stay on MDT1, because it is a mulitple link file
20913         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20914                 error "#2 migrate dir fails"
20915         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20916         [ $mdt_index == 1 ] || error "a is not on MDT1"
20917
20918         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20919                 error "#3 migrate dir fails"
20920
20921         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20922         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20923         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20924
20925         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20926         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20927
20928         # a should be migrated to MDT0, since no other links on MDT1
20929         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20930                 error "#4 migrate dir fails"
20931         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20932         [ $mdt_index == 0 ] || error "a is not on MDT0"
20933
20934         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20935 }
20936 run_test 230f "migrate mulitple remote link files"
20937
20938 test_230g() {
20939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20940         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20941         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20942                 skip "Need MDS version at least 2.11.52"
20943
20944         mkdir -p $DIR/$tdir/migrate_dir
20945
20946         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20947                 error "migrating dir to non-exist MDT succeeds"
20948         true
20949 }
20950 run_test 230g "migrate dir to non-exist MDT"
20951
20952 test_230h() {
20953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20955         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20956                 skip "Need MDS version at least 2.11.52"
20957
20958         local mdt_index
20959
20960         mkdir -p $DIR/$tdir/migrate_dir
20961
20962         $LFS migrate -m1 $DIR &&
20963                 error "migrating mountpoint1 should fail"
20964
20965         $LFS migrate -m1 $DIR/$tdir/.. &&
20966                 error "migrating mountpoint2 should fail"
20967
20968         # same as mv
20969         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20970                 error "migrating $tdir/migrate_dir/.. should fail"
20971
20972         true
20973 }
20974 run_test 230h "migrate .. and root"
20975
20976 test_230i() {
20977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20979         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20980                 skip "Need MDS version at least 2.11.52"
20981
20982         mkdir -p $DIR/$tdir/migrate_dir
20983
20984         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20985                 error "migration fails with a tailing slash"
20986
20987         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20988                 error "migration fails with two tailing slashes"
20989 }
20990 run_test 230i "lfs migrate -m tolerates trailing slashes"
20991
20992 test_230j() {
20993         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20994         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20995                 skip "Need MDS version at least 2.11.52"
20996
20997         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20998         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20999                 error "create $tfile failed"
21000         cat /etc/passwd > $DIR/$tdir/$tfile
21001
21002         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21003
21004         cmp /etc/passwd $DIR/$tdir/$tfile ||
21005                 error "DoM file mismatch after migration"
21006 }
21007 run_test 230j "DoM file data not changed after dir migration"
21008
21009 test_230k() {
21010         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21011         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21012                 skip "Need MDS version at least 2.11.56"
21013
21014         local total=20
21015         local files_on_starting_mdt=0
21016
21017         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21018         $LFS getdirstripe $DIR/$tdir
21019         for i in $(seq $total); do
21020                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21021                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21022                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21023         done
21024
21025         echo "$files_on_starting_mdt files on MDT0"
21026
21027         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21028         $LFS getdirstripe $DIR/$tdir
21029
21030         files_on_starting_mdt=0
21031         for i in $(seq $total); do
21032                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21033                         error "file $tfile.$i mismatch after migration"
21034                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21035                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21036         done
21037
21038         echo "$files_on_starting_mdt files on MDT1 after migration"
21039         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21040
21041         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21042         $LFS getdirstripe $DIR/$tdir
21043
21044         files_on_starting_mdt=0
21045         for i in $(seq $total); do
21046                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21047                         error "file $tfile.$i mismatch after 2nd migration"
21048                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21049                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21050         done
21051
21052         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21053         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21054
21055         true
21056 }
21057 run_test 230k "file data not changed after dir migration"
21058
21059 test_230l() {
21060         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21061         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21062                 skip "Need MDS version at least 2.11.56"
21063
21064         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21065         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21066                 error "create files under remote dir failed $i"
21067         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21068 }
21069 run_test 230l "readdir between MDTs won't crash"
21070
21071 test_230m() {
21072         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21073         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21074                 skip "Need MDS version at least 2.11.56"
21075
21076         local MDTIDX=1
21077         local mig_dir=$DIR/$tdir/migrate_dir
21078         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21079         local shortstr="b"
21080         local val
21081
21082         echo "Creating files and dirs with xattrs"
21083         test_mkdir $DIR/$tdir
21084         test_mkdir -i0 -c1 $mig_dir
21085         mkdir $mig_dir/dir
21086         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21087                 error "cannot set xattr attr1 on dir"
21088         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21089                 error "cannot set xattr attr2 on dir"
21090         touch $mig_dir/dir/f0
21091         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21092                 error "cannot set xattr attr1 on file"
21093         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21094                 error "cannot set xattr attr2 on file"
21095         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21096         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21097         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21098         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21099         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21100         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21101         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21102         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21103         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21104
21105         echo "Migrating to MDT1"
21106         $LFS migrate -m $MDTIDX $mig_dir ||
21107                 error "fails on migrating dir to MDT1"
21108
21109         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21110         echo "Checking xattrs"
21111         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21112         [ "$val" = $longstr ] ||
21113                 error "expecting xattr1 $longstr on dir, found $val"
21114         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21115         [ "$val" = $shortstr ] ||
21116                 error "expecting xattr2 $shortstr on dir, found $val"
21117         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21118         [ "$val" = $longstr ] ||
21119                 error "expecting xattr1 $longstr on file, found $val"
21120         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21121         [ "$val" = $shortstr ] ||
21122                 error "expecting xattr2 $shortstr on file, found $val"
21123 }
21124 run_test 230m "xattrs not changed after dir migration"
21125
21126 test_230n() {
21127         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21128         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21129                 skip "Need MDS version at least 2.13.53"
21130
21131         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21132         cat /etc/hosts > $DIR/$tdir/$tfile
21133         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21134         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21135
21136         cmp /etc/hosts $DIR/$tdir/$tfile ||
21137                 error "File data mismatch after migration"
21138 }
21139 run_test 230n "Dir migration with mirrored file"
21140
21141 test_230o() {
21142         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21143         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21144                 skip "Need MDS version at least 2.13.52"
21145
21146         local mdts=$(comma_list $(mdts_nodes))
21147         local timeout=100
21148         local restripe_status
21149         local delta
21150         local i
21151
21152         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21153
21154         # in case "crush" hash type is not set
21155         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21156
21157         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21158                            mdt.*MDT0000.enable_dir_restripe)
21159         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21160         stack_trap "do_nodes $mdts $LCTL set_param \
21161                     mdt.*.enable_dir_restripe=$restripe_status"
21162
21163         mkdir $DIR/$tdir
21164         createmany -m $DIR/$tdir/f 100 ||
21165                 error "create files under remote dir failed $i"
21166         createmany -d $DIR/$tdir/d 100 ||
21167                 error "create dirs under remote dir failed $i"
21168
21169         for i in $(seq 2 $MDSCOUNT); do
21170                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21171                 $LFS setdirstripe -c $i $DIR/$tdir ||
21172                         error "split -c $i $tdir failed"
21173                 wait_update $HOSTNAME \
21174                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21175                         error "dir split not finished"
21176                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21177                         awk '/migrate/ {sum += $2} END { print sum }')
21178                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21179                 # delta is around total_files/stripe_count
21180                 (( $delta < 200 / (i - 1) + 4 )) ||
21181                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21182         done
21183 }
21184 run_test 230o "dir split"
21185
21186 test_230p() {
21187         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21188         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21189                 skip "Need MDS version at least 2.13.52"
21190
21191         local mdts=$(comma_list $(mdts_nodes))
21192         local timeout=100
21193         local restripe_status
21194         local delta
21195         local c
21196
21197         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21198
21199         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21200
21201         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21202                            mdt.*MDT0000.enable_dir_restripe)
21203         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21204         stack_trap "do_nodes $mdts $LCTL set_param \
21205                     mdt.*.enable_dir_restripe=$restripe_status"
21206
21207         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21208         createmany -m $DIR/$tdir/f 100 ||
21209                 error "create files under remote dir failed"
21210         createmany -d $DIR/$tdir/d 100 ||
21211                 error "create dirs under remote dir failed"
21212
21213         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21214                 local mdt_hash="crush"
21215
21216                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21217                 $LFS setdirstripe -c $c $DIR/$tdir ||
21218                         error "split -c $c $tdir failed"
21219                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21220                         mdt_hash="$mdt_hash,fixed"
21221                 elif [ $c -eq 1 ]; then
21222                         mdt_hash="none"
21223                 fi
21224                 wait_update $HOSTNAME \
21225                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21226                         error "dir merge not finished"
21227                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21228                         awk '/migrate/ {sum += $2} END { print sum }')
21229                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21230                 # delta is around total_files/stripe_count
21231                 (( delta < 200 / c + 4 )) ||
21232                         error "$delta files migrated >= $((200 / c + 4))"
21233         done
21234 }
21235 run_test 230p "dir merge"
21236
21237 test_230q() {
21238         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21239         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21240                 skip "Need MDS version at least 2.13.52"
21241
21242         local mdts=$(comma_list $(mdts_nodes))
21243         local saved_threshold=$(do_facet mds1 \
21244                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21245         local saved_delta=$(do_facet mds1 \
21246                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21247         local threshold=100
21248         local delta=2
21249         local total=0
21250         local stripe_count=0
21251         local stripe_index
21252         local nr_files
21253         local create
21254
21255         # test with fewer files on ZFS
21256         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21257
21258         stack_trap "do_nodes $mdts $LCTL set_param \
21259                     mdt.*.dir_split_count=$saved_threshold"
21260         stack_trap "do_nodes $mdts $LCTL set_param \
21261                     mdt.*.dir_split_delta=$saved_delta"
21262         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21263         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21264         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21265         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21266         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21267         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21268
21269         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21270         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21271
21272         create=$((threshold * 3 / 2))
21273         while [ $stripe_count -lt $MDSCOUNT ]; do
21274                 createmany -m $DIR/$tdir/f $total $create ||
21275                         error "create sub files failed"
21276                 stat $DIR/$tdir > /dev/null
21277                 total=$((total + create))
21278                 stripe_count=$((stripe_count + delta))
21279                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21280
21281                 wait_update $HOSTNAME \
21282                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21283                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21284
21285                 wait_update $HOSTNAME \
21286                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21287                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21288
21289                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21290                 echo "$nr_files/$total files on MDT$stripe_index after split"
21291                 # allow 10% margin of imbalance with crush hash
21292                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21293                         error "$nr_files files on MDT$stripe_index after split"
21294
21295                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21296                 [ $nr_files -eq $total ] ||
21297                         error "total sub files $nr_files != $total"
21298         done
21299
21300         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21301
21302         echo "fixed layout directory won't auto split"
21303         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21304         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21305                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21306         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21307                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21308 }
21309 run_test 230q "dir auto split"
21310
21311 test_230r() {
21312         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21313         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21314         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21315                 skip "Need MDS version at least 2.13.54"
21316
21317         # maximum amount of local locks:
21318         # parent striped dir - 2 locks
21319         # new stripe in parent to migrate to - 1 lock
21320         # source and target - 2 locks
21321         # Total 5 locks for regular file
21322         mkdir -p $DIR/$tdir
21323         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21324         touch $DIR/$tdir/dir1/eee
21325
21326         # create 4 hardlink for 4 more locks
21327         # Total: 9 locks > RS_MAX_LOCKS (8)
21328         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21329         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21330         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21331         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21332         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21333         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21334         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21335         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21336
21337         cancel_lru_locks mdc
21338
21339         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21340                 error "migrate dir fails"
21341
21342         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21343 }
21344 run_test 230r "migrate with too many local locks"
21345
21346 test_230s() {
21347         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21348                 skip "Need MDS version at least 2.14.52"
21349
21350         local mdts=$(comma_list $(mdts_nodes))
21351         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21352                                 mdt.*MDT0000.enable_dir_restripe)
21353
21354         stack_trap "do_nodes $mdts $LCTL set_param \
21355                     mdt.*.enable_dir_restripe=$restripe_status"
21356
21357         local st
21358         for st in 0 1; do
21359                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21360                 test_mkdir $DIR/$tdir
21361                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21362                         error "$LFS mkdir should return EEXIST if target exists"
21363                 rmdir $DIR/$tdir
21364         done
21365 }
21366 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21367
21368 test_230t()
21369 {
21370         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21371         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21372                 skip "Need MDS version at least 2.14.50"
21373
21374         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21375         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21376         $LFS project -p 1 -s $DIR/$tdir ||
21377                 error "set $tdir project id failed"
21378         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21379                 error "set subdir project id failed"
21380         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21381 }
21382 run_test 230t "migrate directory with project ID set"
21383
21384 test_230u()
21385 {
21386         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21387         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21388                 skip "Need MDS version at least 2.14.53"
21389
21390         local count
21391
21392         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21393         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21394         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21395         for i in $(seq 0 $((MDSCOUNT - 1))); do
21396                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21397                 echo "$count dirs migrated to MDT$i"
21398         done
21399         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21400         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21401 }
21402 run_test 230u "migrate directory by QOS"
21403
21404 test_230v()
21405 {
21406         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21407         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21408                 skip "Need MDS version at least 2.14.53"
21409
21410         local count
21411
21412         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21413         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21414         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21415         for i in $(seq 0 $((MDSCOUNT - 1))); do
21416                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21417                 echo "$count subdirs migrated to MDT$i"
21418                 (( i == 3 )) && (( count > 0 )) &&
21419                         error "subdir shouldn't be migrated to MDT3"
21420         done
21421         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21422         (( count == 3 )) || error "dirs migrated to $count MDTs"
21423 }
21424 run_test 230v "subdir migrated to the MDT where its parent is located"
21425
21426 test_230w() {
21427         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21428         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21429                 skip "Need MDS version at least 2.15.0"
21430
21431         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21432         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21433         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21434
21435         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21436                 error "migrate failed"
21437
21438         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21439                 error "$tdir stripe count mismatch"
21440
21441         for i in $(seq 0 9); do
21442                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21443                         error "d$i is striped"
21444         done
21445 }
21446 run_test 230w "non-recursive mode dir migration"
21447
21448 test_230x() {
21449         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21450         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21451                 skip "Need MDS version at least 2.15.0"
21452
21453         mkdir -p $DIR/$tdir || error "mkdir failed"
21454         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21455
21456         local mdt_name=$(mdtname_from_index 0)
21457         local low=$(do_facet mds2 $LCTL get_param -n \
21458                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21459         local high=$(do_facet mds2 $LCTL get_param -n \
21460                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21461         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21462         local maxage=$(do_facet mds2 $LCTL get_param -n \
21463                 osp.*$mdt_name-osp-MDT0001.maxage)
21464
21465         stack_trap "do_facet mds2 $LCTL set_param -n \
21466                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21467                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21468         stack_trap "do_facet mds2 $LCTL set_param -n \
21469                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21470
21471         do_facet mds2 $LCTL set_param -n \
21472                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21473         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21474         sleep 4
21475         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21476                 error "migrate $tdir should fail"
21477
21478         do_facet mds2 $LCTL set_param -n \
21479                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21480         do_facet mds2 $LCTL set_param -n \
21481                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21482         sleep 4
21483         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21484                 error "migrate failed"
21485         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21486                 error "$tdir stripe count mismatch"
21487 }
21488 run_test 230x "dir migration check space"
21489
21490 test_231a()
21491 {
21492         # For simplicity this test assumes that max_pages_per_rpc
21493         # is the same across all OSCs
21494         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21495         local bulk_size=$((max_pages * PAGE_SIZE))
21496         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21497                                        head -n 1)
21498
21499         mkdir -p $DIR/$tdir
21500         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21501                 error "failed to set stripe with -S ${brw_size}M option"
21502
21503         # clear the OSC stats
21504         $LCTL set_param osc.*.stats=0 &>/dev/null
21505         stop_writeback
21506
21507         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21508         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21509                 oflag=direct &>/dev/null || error "dd failed"
21510
21511         sync; sleep 1; sync # just to be safe
21512         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21513         if [ x$nrpcs != "x1" ]; then
21514                 $LCTL get_param osc.*.stats
21515                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21516         fi
21517
21518         start_writeback
21519         # Drop the OSC cache, otherwise we will read from it
21520         cancel_lru_locks osc
21521
21522         # clear the OSC stats
21523         $LCTL set_param osc.*.stats=0 &>/dev/null
21524
21525         # Client reads $bulk_size.
21526         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21527                 iflag=direct &>/dev/null || error "dd failed"
21528
21529         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21530         if [ x$nrpcs != "x1" ]; then
21531                 $LCTL get_param osc.*.stats
21532                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21533         fi
21534 }
21535 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21536
21537 test_231b() {
21538         mkdir -p $DIR/$tdir
21539         local i
21540         for i in {0..1023}; do
21541                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21542                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21543                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21544         done
21545         sync
21546 }
21547 run_test 231b "must not assert on fully utilized OST request buffer"
21548
21549 test_232a() {
21550         mkdir -p $DIR/$tdir
21551         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21552
21553         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21554         do_facet ost1 $LCTL set_param fail_loc=0x31c
21555
21556         # ignore dd failure
21557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21558
21559         do_facet ost1 $LCTL set_param fail_loc=0
21560         umount_client $MOUNT || error "umount failed"
21561         mount_client $MOUNT || error "mount failed"
21562         stop ost1 || error "cannot stop ost1"
21563         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21564 }
21565 run_test 232a "failed lock should not block umount"
21566
21567 test_232b() {
21568         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21569                 skip "Need MDS version at least 2.10.58"
21570
21571         mkdir -p $DIR/$tdir
21572         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21574         sync
21575         cancel_lru_locks osc
21576
21577         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21578         do_facet ost1 $LCTL set_param fail_loc=0x31c
21579
21580         # ignore failure
21581         $LFS data_version $DIR/$tdir/$tfile || true
21582
21583         do_facet ost1 $LCTL set_param fail_loc=0
21584         umount_client $MOUNT || error "umount failed"
21585         mount_client $MOUNT || error "mount failed"
21586         stop ost1 || error "cannot stop ost1"
21587         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21588 }
21589 run_test 232b "failed data version lock should not block umount"
21590
21591 test_233a() {
21592         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21593                 skip "Need MDS version at least 2.3.64"
21594         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21595
21596         local fid=$($LFS path2fid $MOUNT)
21597
21598         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21599                 error "cannot access $MOUNT using its FID '$fid'"
21600 }
21601 run_test 233a "checking that OBF of the FS root succeeds"
21602
21603 test_233b() {
21604         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21605                 skip "Need MDS version at least 2.5.90"
21606         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21607
21608         local fid=$($LFS path2fid $MOUNT/.lustre)
21609
21610         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21611                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21612
21613         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21614         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21615                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21616 }
21617 run_test 233b "checking that OBF of the FS .lustre succeeds"
21618
21619 test_234() {
21620         local p="$TMP/sanityN-$TESTNAME.parameters"
21621         save_lustre_params client "llite.*.xattr_cache" > $p
21622         lctl set_param llite.*.xattr_cache 1 ||
21623                 skip_env "xattr cache is not supported"
21624
21625         mkdir -p $DIR/$tdir || error "mkdir failed"
21626         touch $DIR/$tdir/$tfile || error "touch failed"
21627         # OBD_FAIL_LLITE_XATTR_ENOMEM
21628         $LCTL set_param fail_loc=0x1405
21629         getfattr -n user.attr $DIR/$tdir/$tfile &&
21630                 error "getfattr should have failed with ENOMEM"
21631         $LCTL set_param fail_loc=0x0
21632         rm -rf $DIR/$tdir
21633
21634         restore_lustre_params < $p
21635         rm -f $p
21636 }
21637 run_test 234 "xattr cache should not crash on ENOMEM"
21638
21639 test_235() {
21640         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21641                 skip "Need MDS version at least 2.4.52"
21642
21643         flock_deadlock $DIR/$tfile
21644         local RC=$?
21645         case $RC in
21646                 0)
21647                 ;;
21648                 124) error "process hangs on a deadlock"
21649                 ;;
21650                 *) error "error executing flock_deadlock $DIR/$tfile"
21651                 ;;
21652         esac
21653 }
21654 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21655
21656 #LU-2935
21657 test_236() {
21658         check_swap_layouts_support
21659
21660         local ref1=/etc/passwd
21661         local ref2=/etc/group
21662         local file1=$DIR/$tdir/f1
21663         local file2=$DIR/$tdir/f2
21664
21665         test_mkdir -c1 $DIR/$tdir
21666         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21667         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21668         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21669         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21670         local fd=$(free_fd)
21671         local cmd="exec $fd<>$file2"
21672         eval $cmd
21673         rm $file2
21674         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21675                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21676         cmd="exec $fd>&-"
21677         eval $cmd
21678         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21679
21680         #cleanup
21681         rm -rf $DIR/$tdir
21682 }
21683 run_test 236 "Layout swap on open unlinked file"
21684
21685 # LU-4659 linkea consistency
21686 test_238() {
21687         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21688                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21689                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21690                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21691
21692         touch $DIR/$tfile
21693         ln $DIR/$tfile $DIR/$tfile.lnk
21694         touch $DIR/$tfile.new
21695         mv $DIR/$tfile.new $DIR/$tfile
21696         local fid1=$($LFS path2fid $DIR/$tfile)
21697         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21698         local path1=$($LFS fid2path $FSNAME "$fid1")
21699         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21700         local path2=$($LFS fid2path $FSNAME "$fid2")
21701         [ $tfile.lnk == $path2 ] ||
21702                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21703         rm -f $DIR/$tfile*
21704 }
21705 run_test 238 "Verify linkea consistency"
21706
21707 test_239A() { # was test_239
21708         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21709                 skip "Need MDS version at least 2.5.60"
21710
21711         local list=$(comma_list $(mdts_nodes))
21712
21713         mkdir -p $DIR/$tdir
21714         createmany -o $DIR/$tdir/f- 5000
21715         unlinkmany $DIR/$tdir/f- 5000
21716         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21717                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21718         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21719                         osp.*MDT*.sync_in_flight" | calc_sum)
21720         [ "$changes" -eq 0 ] || error "$changes not synced"
21721 }
21722 run_test 239A "osp_sync test"
21723
21724 test_239a() { #LU-5297
21725         remote_mds_nodsh && skip "remote MDS with nodsh"
21726
21727         touch $DIR/$tfile
21728         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21729         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21730         chgrp $RUNAS_GID $DIR/$tfile
21731         wait_delete_completed
21732 }
21733 run_test 239a "process invalid osp sync record correctly"
21734
21735 test_239b() { #LU-5297
21736         remote_mds_nodsh && skip "remote MDS with nodsh"
21737
21738         touch $DIR/$tfile1
21739         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21740         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21741         chgrp $RUNAS_GID $DIR/$tfile1
21742         wait_delete_completed
21743         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21744         touch $DIR/$tfile2
21745         chgrp $RUNAS_GID $DIR/$tfile2
21746         wait_delete_completed
21747 }
21748 run_test 239b "process osp sync record with ENOMEM error correctly"
21749
21750 test_240() {
21751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21752         remote_mds_nodsh && skip "remote MDS with nodsh"
21753
21754         mkdir -p $DIR/$tdir
21755
21756         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21757                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21758         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21759                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21760
21761         umount_client $MOUNT || error "umount failed"
21762         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21763         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21764         mount_client $MOUNT || error "failed to mount client"
21765
21766         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21767         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21768 }
21769 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21770
21771 test_241_bio() {
21772         local count=$1
21773         local bsize=$2
21774
21775         for LOOP in $(seq $count); do
21776                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21777                 cancel_lru_locks $OSC || true
21778         done
21779 }
21780
21781 test_241_dio() {
21782         local count=$1
21783         local bsize=$2
21784
21785         for LOOP in $(seq $1); do
21786                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21787                         2>/dev/null
21788         done
21789 }
21790
21791 test_241a() { # was test_241
21792         local bsize=$PAGE_SIZE
21793
21794         (( bsize < 40960 )) && bsize=40960
21795         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21796         ls -la $DIR/$tfile
21797         cancel_lru_locks $OSC
21798         test_241_bio 1000 $bsize &
21799         PID=$!
21800         test_241_dio 1000 $bsize
21801         wait $PID
21802 }
21803 run_test 241a "bio vs dio"
21804
21805 test_241b() {
21806         local bsize=$PAGE_SIZE
21807
21808         (( bsize < 40960 )) && bsize=40960
21809         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21810         ls -la $DIR/$tfile
21811         test_241_dio 1000 $bsize &
21812         PID=$!
21813         test_241_dio 1000 $bsize
21814         wait $PID
21815 }
21816 run_test 241b "dio vs dio"
21817
21818 test_242() {
21819         remote_mds_nodsh && skip "remote MDS with nodsh"
21820
21821         mkdir_on_mdt0 $DIR/$tdir
21822         touch $DIR/$tdir/$tfile
21823
21824         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21825         do_facet mds1 lctl set_param fail_loc=0x105
21826         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21827
21828         do_facet mds1 lctl set_param fail_loc=0
21829         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21830 }
21831 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21832
21833 test_243()
21834 {
21835         test_mkdir $DIR/$tdir
21836         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21837 }
21838 run_test 243 "various group lock tests"
21839
21840 test_244a()
21841 {
21842         test_mkdir $DIR/$tdir
21843         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21844         sendfile_grouplock $DIR/$tdir/$tfile || \
21845                 error "sendfile+grouplock failed"
21846         rm -rf $DIR/$tdir
21847 }
21848 run_test 244a "sendfile with group lock tests"
21849
21850 test_244b()
21851 {
21852         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21853
21854         local threads=50
21855         local size=$((1024*1024))
21856
21857         test_mkdir $DIR/$tdir
21858         for i in $(seq 1 $threads); do
21859                 local file=$DIR/$tdir/file_$((i / 10))
21860                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21861                 local pids[$i]=$!
21862         done
21863         for i in $(seq 1 $threads); do
21864                 wait ${pids[$i]}
21865         done
21866 }
21867 run_test 244b "multi-threaded write with group lock"
21868
21869 test_245a() {
21870         local flagname="multi_mod_rpcs"
21871         local connect_data_name="max_mod_rpcs"
21872         local out
21873
21874         # check if multiple modify RPCs flag is set
21875         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21876                 grep "connect_flags:")
21877         echo "$out"
21878
21879         echo "$out" | grep -qw $flagname
21880         if [ $? -ne 0 ]; then
21881                 echo "connect flag $flagname is not set"
21882                 return
21883         fi
21884
21885         # check if multiple modify RPCs data is set
21886         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21887         echo "$out"
21888
21889         echo "$out" | grep -qw $connect_data_name ||
21890                 error "import should have connect data $connect_data_name"
21891 }
21892 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21893
21894 test_245b() {
21895         local flagname="multi_mod_rpcs"
21896         local connect_data_name="max_mod_rpcs"
21897         local out
21898
21899         remote_mds_nodsh && skip "remote MDS with nodsh"
21900         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21901
21902         # check if multiple modify RPCs flag is set
21903         out=$(do_facet mds1 \
21904               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21905               grep "connect_flags:")
21906         echo "$out"
21907
21908         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21909
21910         # check if multiple modify RPCs data is set
21911         out=$(do_facet mds1 \
21912               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21913
21914         [[ "$out" =~ $connect_data_name ]] ||
21915                 {
21916                         echo "$out"
21917                         error "missing connect data $connect_data_name"
21918                 }
21919 }
21920 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21921
21922 cleanup_247() {
21923         local submount=$1
21924
21925         trap 0
21926         umount_client $submount
21927         rmdir $submount
21928 }
21929
21930 test_247a() {
21931         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21932                 grep -q subtree ||
21933                 skip_env "Fileset feature is not supported"
21934
21935         local submount=${MOUNT}_$tdir
21936
21937         mkdir $MOUNT/$tdir
21938         mkdir -p $submount || error "mkdir $submount failed"
21939         FILESET="$FILESET/$tdir" mount_client $submount ||
21940                 error "mount $submount failed"
21941         trap "cleanup_247 $submount" EXIT
21942         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21943         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21944                 error "read $MOUNT/$tdir/$tfile failed"
21945         cleanup_247 $submount
21946 }
21947 run_test 247a "mount subdir as fileset"
21948
21949 test_247b() {
21950         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21951                 skip_env "Fileset feature is not supported"
21952
21953         local submount=${MOUNT}_$tdir
21954
21955         rm -rf $MOUNT/$tdir
21956         mkdir -p $submount || error "mkdir $submount failed"
21957         SKIP_FILESET=1
21958         FILESET="$FILESET/$tdir" mount_client $submount &&
21959                 error "mount $submount should fail"
21960         rmdir $submount
21961 }
21962 run_test 247b "mount subdir that dose not exist"
21963
21964 test_247c() {
21965         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21966                 skip_env "Fileset feature is not supported"
21967
21968         local submount=${MOUNT}_$tdir
21969
21970         mkdir -p $MOUNT/$tdir/dir1
21971         mkdir -p $submount || error "mkdir $submount failed"
21972         trap "cleanup_247 $submount" EXIT
21973         FILESET="$FILESET/$tdir" mount_client $submount ||
21974                 error "mount $submount failed"
21975         local fid=$($LFS path2fid $MOUNT/)
21976         $LFS fid2path $submount $fid && error "fid2path should fail"
21977         cleanup_247 $submount
21978 }
21979 run_test 247c "running fid2path outside subdirectory root"
21980
21981 test_247d() {
21982         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21983                 skip "Fileset feature is not supported"
21984
21985         local submount=${MOUNT}_$tdir
21986
21987         mkdir -p $MOUNT/$tdir/dir1
21988         mkdir -p $submount || error "mkdir $submount failed"
21989         FILESET="$FILESET/$tdir" mount_client $submount ||
21990                 error "mount $submount failed"
21991         trap "cleanup_247 $submount" EXIT
21992
21993         local td=$submount/dir1
21994         local fid=$($LFS path2fid $td)
21995         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21996
21997         # check that we get the same pathname back
21998         local rootpath
21999         local found
22000         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22001                 echo "$rootpath $fid"
22002                 found=$($LFS fid2path $rootpath "$fid")
22003                 [ -n "$found" ] || error "fid2path should succeed"
22004                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22005         done
22006         # check wrong root path format
22007         rootpath=$submount"_wrong"
22008         found=$($LFS fid2path $rootpath "$fid")
22009         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22010
22011         cleanup_247 $submount
22012 }
22013 run_test 247d "running fid2path inside subdirectory root"
22014
22015 # LU-8037
22016 test_247e() {
22017         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22018                 grep -q subtree ||
22019                 skip "Fileset feature is not supported"
22020
22021         local submount=${MOUNT}_$tdir
22022
22023         mkdir $MOUNT/$tdir
22024         mkdir -p $submount || error "mkdir $submount failed"
22025         FILESET="$FILESET/.." mount_client $submount &&
22026                 error "mount $submount should fail"
22027         rmdir $submount
22028 }
22029 run_test 247e "mount .. as fileset"
22030
22031 test_247f() {
22032         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22033         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22034                 skip "Need at least version 2.14.50.162"
22035         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22036                 skip "Fileset feature is not supported"
22037
22038         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22039         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22040                 error "mkdir remote failed"
22041         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22042                 error "mkdir remote/subdir failed"
22043         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22044                 error "mkdir striped failed"
22045         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22046
22047         local submount=${MOUNT}_$tdir
22048
22049         mkdir -p $submount || error "mkdir $submount failed"
22050         stack_trap "rmdir $submount"
22051
22052         local dir
22053         local fileset=$FILESET
22054         local mdts=$(comma_list $(mdts_nodes))
22055
22056         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22057         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22058                 $tdir/striped/subdir $tdir/striped/.; do
22059                 FILESET="$fileset/$dir" mount_client $submount ||
22060                         error "mount $dir failed"
22061                 umount_client $submount
22062         done
22063 }
22064 run_test 247f "mount striped or remote directory as fileset"
22065
22066 test_subdir_mount_lock()
22067 {
22068         local testdir=$1
22069         local submount=${MOUNT}_$(basename $testdir)
22070
22071         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22072
22073         mkdir -p $submount || error "mkdir $submount failed"
22074         stack_trap "rmdir $submount"
22075
22076         FILESET="$fileset/$testdir" mount_client $submount ||
22077                 error "mount $FILESET failed"
22078         stack_trap "umount $submount"
22079
22080         local mdts=$(comma_list $(mdts_nodes))
22081
22082         local nrpcs
22083
22084         stat $submount > /dev/null || error "stat $submount failed"
22085         cancel_lru_locks $MDC
22086         stat $submount > /dev/null || error "stat $submount failed"
22087         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22088         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22089         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22090         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22091                 awk '/getattr/ {sum += $2} END {print sum}')
22092
22093         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22094 }
22095
22096 test_247g() {
22097         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22098
22099         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22100                 error "mkdir $tdir failed"
22101         test_subdir_mount_lock $tdir
22102 }
22103 run_test 247g "striped directory submount revalidate ROOT from cache"
22104
22105 test_247h() {
22106         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22107         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22108                 skip "Need MDS version at least 2.15.51"
22109
22110         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22111         test_subdir_mount_lock $tdir
22112         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22113         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22114                 error "mkdir $tdir.1 failed"
22115         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22116 }
22117 run_test 247h "remote directory submount revalidate ROOT from cache"
22118
22119 test_248a() {
22120         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22121         [ -z "$fast_read_sav" ] && skip "no fast read support"
22122
22123         # create a large file for fast read verification
22124         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22125
22126         # make sure the file is created correctly
22127         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22128                 { rm -f $DIR/$tfile; skip "file creation error"; }
22129
22130         echo "Test 1: verify that fast read is 4 times faster on cache read"
22131
22132         # small read with fast read enabled
22133         $LCTL set_param -n llite.*.fast_read=1
22134         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22135                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22136                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22137         # small read with fast read disabled
22138         $LCTL set_param -n llite.*.fast_read=0
22139         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22140                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22141                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22142
22143         # verify that fast read is 4 times faster for cache read
22144         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22145                 error_not_in_vm "fast read was not 4 times faster: " \
22146                            "$t_fast vs $t_slow"
22147
22148         echo "Test 2: verify the performance between big and small read"
22149         $LCTL set_param -n llite.*.fast_read=1
22150
22151         # 1k non-cache read
22152         cancel_lru_locks osc
22153         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22154                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22155                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22156
22157         # 1M non-cache read
22158         cancel_lru_locks osc
22159         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22160                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22161                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22162
22163         # verify that big IO is not 4 times faster than small IO
22164         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22165                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22166
22167         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22168         rm -f $DIR/$tfile
22169 }
22170 run_test 248a "fast read verification"
22171
22172 test_248b() {
22173         # Default short_io_bytes=16384, try both smaller and larger sizes.
22174         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22175         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22176         echo "bs=53248 count=113 normal buffered write"
22177         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22178                 error "dd of initial data file failed"
22179         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22180
22181         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22182         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22183                 error "dd with sync normal writes failed"
22184         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22185
22186         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22187         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22188                 error "dd with sync small writes failed"
22189         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22190
22191         cancel_lru_locks osc
22192
22193         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22194         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22195         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22196         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22197                 iflag=direct || error "dd with O_DIRECT small read failed"
22198         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22199         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22200                 error "compare $TMP/$tfile.1 failed"
22201
22202         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22203         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22204
22205         # just to see what the maximum tunable value is, and test parsing
22206         echo "test invalid parameter 2MB"
22207         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22208                 error "too-large short_io_bytes allowed"
22209         echo "test maximum parameter 512KB"
22210         # if we can set a larger short_io_bytes, run test regardless of version
22211         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22212                 # older clients may not allow setting it this large, that's OK
22213                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22214                         skip "Need at least client version 2.13.50"
22215                 error "medium short_io_bytes failed"
22216         fi
22217         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22218         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22219
22220         echo "test large parameter 64KB"
22221         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22222         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22223
22224         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22225         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22226                 error "dd with sync large writes failed"
22227         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22228
22229         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22230         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22231         num=$((113 * 4096 / PAGE_SIZE))
22232         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22233         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22234                 error "dd with O_DIRECT large writes failed"
22235         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22236                 error "compare $DIR/$tfile.3 failed"
22237
22238         cancel_lru_locks osc
22239
22240         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22241         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22242                 error "dd with O_DIRECT large read failed"
22243         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22244                 error "compare $TMP/$tfile.2 failed"
22245
22246         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22247         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22248                 error "dd with O_DIRECT large read failed"
22249         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22250                 error "compare $TMP/$tfile.3 failed"
22251 }
22252 run_test 248b "test short_io read and write for both small and large sizes"
22253
22254 test_249() { # LU-7890
22255         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22256                 skip "Need at least version 2.8.54"
22257
22258         rm -f $DIR/$tfile
22259         $LFS setstripe -c 1 $DIR/$tfile
22260         # Offset 2T == 4k * 512M
22261         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22262                 error "dd to 2T offset failed"
22263 }
22264 run_test 249 "Write above 2T file size"
22265
22266 test_250() {
22267         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22268          && skip "no 16TB file size limit on ZFS"
22269
22270         $LFS setstripe -c 1 $DIR/$tfile
22271         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22272         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22273         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22274         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22275                 conv=notrunc,fsync && error "append succeeded"
22276         return 0
22277 }
22278 run_test 250 "Write above 16T limit"
22279
22280 test_251() {
22281         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22282
22283         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22284         #Skip once - writing the first stripe will succeed
22285         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22286         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22287                 error "short write happened"
22288
22289         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22290         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22291                 error "short read happened"
22292
22293         rm -f $DIR/$tfile
22294 }
22295 run_test 251 "Handling short read and write correctly"
22296
22297 test_252() {
22298         remote_mds_nodsh && skip "remote MDS with nodsh"
22299         remote_ost_nodsh && skip "remote OST with nodsh"
22300         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22301                 skip_env "ldiskfs only test"
22302         fi
22303
22304         local tgt
22305         local dev
22306         local out
22307         local uuid
22308         local num
22309         local gen
22310
22311         # check lr_reader on OST0000
22312         tgt=ost1
22313         dev=$(facet_device $tgt)
22314         out=$(do_facet $tgt $LR_READER $dev)
22315         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22316         echo "$out"
22317         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22318         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22319                 error "Invalid uuid returned by $LR_READER on target $tgt"
22320         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22321
22322         # check lr_reader -c on MDT0000
22323         tgt=mds1
22324         dev=$(facet_device $tgt)
22325         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22326                 skip "$LR_READER does not support additional options"
22327         fi
22328         out=$(do_facet $tgt $LR_READER -c $dev)
22329         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22330         echo "$out"
22331         num=$(echo "$out" | grep -c "mdtlov")
22332         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22333                 error "Invalid number of mdtlov clients returned by $LR_READER"
22334         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22335
22336         # check lr_reader -cr on MDT0000
22337         out=$(do_facet $tgt $LR_READER -cr $dev)
22338         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22339         echo "$out"
22340         echo "$out" | grep -q "^reply_data:$" ||
22341                 error "$LR_READER should have returned 'reply_data' section"
22342         num=$(echo "$out" | grep -c "client_generation")
22343         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22344 }
22345 run_test 252 "check lr_reader tool"
22346
22347 test_253() {
22348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22349         remote_mds_nodsh && skip "remote MDS with nodsh"
22350         remote_mgs_nodsh && skip "remote MGS with nodsh"
22351
22352         local ostidx=0
22353         local rc=0
22354         local ost_name=$(ostname_from_index $ostidx)
22355
22356         # on the mdt's osc
22357         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22358         do_facet $SINGLEMDS $LCTL get_param -n \
22359                 osp.$mdtosc_proc1.reserved_mb_high ||
22360                 skip  "remote MDS does not support reserved_mb_high"
22361
22362         rm -rf $DIR/$tdir
22363         wait_mds_ost_sync
22364         wait_delete_completed
22365         mkdir $DIR/$tdir
22366
22367         pool_add $TESTNAME || error "Pool creation failed"
22368         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22369
22370         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22371                 error "Setstripe failed"
22372
22373         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22374
22375         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22376                     grep "watermarks")
22377         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22378
22379         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22380                         osp.$mdtosc_proc1.prealloc_status)
22381         echo "prealloc_status $oa_status"
22382
22383         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22384                 error "File creation should fail"
22385
22386         #object allocation was stopped, but we still able to append files
22387         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22388                 oflag=append || error "Append failed"
22389
22390         rm -f $DIR/$tdir/$tfile.0
22391
22392         # For this test, we want to delete the files we created to go out of
22393         # space but leave the watermark, so we remain nearly out of space
22394         ost_watermarks_enospc_delete_files $tfile $ostidx
22395
22396         wait_delete_completed
22397
22398         sleep_maxage
22399
22400         for i in $(seq 10 12); do
22401                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22402                         2>/dev/null || error "File creation failed after rm"
22403         done
22404
22405         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22406                         osp.$mdtosc_proc1.prealloc_status)
22407         echo "prealloc_status $oa_status"
22408
22409         if (( oa_status != 0 )); then
22410                 error "Object allocation still disable after rm"
22411         fi
22412 }
22413 run_test 253 "Check object allocation limit"
22414
22415 test_254() {
22416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22417         remote_mds_nodsh && skip "remote MDS with nodsh"
22418
22419         local mdt=$(facet_svc $SINGLEMDS)
22420
22421         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22422                 skip "MDS does not support changelog_size"
22423
22424         local cl_user
22425
22426         changelog_register || error "changelog_register failed"
22427
22428         changelog_clear 0 || error "changelog_clear failed"
22429
22430         local size1=$(do_facet $SINGLEMDS \
22431                       $LCTL get_param -n mdd.$mdt.changelog_size)
22432         echo "Changelog size $size1"
22433
22434         rm -rf $DIR/$tdir
22435         $LFS mkdir -i 0 $DIR/$tdir
22436         # change something
22437         mkdir -p $DIR/$tdir/pics/2008/zachy
22438         touch $DIR/$tdir/pics/2008/zachy/timestamp
22439         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22440         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22441         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22442         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22443         rm $DIR/$tdir/pics/desktop.jpg
22444
22445         local size2=$(do_facet $SINGLEMDS \
22446                       $LCTL get_param -n mdd.$mdt.changelog_size)
22447         echo "Changelog size after work $size2"
22448
22449         (( $size2 > $size1 )) ||
22450                 error "new Changelog size=$size2 less than old size=$size1"
22451 }
22452 run_test 254 "Check changelog size"
22453
22454 ladvise_no_type()
22455 {
22456         local type=$1
22457         local file=$2
22458
22459         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22460                 awk -F: '{print $2}' | grep $type > /dev/null
22461         if [ $? -ne 0 ]; then
22462                 return 0
22463         fi
22464         return 1
22465 }
22466
22467 ladvise_no_ioctl()
22468 {
22469         local file=$1
22470
22471         lfs ladvise -a willread $file > /dev/null 2>&1
22472         if [ $? -eq 0 ]; then
22473                 return 1
22474         fi
22475
22476         lfs ladvise -a willread $file 2>&1 |
22477                 grep "Inappropriate ioctl for device" > /dev/null
22478         if [ $? -eq 0 ]; then
22479                 return 0
22480         fi
22481         return 1
22482 }
22483
22484 percent() {
22485         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22486 }
22487
22488 # run a random read IO workload
22489 # usage: random_read_iops <filename> <filesize> <iosize>
22490 random_read_iops() {
22491         local file=$1
22492         local fsize=$2
22493         local iosize=${3:-4096}
22494
22495         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22496                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22497 }
22498
22499 drop_file_oss_cache() {
22500         local file="$1"
22501         local nodes="$2"
22502
22503         $LFS ladvise -a dontneed $file 2>/dev/null ||
22504                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22505 }
22506
22507 ladvise_willread_performance()
22508 {
22509         local repeat=10
22510         local average_origin=0
22511         local average_cache=0
22512         local average_ladvise=0
22513
22514         for ((i = 1; i <= $repeat; i++)); do
22515                 echo "Iter $i/$repeat: reading without willread hint"
22516                 cancel_lru_locks osc
22517                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22518                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22519                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22520                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22521
22522                 cancel_lru_locks osc
22523                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22524                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22525                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22526
22527                 cancel_lru_locks osc
22528                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22529                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22530                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22531                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22532                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22533         done
22534         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22535         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22536         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22537
22538         speedup_cache=$(percent $average_cache $average_origin)
22539         speedup_ladvise=$(percent $average_ladvise $average_origin)
22540
22541         echo "Average uncached read: $average_origin"
22542         echo "Average speedup with OSS cached read: " \
22543                 "$average_cache = +$speedup_cache%"
22544         echo "Average speedup with ladvise willread: " \
22545                 "$average_ladvise = +$speedup_ladvise%"
22546
22547         local lowest_speedup=20
22548         if (( ${average_cache%.*} < $lowest_speedup )); then
22549                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22550                      " got $average_cache%. Skipping ladvise willread check."
22551                 return 0
22552         fi
22553
22554         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22555         # it is still good to run until then to exercise 'ladvise willread'
22556         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22557                 [ "$ost1_FSTYPE" = "zfs" ] &&
22558                 echo "osd-zfs does not support dontneed or drop_caches" &&
22559                 return 0
22560
22561         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22562         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22563                 error_not_in_vm "Speedup with willread is less than " \
22564                         "$lowest_speedup%, got $average_ladvise%"
22565 }
22566
22567 test_255a() {
22568         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22569                 skip "lustre < 2.8.54 does not support ladvise "
22570         remote_ost_nodsh && skip "remote OST with nodsh"
22571
22572         stack_trap "rm -f $DIR/$tfile"
22573         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22574
22575         ladvise_no_type willread $DIR/$tfile &&
22576                 skip "willread ladvise is not supported"
22577
22578         ladvise_no_ioctl $DIR/$tfile &&
22579                 skip "ladvise ioctl is not supported"
22580
22581         local size_mb=100
22582         local size=$((size_mb * 1048576))
22583         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22584                 error "dd to $DIR/$tfile failed"
22585
22586         lfs ladvise -a willread $DIR/$tfile ||
22587                 error "Ladvise failed with no range argument"
22588
22589         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22590                 error "Ladvise failed with no -l or -e argument"
22591
22592         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22593                 error "Ladvise failed with only -e argument"
22594
22595         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22596                 error "Ladvise failed with only -l argument"
22597
22598         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22599                 error "End offset should not be smaller than start offset"
22600
22601         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22602                 error "End offset should not be equal to start offset"
22603
22604         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22605                 error "Ladvise failed with overflowing -s argument"
22606
22607         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22608                 error "Ladvise failed with overflowing -e argument"
22609
22610         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22611                 error "Ladvise failed with overflowing -l argument"
22612
22613         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22614                 error "Ladvise succeeded with conflicting -l and -e arguments"
22615
22616         echo "Synchronous ladvise should wait"
22617         local delay=4
22618 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22619         do_nodes $(comma_list $(osts_nodes)) \
22620                 $LCTL set_param fail_val=$delay fail_loc=0x237
22621
22622         local start_ts=$SECONDS
22623         lfs ladvise -a willread $DIR/$tfile ||
22624                 error "Ladvise failed with no range argument"
22625         local end_ts=$SECONDS
22626         local inteval_ts=$((end_ts - start_ts))
22627
22628         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22629                 error "Synchronous advice didn't wait reply"
22630         fi
22631
22632         echo "Asynchronous ladvise shouldn't wait"
22633         local start_ts=$SECONDS
22634         lfs ladvise -a willread -b $DIR/$tfile ||
22635                 error "Ladvise failed with no range argument"
22636         local end_ts=$SECONDS
22637         local inteval_ts=$((end_ts - start_ts))
22638
22639         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22640                 error "Asynchronous advice blocked"
22641         fi
22642
22643         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22644         ladvise_willread_performance
22645 }
22646 run_test 255a "check 'lfs ladvise -a willread'"
22647
22648 facet_meminfo() {
22649         local facet=$1
22650         local info=$2
22651
22652         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22653 }
22654
22655 test_255b() {
22656         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22657                 skip "lustre < 2.8.54 does not support ladvise "
22658         remote_ost_nodsh && skip "remote OST with nodsh"
22659
22660         stack_trap "rm -f $DIR/$tfile"
22661         lfs setstripe -c 1 -i 0 $DIR/$tfile
22662
22663         ladvise_no_type dontneed $DIR/$tfile &&
22664                 skip "dontneed ladvise is not supported"
22665
22666         ladvise_no_ioctl $DIR/$tfile &&
22667                 skip "ladvise ioctl is not supported"
22668
22669         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22670                 [ "$ost1_FSTYPE" = "zfs" ] &&
22671                 skip "zfs-osd does not support 'ladvise dontneed'"
22672
22673         local size_mb=100
22674         local size=$((size_mb * 1048576))
22675         # In order to prevent disturbance of other processes, only check 3/4
22676         # of the memory usage
22677         local kibibytes=$((size_mb * 1024 * 3 / 4))
22678
22679         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22680                 error "dd to $DIR/$tfile failed"
22681
22682         #force write to complete before dropping OST cache & checking memory
22683         sync
22684
22685         local total=$(facet_meminfo ost1 MemTotal)
22686         echo "Total memory: $total KiB"
22687
22688         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22689         local before_read=$(facet_meminfo ost1 Cached)
22690         echo "Cache used before read: $before_read KiB"
22691
22692         lfs ladvise -a willread $DIR/$tfile ||
22693                 error "Ladvise willread failed"
22694         local after_read=$(facet_meminfo ost1 Cached)
22695         echo "Cache used after read: $after_read KiB"
22696
22697         lfs ladvise -a dontneed $DIR/$tfile ||
22698                 error "Ladvise dontneed again failed"
22699         local no_read=$(facet_meminfo ost1 Cached)
22700         echo "Cache used after dontneed ladvise: $no_read KiB"
22701
22702         if [ $total -lt $((before_read + kibibytes)) ]; then
22703                 echo "Memory is too small, abort checking"
22704                 return 0
22705         fi
22706
22707         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22708                 error "Ladvise willread should use more memory" \
22709                         "than $kibibytes KiB"
22710         fi
22711
22712         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22713                 error "Ladvise dontneed should release more memory" \
22714                         "than $kibibytes KiB"
22715         fi
22716 }
22717 run_test 255b "check 'lfs ladvise -a dontneed'"
22718
22719 test_255c() {
22720         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22721                 skip "lustre < 2.10.50 does not support lockahead"
22722
22723         local ost1_imp=$(get_osc_import_name client ost1)
22724         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22725                          cut -d'.' -f2)
22726         local count
22727         local new_count
22728         local difference
22729         local i
22730         local rc
22731
22732         test_mkdir -p $DIR/$tdir
22733         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22734
22735         #test 10 returns only success/failure
22736         i=10
22737         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22738         rc=$?
22739         if [ $rc -eq 255 ]; then
22740                 error "Ladvise test${i} failed, ${rc}"
22741         fi
22742
22743         #test 11 counts lock enqueue requests, all others count new locks
22744         i=11
22745         count=$(do_facet ost1 \
22746                 $LCTL get_param -n ost.OSS.ost.stats)
22747         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22748
22749         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22750         rc=$?
22751         if [ $rc -eq 255 ]; then
22752                 error "Ladvise test${i} failed, ${rc}"
22753         fi
22754
22755         new_count=$(do_facet ost1 \
22756                 $LCTL get_param -n ost.OSS.ost.stats)
22757         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22758                    awk '{ print $2 }')
22759
22760         difference="$((new_count - count))"
22761         if [ $difference -ne $rc ]; then
22762                 error "Ladvise test${i}, bad enqueue count, returned " \
22763                       "${rc}, actual ${difference}"
22764         fi
22765
22766         for i in $(seq 12 21); do
22767                 # If we do not do this, we run the risk of having too many
22768                 # locks and starting lock cancellation while we are checking
22769                 # lock counts.
22770                 cancel_lru_locks osc
22771
22772                 count=$($LCTL get_param -n \
22773                        ldlm.namespaces.$imp_name.lock_unused_count)
22774
22775                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22776                 rc=$?
22777                 if [ $rc -eq 255 ]; then
22778                         error "Ladvise test ${i} failed, ${rc}"
22779                 fi
22780
22781                 new_count=$($LCTL get_param -n \
22782                        ldlm.namespaces.$imp_name.lock_unused_count)
22783                 difference="$((new_count - count))"
22784
22785                 # Test 15 output is divided by 100 to map down to valid return
22786                 if [ $i -eq 15 ]; then
22787                         rc="$((rc * 100))"
22788                 fi
22789
22790                 if [ $difference -ne $rc ]; then
22791                         error "Ladvise test ${i}, bad lock count, returned " \
22792                               "${rc}, actual ${difference}"
22793                 fi
22794         done
22795
22796         #test 22 returns only success/failure
22797         i=22
22798         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22799         rc=$?
22800         if [ $rc -eq 255 ]; then
22801                 error "Ladvise test${i} failed, ${rc}"
22802         fi
22803 }
22804 run_test 255c "suite of ladvise lockahead tests"
22805
22806 test_256() {
22807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22808         remote_mds_nodsh && skip "remote MDS with nodsh"
22809         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22810         changelog_users $SINGLEMDS | grep "^cl" &&
22811                 skip "active changelog user"
22812
22813         local cl_user
22814         local cat_sl
22815         local mdt_dev
22816
22817         mdt_dev=$(facet_device $SINGLEMDS)
22818         echo $mdt_dev
22819
22820         changelog_register || error "changelog_register failed"
22821
22822         rm -rf $DIR/$tdir
22823         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22824
22825         changelog_clear 0 || error "changelog_clear failed"
22826
22827         # change something
22828         touch $DIR/$tdir/{1..10}
22829
22830         # stop the MDT
22831         stop $SINGLEMDS || error "Fail to stop MDT"
22832
22833         # remount the MDT
22834         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22835                 error "Fail to start MDT"
22836
22837         #after mount new plainllog is used
22838         touch $DIR/$tdir/{11..19}
22839         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22840         stack_trap "rm -f $tmpfile"
22841         cat_sl=$(do_facet $SINGLEMDS "sync; \
22842                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22843                  llog_reader $tmpfile | grep -c type=1064553b")
22844         do_facet $SINGLEMDS llog_reader $tmpfile
22845
22846         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22847
22848         changelog_clear 0 || error "changelog_clear failed"
22849
22850         cat_sl=$(do_facet $SINGLEMDS "sync; \
22851                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22852                  llog_reader $tmpfile | grep -c type=1064553b")
22853
22854         if (( cat_sl == 2 )); then
22855                 error "Empty plain llog was not deleted from changelog catalog"
22856         elif (( cat_sl != 1 )); then
22857                 error "Active plain llog shouldn't be deleted from catalog"
22858         fi
22859 }
22860 run_test 256 "Check llog delete for empty and not full state"
22861
22862 test_257() {
22863         remote_mds_nodsh && skip "remote MDS with nodsh"
22864         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22865                 skip "Need MDS version at least 2.8.55"
22866
22867         test_mkdir $DIR/$tdir
22868
22869         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22870                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22871         stat $DIR/$tdir
22872
22873 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22874         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22875         local facet=mds$((mdtidx + 1))
22876         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22877         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22878
22879         stop $facet || error "stop MDS failed"
22880         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22881                 error "start MDS fail"
22882         wait_recovery_complete $facet
22883 }
22884 run_test 257 "xattr locks are not lost"
22885
22886 # Verify we take the i_mutex when security requires it
22887 test_258a() {
22888 #define OBD_FAIL_IMUTEX_SEC 0x141c
22889         $LCTL set_param fail_loc=0x141c
22890         touch $DIR/$tfile
22891         chmod u+s $DIR/$tfile
22892         chmod a+rwx $DIR/$tfile
22893         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22894         RC=$?
22895         if [ $RC -ne 0 ]; then
22896                 error "error, failed to take i_mutex, rc=$?"
22897         fi
22898         rm -f $DIR/$tfile
22899 }
22900 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22901
22902 # Verify we do NOT take the i_mutex in the normal case
22903 test_258b() {
22904 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22905         $LCTL set_param fail_loc=0x141d
22906         touch $DIR/$tfile
22907         chmod a+rwx $DIR
22908         chmod a+rw $DIR/$tfile
22909         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22910         RC=$?
22911         if [ $RC -ne 0 ]; then
22912                 error "error, took i_mutex unnecessarily, rc=$?"
22913         fi
22914         rm -f $DIR/$tfile
22915
22916 }
22917 run_test 258b "verify i_mutex security behavior"
22918
22919 test_259() {
22920         local file=$DIR/$tfile
22921         local before
22922         local after
22923
22924         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22925
22926         stack_trap "rm -f $file" EXIT
22927
22928         wait_delete_completed
22929         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22930         echo "before: $before"
22931
22932         $LFS setstripe -i 0 -c 1 $file
22933         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22934         sync_all_data
22935         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22936         echo "after write: $after"
22937
22938 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22939         do_facet ost1 $LCTL set_param fail_loc=0x2301
22940         $TRUNCATE $file 0
22941         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22942         echo "after truncate: $after"
22943
22944         stop ost1
22945         do_facet ost1 $LCTL set_param fail_loc=0
22946         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22947         sleep 2
22948         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22949         echo "after restart: $after"
22950         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22951                 error "missing truncate?"
22952
22953         return 0
22954 }
22955 run_test 259 "crash at delayed truncate"
22956
22957 test_260() {
22958 #define OBD_FAIL_MDC_CLOSE               0x806
22959         $LCTL set_param fail_loc=0x80000806
22960         touch $DIR/$tfile
22961
22962 }
22963 run_test 260 "Check mdc_close fail"
22964
22965 ### Data-on-MDT sanity tests ###
22966 test_270a() {
22967         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22968                 skip "Need MDS version at least 2.10.55 for DoM"
22969
22970         # create DoM file
22971         local dom=$DIR/$tdir/dom_file
22972         local tmp=$DIR/$tdir/tmp_file
22973
22974         mkdir_on_mdt0 $DIR/$tdir
22975
22976         # basic checks for DoM component creation
22977         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22978                 error "Can set MDT layout to non-first entry"
22979
22980         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22981                 error "Can define multiple entries as MDT layout"
22982
22983         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22984
22985         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22986         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22987         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22988
22989         local mdtidx=$($LFS getstripe -m $dom)
22990         local mdtname=MDT$(printf %04x $mdtidx)
22991         local facet=mds$((mdtidx + 1))
22992         local space_check=1
22993
22994         # Skip free space checks with ZFS
22995         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22996
22997         # write
22998         sync
22999         local size_tmp=$((65536 * 3))
23000         local mdtfree1=$(do_facet $facet \
23001                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23002
23003         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23004         # check also direct IO along write
23005         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23006         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23007         sync
23008         cmp $tmp $dom || error "file data is different"
23009         [ $(stat -c%s $dom) == $size_tmp ] ||
23010                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23011         if [ $space_check == 1 ]; then
23012                 local mdtfree2=$(do_facet $facet \
23013                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23014
23015                 # increase in usage from by $size_tmp
23016                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23017                         error "MDT free space wrong after write: " \
23018                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23019         fi
23020
23021         # truncate
23022         local size_dom=10000
23023
23024         $TRUNCATE $dom $size_dom
23025         [ $(stat -c%s $dom) == $size_dom ] ||
23026                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23027         if [ $space_check == 1 ]; then
23028                 mdtfree1=$(do_facet $facet \
23029                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23030                 # decrease in usage from $size_tmp to new $size_dom
23031                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23032                   $(((size_tmp - size_dom) / 1024)) ] ||
23033                         error "MDT free space is wrong after truncate: " \
23034                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23035         fi
23036
23037         # append
23038         cat $tmp >> $dom
23039         sync
23040         size_dom=$((size_dom + size_tmp))
23041         [ $(stat -c%s $dom) == $size_dom ] ||
23042                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23043         if [ $space_check == 1 ]; then
23044                 mdtfree2=$(do_facet $facet \
23045                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23046                 # increase in usage by $size_tmp from previous
23047                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23048                         error "MDT free space is wrong after append: " \
23049                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23050         fi
23051
23052         # delete
23053         rm $dom
23054         if [ $space_check == 1 ]; then
23055                 mdtfree1=$(do_facet $facet \
23056                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23057                 # decrease in usage by $size_dom from previous
23058                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23059                         error "MDT free space is wrong after removal: " \
23060                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23061         fi
23062
23063         # combined striping
23064         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23065                 error "Can't create DoM + OST striping"
23066
23067         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23068         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23069         # check also direct IO along write
23070         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23071         sync
23072         cmp $tmp $dom || error "file data is different"
23073         [ $(stat -c%s $dom) == $size_tmp ] ||
23074                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23075         rm $dom $tmp
23076
23077         return 0
23078 }
23079 run_test 270a "DoM: basic functionality tests"
23080
23081 test_270b() {
23082         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23083                 skip "Need MDS version at least 2.10.55"
23084
23085         local dom=$DIR/$tdir/dom_file
23086         local max_size=1048576
23087
23088         mkdir -p $DIR/$tdir
23089         $LFS setstripe -E $max_size -L mdt $dom
23090
23091         # truncate over the limit
23092         $TRUNCATE $dom $(($max_size + 1)) &&
23093                 error "successful truncate over the maximum size"
23094         # write over the limit
23095         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23096                 error "successful write over the maximum size"
23097         # append over the limit
23098         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23099         echo "12345" >> $dom && error "successful append over the maximum size"
23100         rm $dom
23101
23102         return 0
23103 }
23104 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23105
23106 test_270c() {
23107         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23108                 skip "Need MDS version at least 2.10.55"
23109
23110         mkdir -p $DIR/$tdir
23111         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23112
23113         # check files inherit DoM EA
23114         touch $DIR/$tdir/first
23115         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23116                 error "bad pattern"
23117         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23118                 error "bad stripe count"
23119         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23120                 error "bad stripe size"
23121
23122         # check directory inherits DoM EA and uses it as default
23123         mkdir $DIR/$tdir/subdir
23124         touch $DIR/$tdir/subdir/second
23125         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23126                 error "bad pattern in sub-directory"
23127         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23128                 error "bad stripe count in sub-directory"
23129         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23130                 error "bad stripe size in sub-directory"
23131         return 0
23132 }
23133 run_test 270c "DoM: DoM EA inheritance tests"
23134
23135 test_270d() {
23136         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23137                 skip "Need MDS version at least 2.10.55"
23138
23139         mkdir -p $DIR/$tdir
23140         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23141
23142         # inherit default DoM striping
23143         mkdir $DIR/$tdir/subdir
23144         touch $DIR/$tdir/subdir/f1
23145
23146         # change default directory striping
23147         $LFS setstripe -c 1 $DIR/$tdir/subdir
23148         touch $DIR/$tdir/subdir/f2
23149         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23150                 error "wrong default striping in file 2"
23151         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23152                 error "bad pattern in file 2"
23153         return 0
23154 }
23155 run_test 270d "DoM: change striping from DoM to RAID0"
23156
23157 test_270e() {
23158         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23159                 skip "Need MDS version at least 2.10.55"
23160
23161         mkdir -p $DIR/$tdir/dom
23162         mkdir -p $DIR/$tdir/norm
23163         DOMFILES=20
23164         NORMFILES=10
23165         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23166         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23167
23168         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23169         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23170
23171         # find DoM files by layout
23172         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23173         [ $NUM -eq  $DOMFILES ] ||
23174                 error "lfs find -L: found $NUM, expected $DOMFILES"
23175         echo "Test 1: lfs find 20 DOM files by layout: OK"
23176
23177         # there should be 1 dir with default DOM striping
23178         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23179         [ $NUM -eq  1 ] ||
23180                 error "lfs find -L: found $NUM, expected 1 dir"
23181         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23182
23183         # find DoM files by stripe size
23184         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23185         [ $NUM -eq  $DOMFILES ] ||
23186                 error "lfs find -S: found $NUM, expected $DOMFILES"
23187         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23188
23189         # find files by stripe offset except DoM files
23190         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23191         [ $NUM -eq  $NORMFILES ] ||
23192                 error "lfs find -i: found $NUM, expected $NORMFILES"
23193         echo "Test 5: lfs find no DOM files by stripe index: OK"
23194         return 0
23195 }
23196 run_test 270e "DoM: lfs find with DoM files test"
23197
23198 test_270f() {
23199         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23200                 skip "Need MDS version at least 2.10.55"
23201
23202         local mdtname=${FSNAME}-MDT0000-mdtlov
23203         local dom=$DIR/$tdir/dom_file
23204         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23205                                                 lod.$mdtname.dom_stripesize)
23206         local dom_limit=131072
23207
23208         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23209         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23210                                                 lod.$mdtname.dom_stripesize)
23211         [ ${dom_limit} -eq ${dom_current} ] ||
23212                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23213
23214         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23215         $LFS setstripe -d $DIR/$tdir
23216         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23217                 error "Can't set directory default striping"
23218
23219         # exceed maximum stripe size
23220         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23221                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23222         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23223                 error "Able to create DoM component size more than LOD limit"
23224
23225         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23226         dom_current=$(do_facet mds1 $LCTL get_param -n \
23227                                                 lod.$mdtname.dom_stripesize)
23228         [ 0 -eq ${dom_current} ] ||
23229                 error "Can't set zero DoM stripe limit"
23230         rm $dom
23231
23232         # attempt to create DoM file on server with disabled DoM should
23233         # remove DoM entry from layout and be succeed
23234         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23235                 error "Can't create DoM file (DoM is disabled)"
23236         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23237                 error "File has DoM component while DoM is disabled"
23238         rm $dom
23239
23240         # attempt to create DoM file with only DoM stripe should return error
23241         $LFS setstripe -E $dom_limit -L mdt $dom &&
23242                 error "Able to create DoM-only file while DoM is disabled"
23243
23244         # too low values to be aligned with smallest stripe size 64K
23245         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23246         dom_current=$(do_facet mds1 $LCTL get_param -n \
23247                                                 lod.$mdtname.dom_stripesize)
23248         [ 30000 -eq ${dom_current} ] &&
23249                 error "Can set too small DoM stripe limit"
23250
23251         # 64K is a minimal stripe size in Lustre, expect limit of that size
23252         [ 65536 -eq ${dom_current} ] ||
23253                 error "Limit is not set to 64K but ${dom_current}"
23254
23255         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23256         dom_current=$(do_facet mds1 $LCTL get_param -n \
23257                                                 lod.$mdtname.dom_stripesize)
23258         echo $dom_current
23259         [ 2147483648 -eq ${dom_current} ] &&
23260                 error "Can set too large DoM stripe limit"
23261
23262         do_facet mds1 $LCTL set_param -n \
23263                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23264         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23265                 error "Can't create DoM component size after limit change"
23266         do_facet mds1 $LCTL set_param -n \
23267                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23268         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23269                 error "Can't create DoM file after limit decrease"
23270         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23271                 error "Can create big DoM component after limit decrease"
23272         touch ${dom}_def ||
23273                 error "Can't create file with old default layout"
23274
23275         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23276         return 0
23277 }
23278 run_test 270f "DoM: maximum DoM stripe size checks"
23279
23280 test_270g() {
23281         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23282                 skip "Need MDS version at least 2.13.52"
23283         local dom=$DIR/$tdir/$tfile
23284
23285         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23286         local lodname=${FSNAME}-MDT0000-mdtlov
23287
23288         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23289         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23290         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23291         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23292
23293         local dom_limit=1024
23294         local dom_threshold="50%"
23295
23296         $LFS setstripe -d $DIR/$tdir
23297         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23298                 error "Can't set directory default striping"
23299
23300         do_facet mds1 $LCTL set_param -n \
23301                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23302         # set 0 threshold and create DOM file to change tunable stripesize
23303         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23304         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23305                 error "Failed to create $dom file"
23306         # now tunable dom_cur_stripesize should reach maximum
23307         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23308                                         lod.${lodname}.dom_stripesize_cur_kb)
23309         [[ $dom_current == $dom_limit ]] ||
23310                 error "Current DOM stripesize is not maximum"
23311         rm $dom
23312
23313         # set threshold for further tests
23314         do_facet mds1 $LCTL set_param -n \
23315                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23316         echo "DOM threshold is $dom_threshold free space"
23317         local dom_def
23318         local dom_set
23319         # Spoof bfree to exceed threshold
23320         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23321         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23322         for spfree in 40 20 0 15 30 55; do
23323                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23324                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23325                         error "Failed to create $dom file"
23326                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23327                                         lod.${lodname}.dom_stripesize_cur_kb)
23328                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23329                 [[ $dom_def != $dom_current ]] ||
23330                         error "Default stripe size was not changed"
23331                 if (( spfree > 0 )) ; then
23332                         dom_set=$($LFS getstripe -S $dom)
23333                         (( dom_set == dom_def * 1024 )) ||
23334                                 error "DOM component size is still old"
23335                 else
23336                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23337                                 error "DoM component is set with no free space"
23338                 fi
23339                 rm $dom
23340                 dom_current=$dom_def
23341         done
23342 }
23343 run_test 270g "DoM: default DoM stripe size depends on free space"
23344
23345 test_270h() {
23346         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23347                 skip "Need MDS version at least 2.13.53"
23348
23349         local mdtname=${FSNAME}-MDT0000-mdtlov
23350         local dom=$DIR/$tdir/$tfile
23351         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23352
23353         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23354         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23355
23356         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23357         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23358                 error "can't create OST file"
23359         # mirrored file with DOM entry in the second mirror
23360         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23361                 error "can't create mirror with DoM component"
23362
23363         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23364
23365         # DOM component in the middle and has other enries in the same mirror,
23366         # should succeed but lost DoM component
23367         $LFS setstripe --copy=${dom}_1 $dom ||
23368                 error "Can't create file from OST|DOM mirror layout"
23369         # check new file has no DoM layout after all
23370         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23371                 error "File has DoM component while DoM is disabled"
23372 }
23373 run_test 270h "DoM: DoM stripe removal when disabled on server"
23374
23375 test_270i() {
23376         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23377                 skip "Need MDS version at least 2.14.54"
23378
23379         mkdir $DIR/$tdir
23380         # DoM with plain layout
23381         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23382                 error "default plain layout with DoM must fail"
23383         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23384                 error "setstripe plain file layout with DoM must fail"
23385         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23386                 error "default DoM layout with bad striping must fail"
23387         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23388                 error "setstripe to DoM layout with bad striping must fail"
23389         return 0
23390 }
23391 run_test 270i "DoM: setting invalid DoM striping should fail"
23392
23393 test_271a() {
23394         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23395                 skip "Need MDS version at least 2.10.55"
23396
23397         local dom=$DIR/$tdir/dom
23398
23399         mkdir -p $DIR/$tdir
23400
23401         $LFS setstripe -E 1024K -L mdt $dom
23402
23403         lctl set_param -n mdc.*.stats=clear
23404         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23405         cat $dom > /dev/null
23406         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23407         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23408         ls $dom
23409         rm -f $dom
23410 }
23411 run_test 271a "DoM: data is cached for read after write"
23412
23413 test_271b() {
23414         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23415                 skip "Need MDS version at least 2.10.55"
23416
23417         local dom=$DIR/$tdir/dom
23418
23419         mkdir -p $DIR/$tdir
23420
23421         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23422
23423         lctl set_param -n mdc.*.stats=clear
23424         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23425         cancel_lru_locks mdc
23426         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23427         # second stat to check size is cached on client
23428         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23429         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23430         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23431         rm -f $dom
23432 }
23433 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23434
23435 test_271ba() {
23436         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23437                 skip "Need MDS version at least 2.10.55"
23438
23439         local dom=$DIR/$tdir/dom
23440
23441         mkdir -p $DIR/$tdir
23442
23443         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23444
23445         lctl set_param -n mdc.*.stats=clear
23446         lctl set_param -n osc.*.stats=clear
23447         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23448         cancel_lru_locks mdc
23449         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23450         # second stat to check size is cached on client
23451         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23452         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23453         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23454         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23455         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23456         rm -f $dom
23457 }
23458 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23459
23460
23461 get_mdc_stats() {
23462         local mdtidx=$1
23463         local param=$2
23464         local mdt=MDT$(printf %04x $mdtidx)
23465
23466         if [ -z $param ]; then
23467                 lctl get_param -n mdc.*$mdt*.stats
23468         else
23469                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23470         fi
23471 }
23472
23473 test_271c() {
23474         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23475                 skip "Need MDS version at least 2.10.55"
23476
23477         local dom=$DIR/$tdir/dom
23478
23479         mkdir -p $DIR/$tdir
23480
23481         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23482
23483         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23484         local facet=mds$((mdtidx + 1))
23485
23486         cancel_lru_locks mdc
23487         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23488         createmany -o $dom 1000
23489         lctl set_param -n mdc.*.stats=clear
23490         smalliomany -w $dom 1000 200
23491         get_mdc_stats $mdtidx
23492         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23493         # Each file has 1 open, 1 IO enqueues, total 2000
23494         # but now we have also +1 getxattr for security.capability, total 3000
23495         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23496         unlinkmany $dom 1000
23497
23498         cancel_lru_locks mdc
23499         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23500         createmany -o $dom 1000
23501         lctl set_param -n mdc.*.stats=clear
23502         smalliomany -w $dom 1000 200
23503         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23504         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23505         # for OPEN and IO lock.
23506         [ $((enq - enq_2)) -ge 1000 ] ||
23507                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23508         unlinkmany $dom 1000
23509         return 0
23510 }
23511 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23512
23513 cleanup_271def_tests() {
23514         trap 0
23515         rm -f $1
23516 }
23517
23518 test_271d() {
23519         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23520                 skip "Need MDS version at least 2.10.57"
23521
23522         local dom=$DIR/$tdir/dom
23523         local tmp=$TMP/$tfile
23524         trap "cleanup_271def_tests $tmp" EXIT
23525
23526         mkdir -p $DIR/$tdir
23527
23528         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23529
23530         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23531
23532         cancel_lru_locks mdc
23533         dd if=/dev/urandom of=$tmp bs=1000 count=1
23534         dd if=$tmp of=$dom bs=1000 count=1
23535         cancel_lru_locks mdc
23536
23537         cat /etc/hosts >> $tmp
23538         lctl set_param -n mdc.*.stats=clear
23539
23540         # append data to the same file it should update local page
23541         echo "Append to the same page"
23542         cat /etc/hosts >> $dom
23543         local num=$(get_mdc_stats $mdtidx ost_read)
23544         local ra=$(get_mdc_stats $mdtidx req_active)
23545         local rw=$(get_mdc_stats $mdtidx req_waittime)
23546
23547         [ -z $num ] || error "$num READ RPC occured"
23548         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23549         echo "... DONE"
23550
23551         # compare content
23552         cmp $tmp $dom || error "file miscompare"
23553
23554         cancel_lru_locks mdc
23555         lctl set_param -n mdc.*.stats=clear
23556
23557         echo "Open and read file"
23558         cat $dom > /dev/null
23559         local num=$(get_mdc_stats $mdtidx ost_read)
23560         local ra=$(get_mdc_stats $mdtidx req_active)
23561         local rw=$(get_mdc_stats $mdtidx req_waittime)
23562
23563         [ -z $num ] || error "$num READ RPC occured"
23564         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23565         echo "... DONE"
23566
23567         # compare content
23568         cmp $tmp $dom || error "file miscompare"
23569
23570         return 0
23571 }
23572 run_test 271d "DoM: read on open (1K file in reply buffer)"
23573
23574 test_271f() {
23575         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23576                 skip "Need MDS version at least 2.10.57"
23577
23578         local dom=$DIR/$tdir/dom
23579         local tmp=$TMP/$tfile
23580         trap "cleanup_271def_tests $tmp" EXIT
23581
23582         mkdir -p $DIR/$tdir
23583
23584         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23585
23586         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23587
23588         cancel_lru_locks mdc
23589         dd if=/dev/urandom of=$tmp bs=265000 count=1
23590         dd if=$tmp of=$dom bs=265000 count=1
23591         cancel_lru_locks mdc
23592         cat /etc/hosts >> $tmp
23593         lctl set_param -n mdc.*.stats=clear
23594
23595         echo "Append to the same page"
23596         cat /etc/hosts >> $dom
23597         local num=$(get_mdc_stats $mdtidx ost_read)
23598         local ra=$(get_mdc_stats $mdtidx req_active)
23599         local rw=$(get_mdc_stats $mdtidx req_waittime)
23600
23601         [ -z $num ] || error "$num READ RPC occured"
23602         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23603         echo "... DONE"
23604
23605         # compare content
23606         cmp $tmp $dom || error "file miscompare"
23607
23608         cancel_lru_locks mdc
23609         lctl set_param -n mdc.*.stats=clear
23610
23611         echo "Open and read file"
23612         cat $dom > /dev/null
23613         local num=$(get_mdc_stats $mdtidx ost_read)
23614         local ra=$(get_mdc_stats $mdtidx req_active)
23615         local rw=$(get_mdc_stats $mdtidx req_waittime)
23616
23617         [ -z $num ] && num=0
23618         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23619         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23620         echo "... DONE"
23621
23622         # compare content
23623         cmp $tmp $dom || error "file miscompare"
23624
23625         return 0
23626 }
23627 run_test 271f "DoM: read on open (200K file and read tail)"
23628
23629 test_271g() {
23630         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23631                 skip "Skipping due to old client or server version"
23632
23633         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23634         # to get layout
23635         $CHECKSTAT -t file $DIR1/$tfile
23636
23637         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23638         MULTIOP_PID=$!
23639         sleep 1
23640         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23641         $LCTL set_param fail_loc=0x80000314
23642         rm $DIR1/$tfile || error "Unlink fails"
23643         RC=$?
23644         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23645         [ $RC -eq 0 ] || error "Failed write to stale object"
23646 }
23647 run_test 271g "Discard DoM data vs client flush race"
23648
23649 test_272a() {
23650         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23651                 skip "Need MDS version at least 2.11.50"
23652
23653         local dom=$DIR/$tdir/dom
23654         mkdir -p $DIR/$tdir
23655
23656         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23657         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23658                 error "failed to write data into $dom"
23659         local old_md5=$(md5sum $dom)
23660
23661         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23662                 error "failed to migrate to the same DoM component"
23663
23664         local new_md5=$(md5sum $dom)
23665
23666         [ "$old_md5" == "$new_md5" ] ||
23667                 error "md5sum differ: $old_md5, $new_md5"
23668
23669         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23670                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23671 }
23672 run_test 272a "DoM migration: new layout with the same DOM component"
23673
23674 test_272b() {
23675         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23676                 skip "Need MDS version at least 2.11.50"
23677
23678         local dom=$DIR/$tdir/dom
23679         mkdir -p $DIR/$tdir
23680         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23681
23682         local mdtidx=$($LFS getstripe -m $dom)
23683         local mdtname=MDT$(printf %04x $mdtidx)
23684         local facet=mds$((mdtidx + 1))
23685
23686         local mdtfree1=$(do_facet $facet \
23687                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23688         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23689                 error "failed to write data into $dom"
23690         local old_md5=$(md5sum $dom)
23691         cancel_lru_locks mdc
23692         local mdtfree1=$(do_facet $facet \
23693                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23694
23695         $LFS migrate -c2 $dom ||
23696                 error "failed to migrate to the new composite layout"
23697         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23698                 error "MDT stripe was not removed"
23699
23700         cancel_lru_locks mdc
23701         local new_md5=$(md5sum $dom)
23702         [ "$old_md5" == "$new_md5" ] ||
23703                 error "$old_md5 != $new_md5"
23704
23705         # Skip free space checks with ZFS
23706         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23707                 local mdtfree2=$(do_facet $facet \
23708                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23709                 [ $mdtfree2 -gt $mdtfree1 ] ||
23710                         error "MDT space is not freed after migration"
23711         fi
23712         return 0
23713 }
23714 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23715
23716 test_272c() {
23717         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23718                 skip "Need MDS version at least 2.11.50"
23719
23720         local dom=$DIR/$tdir/$tfile
23721         mkdir -p $DIR/$tdir
23722         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23723
23724         local mdtidx=$($LFS getstripe -m $dom)
23725         local mdtname=MDT$(printf %04x $mdtidx)
23726         local facet=mds$((mdtidx + 1))
23727
23728         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23729                 error "failed to write data into $dom"
23730         local old_md5=$(md5sum $dom)
23731         cancel_lru_locks mdc
23732         local mdtfree1=$(do_facet $facet \
23733                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23734
23735         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23736                 error "failed to migrate to the new composite layout"
23737         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23738                 error "MDT stripe was not removed"
23739
23740         cancel_lru_locks mdc
23741         local new_md5=$(md5sum $dom)
23742         [ "$old_md5" == "$new_md5" ] ||
23743                 error "$old_md5 != $new_md5"
23744
23745         # Skip free space checks with ZFS
23746         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23747                 local mdtfree2=$(do_facet $facet \
23748                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23749                 [ $mdtfree2 -gt $mdtfree1 ] ||
23750                         error "MDS space is not freed after migration"
23751         fi
23752         return 0
23753 }
23754 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23755
23756 test_272d() {
23757         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23758                 skip "Need MDS version at least 2.12.55"
23759
23760         local dom=$DIR/$tdir/$tfile
23761         mkdir -p $DIR/$tdir
23762         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23763
23764         local mdtidx=$($LFS getstripe -m $dom)
23765         local mdtname=MDT$(printf %04x $mdtidx)
23766         local facet=mds$((mdtidx + 1))
23767
23768         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23769                 error "failed to write data into $dom"
23770         local old_md5=$(md5sum $dom)
23771         cancel_lru_locks mdc
23772         local mdtfree1=$(do_facet $facet \
23773                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23774
23775         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23776                 error "failed mirroring to the new composite layout"
23777         $LFS mirror resync $dom ||
23778                 error "failed mirror resync"
23779         $LFS mirror split --mirror-id 1 -d $dom ||
23780                 error "failed mirror split"
23781
23782         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23783                 error "MDT stripe was not removed"
23784
23785         cancel_lru_locks mdc
23786         local new_md5=$(md5sum $dom)
23787         [ "$old_md5" == "$new_md5" ] ||
23788                 error "$old_md5 != $new_md5"
23789
23790         # Skip free space checks with ZFS
23791         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23792                 local mdtfree2=$(do_facet $facet \
23793                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23794                 [ $mdtfree2 -gt $mdtfree1 ] ||
23795                         error "MDS space is not freed after DOM mirror deletion"
23796         fi
23797         return 0
23798 }
23799 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23800
23801 test_272e() {
23802         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23803                 skip "Need MDS version at least 2.12.55"
23804
23805         local dom=$DIR/$tdir/$tfile
23806         mkdir -p $DIR/$tdir
23807         $LFS setstripe -c 2 $dom
23808
23809         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23810                 error "failed to write data into $dom"
23811         local old_md5=$(md5sum $dom)
23812         cancel_lru_locks
23813
23814         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23815                 error "failed mirroring to the DOM layout"
23816         $LFS mirror resync $dom ||
23817                 error "failed mirror resync"
23818         $LFS mirror split --mirror-id 1 -d $dom ||
23819                 error "failed mirror split"
23820
23821         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23822                 error "MDT stripe wasn't set"
23823
23824         cancel_lru_locks
23825         local new_md5=$(md5sum $dom)
23826         [ "$old_md5" == "$new_md5" ] ||
23827                 error "$old_md5 != $new_md5"
23828
23829         return 0
23830 }
23831 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23832
23833 test_272f() {
23834         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23835                 skip "Need MDS version at least 2.12.55"
23836
23837         local dom=$DIR/$tdir/$tfile
23838         mkdir -p $DIR/$tdir
23839         $LFS setstripe -c 2 $dom
23840
23841         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23842                 error "failed to write data into $dom"
23843         local old_md5=$(md5sum $dom)
23844         cancel_lru_locks
23845
23846         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23847                 error "failed migrating to the DOM file"
23848
23849         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23850                 error "MDT stripe wasn't set"
23851
23852         cancel_lru_locks
23853         local new_md5=$(md5sum $dom)
23854         [ "$old_md5" != "$new_md5" ] &&
23855                 error "$old_md5 != $new_md5"
23856
23857         return 0
23858 }
23859 run_test 272f "DoM migration: OST-striped file to DOM file"
23860
23861 test_273a() {
23862         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23863                 skip "Need MDS version at least 2.11.50"
23864
23865         # Layout swap cannot be done if either file has DOM component,
23866         # this will never be supported, migration should be used instead
23867
23868         local dom=$DIR/$tdir/$tfile
23869         mkdir -p $DIR/$tdir
23870
23871         $LFS setstripe -c2 ${dom}_plain
23872         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23873         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23874                 error "can swap layout with DoM component"
23875         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23876                 error "can swap layout with DoM component"
23877
23878         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23879         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23880                 error "can swap layout with DoM component"
23881         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23882                 error "can swap layout with DoM component"
23883         return 0
23884 }
23885 run_test 273a "DoM: layout swapping should fail with DOM"
23886
23887 test_273b() {
23888         mkdir -p $DIR/$tdir
23889         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23890
23891 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23892         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23893
23894         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23895 }
23896 run_test 273b "DoM: race writeback and object destroy"
23897
23898 test_273c() {
23899         mkdir -p $DIR/$tdir
23900         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
23901
23902         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
23903         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
23904
23905         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23906 }
23907 run_test 273c "race writeback and object destroy"
23908
23909 test_275() {
23910         remote_ost_nodsh && skip "remote OST with nodsh"
23911         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23912                 skip "Need OST version >= 2.10.57"
23913
23914         local file=$DIR/$tfile
23915         local oss
23916
23917         oss=$(comma_list $(osts_nodes))
23918
23919         dd if=/dev/urandom of=$file bs=1M count=2 ||
23920                 error "failed to create a file"
23921         cancel_lru_locks osc
23922
23923         #lock 1
23924         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23925                 error "failed to read a file"
23926
23927 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23928         $LCTL set_param fail_loc=0x8000031f
23929
23930         cancel_lru_locks osc &
23931         sleep 1
23932
23933 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23934         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23935         #IO takes another lock, but matches the PENDING one
23936         #and places it to the IO RPC
23937         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23938                 error "failed to read a file with PENDING lock"
23939 }
23940 run_test 275 "Read on a canceled duplicate lock"
23941
23942 test_276() {
23943         remote_ost_nodsh && skip "remote OST with nodsh"
23944         local pid
23945
23946         do_facet ost1 "(while true; do \
23947                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23948                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23949         pid=$!
23950
23951         for LOOP in $(seq 20); do
23952                 stop ost1
23953                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23954         done
23955         kill -9 $pid
23956         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23957                 rm $TMP/sanity_276_pid"
23958 }
23959 run_test 276 "Race between mount and obd_statfs"
23960
23961 test_277() {
23962         $LCTL set_param ldlm.namespaces.*.lru_size=0
23963         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23964         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23965                         grep ^used_mb | awk '{print $2}')
23966         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23967         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23968                 oflag=direct conv=notrunc
23969         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23970                         grep ^used_mb | awk '{print $2}')
23971         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23972 }
23973 run_test 277 "Direct IO shall drop page cache"
23974
23975 test_278() {
23976         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23977         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23978         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23979                 skip "needs the same host for mdt1 mdt2" && return
23980
23981         local pid1
23982         local pid2
23983
23984 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23985         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23986         stop mds2 &
23987         pid2=$!
23988
23989         stop mds1
23990
23991         echo "Starting MDTs"
23992         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23993         wait $pid2
23994 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23995 #will return NULL
23996         do_facet mds2 $LCTL set_param fail_loc=0
23997
23998         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23999         wait_recovery_complete mds2
24000 }
24001 run_test 278 "Race starting MDS between MDTs stop/start"
24002
24003 test_280() {
24004         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24005                 skip "Need MGS version at least 2.13.52"
24006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24007         combined_mgs_mds || skip "needs combined MGS/MDT"
24008
24009         umount_client $MOUNT
24010 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24011         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24012
24013         mount_client $MOUNT &
24014         sleep 1
24015         stop mgs || error "stop mgs failed"
24016         #for a race mgs would crash
24017         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24018         # make sure we unmount client before remounting
24019         wait
24020         umount_client $MOUNT
24021         mount_client $MOUNT || error "mount client failed"
24022 }
24023 run_test 280 "Race between MGS umount and client llog processing"
24024
24025 cleanup_test_300() {
24026         trap 0
24027         umask $SAVE_UMASK
24028 }
24029 test_striped_dir() {
24030         local mdt_index=$1
24031         local stripe_count
24032         local stripe_index
24033
24034         mkdir -p $DIR/$tdir
24035
24036         SAVE_UMASK=$(umask)
24037         trap cleanup_test_300 RETURN EXIT
24038
24039         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24040                                                 $DIR/$tdir/striped_dir ||
24041                 error "set striped dir error"
24042
24043         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24044         [ "$mode" = "755" ] || error "expect 755 got $mode"
24045
24046         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24047                 error "getdirstripe failed"
24048         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24049         if [ "$stripe_count" != "2" ]; then
24050                 error "1:stripe_count is $stripe_count, expect 2"
24051         fi
24052         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24053         if [ "$stripe_count" != "2" ]; then
24054                 error "2:stripe_count is $stripe_count, expect 2"
24055         fi
24056
24057         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24058         if [ "$stripe_index" != "$mdt_index" ]; then
24059                 error "stripe_index is $stripe_index, expect $mdt_index"
24060         fi
24061
24062         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24063                 error "nlink error after create striped dir"
24064
24065         mkdir $DIR/$tdir/striped_dir/a
24066         mkdir $DIR/$tdir/striped_dir/b
24067
24068         stat $DIR/$tdir/striped_dir/a ||
24069                 error "create dir under striped dir failed"
24070         stat $DIR/$tdir/striped_dir/b ||
24071                 error "create dir under striped dir failed"
24072
24073         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24074                 error "nlink error after mkdir"
24075
24076         rmdir $DIR/$tdir/striped_dir/a
24077         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24078                 error "nlink error after rmdir"
24079
24080         rmdir $DIR/$tdir/striped_dir/b
24081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24082                 error "nlink error after rmdir"
24083
24084         chattr +i $DIR/$tdir/striped_dir
24085         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24086                 error "immutable flags not working under striped dir!"
24087         chattr -i $DIR/$tdir/striped_dir
24088
24089         rmdir $DIR/$tdir/striped_dir ||
24090                 error "rmdir striped dir error"
24091
24092         cleanup_test_300
24093
24094         true
24095 }
24096
24097 test_300a() {
24098         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24099                 skip "skipped for lustre < 2.7.0"
24100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24102
24103         test_striped_dir 0 || error "failed on striped dir on MDT0"
24104         test_striped_dir 1 || error "failed on striped dir on MDT0"
24105 }
24106 run_test 300a "basic striped dir sanity test"
24107
24108 test_300b() {
24109         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24110                 skip "skipped for lustre < 2.7.0"
24111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24113
24114         local i
24115         local mtime1
24116         local mtime2
24117         local mtime3
24118
24119         test_mkdir $DIR/$tdir || error "mkdir fail"
24120         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24121                 error "set striped dir error"
24122         for i in {0..9}; do
24123                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24124                 sleep 1
24125                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24126                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24127                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24128                 sleep 1
24129                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24130                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24131                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24132         done
24133         true
24134 }
24135 run_test 300b "check ctime/mtime for striped dir"
24136
24137 test_300c() {
24138         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24139                 skip "skipped for lustre < 2.7.0"
24140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24142
24143         local file_count
24144
24145         mkdir_on_mdt0 $DIR/$tdir
24146         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24147                 error "set striped dir error"
24148
24149         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24150                 error "chown striped dir failed"
24151
24152         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24153                 error "create 5k files failed"
24154
24155         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24156
24157         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24158
24159         rm -rf $DIR/$tdir
24160 }
24161 run_test 300c "chown && check ls under striped directory"
24162
24163 test_300d() {
24164         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24165                 skip "skipped for lustre < 2.7.0"
24166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24168
24169         local stripe_count
24170         local file
24171
24172         mkdir -p $DIR/$tdir
24173         $LFS setstripe -c 2 $DIR/$tdir
24174
24175         #local striped directory
24176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24177                 error "set striped dir error"
24178         #look at the directories for debug purposes
24179         ls -l $DIR/$tdir
24180         $LFS getdirstripe $DIR/$tdir
24181         ls -l $DIR/$tdir/striped_dir
24182         $LFS getdirstripe $DIR/$tdir/striped_dir
24183         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24184                 error "create 10 files failed"
24185
24186         #remote striped directory
24187         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24188                 error "set striped dir error"
24189         #look at the directories for debug purposes
24190         ls -l $DIR/$tdir
24191         $LFS getdirstripe $DIR/$tdir
24192         ls -l $DIR/$tdir/remote_striped_dir
24193         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24194         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24195                 error "create 10 files failed"
24196
24197         for file in $(find $DIR/$tdir); do
24198                 stripe_count=$($LFS getstripe -c $file)
24199                 [ $stripe_count -eq 2 ] ||
24200                         error "wrong stripe $stripe_count for $file"
24201         done
24202
24203         rm -rf $DIR/$tdir
24204 }
24205 run_test 300d "check default stripe under striped directory"
24206
24207 test_300e() {
24208         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24209                 skip "Need MDS version at least 2.7.55"
24210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24212
24213         local stripe_count
24214         local file
24215
24216         mkdir -p $DIR/$tdir
24217
24218         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24219                 error "set striped dir error"
24220
24221         touch $DIR/$tdir/striped_dir/a
24222         touch $DIR/$tdir/striped_dir/b
24223         touch $DIR/$tdir/striped_dir/c
24224
24225         mkdir $DIR/$tdir/striped_dir/dir_a
24226         mkdir $DIR/$tdir/striped_dir/dir_b
24227         mkdir $DIR/$tdir/striped_dir/dir_c
24228
24229         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24230                 error "set striped adir under striped dir error"
24231
24232         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24233                 error "set striped bdir under striped dir error"
24234
24235         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24236                 error "set striped cdir under striped dir error"
24237
24238         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24239                 error "rename dir under striped dir fails"
24240
24241         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24242                 error "rename dir under different stripes fails"
24243
24244         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24245                 error "rename file under striped dir should succeed"
24246
24247         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24248                 error "rename dir under striped dir should succeed"
24249
24250         rm -rf $DIR/$tdir
24251 }
24252 run_test 300e "check rename under striped directory"
24253
24254 test_300f() {
24255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24258                 skip "Need MDS version at least 2.7.55"
24259
24260         local stripe_count
24261         local file
24262
24263         rm -rf $DIR/$tdir
24264         mkdir -p $DIR/$tdir
24265
24266         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24267                 error "set striped dir error"
24268
24269         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24270                 error "set striped dir error"
24271
24272         touch $DIR/$tdir/striped_dir/a
24273         mkdir $DIR/$tdir/striped_dir/dir_a
24274         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24275                 error "create striped dir under striped dir fails"
24276
24277         touch $DIR/$tdir/striped_dir1/b
24278         mkdir $DIR/$tdir/striped_dir1/dir_b
24279         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24280                 error "create striped dir under striped dir fails"
24281
24282         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24283                 error "rename dir under different striped dir should fail"
24284
24285         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24286                 error "rename striped dir under diff striped dir should fail"
24287
24288         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24289                 error "rename file under diff striped dirs fails"
24290
24291         rm -rf $DIR/$tdir
24292 }
24293 run_test 300f "check rename cross striped directory"
24294
24295 test_300_check_default_striped_dir()
24296 {
24297         local dirname=$1
24298         local default_count=$2
24299         local default_index=$3
24300         local stripe_count
24301         local stripe_index
24302         local dir_stripe_index
24303         local dir
24304
24305         echo "checking $dirname $default_count $default_index"
24306         $LFS setdirstripe -D -c $default_count -i $default_index \
24307                                 -H all_char $DIR/$tdir/$dirname ||
24308                 error "set default stripe on striped dir error"
24309         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24310         [ $stripe_count -eq $default_count ] ||
24311                 error "expect $default_count get $stripe_count for $dirname"
24312
24313         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24314         [ $stripe_index -eq $default_index ] ||
24315                 error "expect $default_index get $stripe_index for $dirname"
24316
24317         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24318                                                 error "create dirs failed"
24319
24320         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24321         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24322         for dir in $(find $DIR/$tdir/$dirname/*); do
24323                 stripe_count=$($LFS getdirstripe -c $dir)
24324                 (( $stripe_count == $default_count )) ||
24325                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24326                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24327                 error "stripe count $default_count != $stripe_count for $dir"
24328
24329                 stripe_index=$($LFS getdirstripe -i $dir)
24330                 [ $default_index -eq -1 ] ||
24331                         [ $stripe_index -eq $default_index ] ||
24332                         error "$stripe_index != $default_index for $dir"
24333
24334                 #check default stripe
24335                 stripe_count=$($LFS getdirstripe -D -c $dir)
24336                 [ $stripe_count -eq $default_count ] ||
24337                 error "default count $default_count != $stripe_count for $dir"
24338
24339                 stripe_index=$($LFS getdirstripe -D -i $dir)
24340                 [ $stripe_index -eq $default_index ] ||
24341                 error "default index $default_index != $stripe_index for $dir"
24342         done
24343         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24344 }
24345
24346 test_300g() {
24347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24348         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24349                 skip "Need MDS version at least 2.7.55"
24350
24351         local dir
24352         local stripe_count
24353         local stripe_index
24354
24355         mkdir_on_mdt0 $DIR/$tdir
24356         mkdir $DIR/$tdir/normal_dir
24357
24358         #Checking when client cache stripe index
24359         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24360         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24361                 error "create striped_dir failed"
24362
24363         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24364                 error "create dir0 fails"
24365         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24366         [ $stripe_index -eq 0 ] ||
24367                 error "dir0 expect index 0 got $stripe_index"
24368
24369         mkdir $DIR/$tdir/striped_dir/dir1 ||
24370                 error "create dir1 fails"
24371         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24372         [ $stripe_index -eq 1 ] ||
24373                 error "dir1 expect index 1 got $stripe_index"
24374
24375         #check default stripe count/stripe index
24376         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24377         test_300_check_default_striped_dir normal_dir 1 0
24378         test_300_check_default_striped_dir normal_dir -1 1
24379         test_300_check_default_striped_dir normal_dir 2 -1
24380
24381         #delete default stripe information
24382         echo "delete default stripeEA"
24383         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24384                 error "set default stripe on striped dir error"
24385
24386         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24387         for dir in $(find $DIR/$tdir/normal_dir/*); do
24388                 stripe_count=$($LFS getdirstripe -c $dir)
24389                 [ $stripe_count -eq 0 ] ||
24390                         error "expect 1 get $stripe_count for $dir"
24391         done
24392 }
24393 run_test 300g "check default striped directory for normal directory"
24394
24395 test_300h() {
24396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24398                 skip "Need MDS version at least 2.7.55"
24399
24400         local dir
24401         local stripe_count
24402
24403         mkdir $DIR/$tdir
24404         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24405                 error "set striped dir error"
24406
24407         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24408         test_300_check_default_striped_dir striped_dir 1 0
24409         test_300_check_default_striped_dir striped_dir -1 1
24410         test_300_check_default_striped_dir striped_dir 2 -1
24411
24412         #delete default stripe information
24413         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24414                 error "set default stripe on striped dir error"
24415
24416         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24417         for dir in $(find $DIR/$tdir/striped_dir/*); do
24418                 stripe_count=$($LFS getdirstripe -c $dir)
24419                 [ $stripe_count -eq 0 ] ||
24420                         error "expect 1 get $stripe_count for $dir"
24421         done
24422 }
24423 run_test 300h "check default striped directory for striped directory"
24424
24425 test_300i() {
24426         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24427         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24428         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24429                 skip "Need MDS version at least 2.7.55"
24430
24431         local stripe_count
24432         local file
24433
24434         mkdir $DIR/$tdir
24435
24436         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24437                 error "set striped dir error"
24438
24439         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24440                 error "create files under striped dir failed"
24441
24442         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24443                 error "set striped hashdir error"
24444
24445         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24446                 error "create dir0 under hash dir failed"
24447         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24448                 error "create dir1 under hash dir failed"
24449         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24450                 error "create dir2 under hash dir failed"
24451
24452         # unfortunately, we need to umount to clear dir layout cache for now
24453         # once we fully implement dir layout, we can drop this
24454         umount_client $MOUNT || error "umount failed"
24455         mount_client $MOUNT || error "mount failed"
24456
24457         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24458         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24459         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24460
24461         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24462                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24463                         error "create crush2 dir $tdir/hashdir/d3 failed"
24464                 $LFS find -H crush2 $DIR/$tdir/hashdir
24465                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24466                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24467
24468                 # mkdir with an invalid hash type (hash=fail_val) from client
24469                 # should be replaced on MDS with a valid (default) hash type
24470                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24471                 $LCTL set_param fail_loc=0x1901 fail_val=99
24472                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24473
24474                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24475                 local expect=$(do_facet mds1 \
24476                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24477                 [[ $hash == $expect ]] ||
24478                         error "d99 hash '$hash' != expected hash '$expect'"
24479         fi
24480
24481         #set the stripe to be unknown hash type on read
24482         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24483         $LCTL set_param fail_loc=0x1901 fail_val=99
24484         for ((i = 0; i < 10; i++)); do
24485                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24486                         error "stat f-$i failed"
24487                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24488         done
24489
24490         touch $DIR/$tdir/striped_dir/f0 &&
24491                 error "create under striped dir with unknown hash should fail"
24492
24493         $LCTL set_param fail_loc=0
24494
24495         umount_client $MOUNT || error "umount failed"
24496         mount_client $MOUNT || error "mount failed"
24497
24498         return 0
24499 }
24500 run_test 300i "client handle unknown hash type striped directory"
24501
24502 test_300j() {
24503         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24505         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24506                 skip "Need MDS version at least 2.7.55"
24507
24508         local stripe_count
24509         local file
24510
24511         mkdir $DIR/$tdir
24512
24513         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24514         $LCTL set_param fail_loc=0x1702
24515         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24516                 error "set striped dir error"
24517
24518         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24519                 error "create files under striped dir failed"
24520
24521         $LCTL set_param fail_loc=0
24522
24523         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24524
24525         return 0
24526 }
24527 run_test 300j "test large update record"
24528
24529 test_300k() {
24530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24531         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24532         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24533                 skip "Need MDS version at least 2.7.55"
24534
24535         # this test needs a huge transaction
24536         local kb
24537         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24538              osd*.$FSNAME-MDT0000.kbytestotal")
24539         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24540
24541         local stripe_count
24542         local file
24543
24544         mkdir $DIR/$tdir
24545
24546         #define OBD_FAIL_LARGE_STRIPE   0x1703
24547         $LCTL set_param fail_loc=0x1703
24548         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24549                 error "set striped dir error"
24550         $LCTL set_param fail_loc=0
24551
24552         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24553                 error "getstripeddir fails"
24554         rm -rf $DIR/$tdir/striped_dir ||
24555                 error "unlink striped dir fails"
24556
24557         return 0
24558 }
24559 run_test 300k "test large striped directory"
24560
24561 test_300l() {
24562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24564         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24565                 skip "Need MDS version at least 2.7.55"
24566
24567         local stripe_index
24568
24569         test_mkdir -p $DIR/$tdir/striped_dir
24570         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24571                         error "chown $RUNAS_ID failed"
24572         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24573                 error "set default striped dir failed"
24574
24575         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24576         $LCTL set_param fail_loc=0x80000158
24577         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24578
24579         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24580         [ $stripe_index -eq 1 ] ||
24581                 error "expect 1 get $stripe_index for $dir"
24582 }
24583 run_test 300l "non-root user to create dir under striped dir with stale layout"
24584
24585 test_300m() {
24586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24587         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24588         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24589                 skip "Need MDS version at least 2.7.55"
24590
24591         mkdir -p $DIR/$tdir/striped_dir
24592         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24593                 error "set default stripes dir error"
24594
24595         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24596
24597         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24598         [ $stripe_count -eq 0 ] ||
24599                         error "expect 0 get $stripe_count for a"
24600
24601         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24602                 error "set default stripes dir error"
24603
24604         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24605
24606         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24607         [ $stripe_count -eq 0 ] ||
24608                         error "expect 0 get $stripe_count for b"
24609
24610         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24611                 error "set default stripes dir error"
24612
24613         mkdir $DIR/$tdir/striped_dir/c &&
24614                 error "default stripe_index is invalid, mkdir c should fails"
24615
24616         rm -rf $DIR/$tdir || error "rmdir fails"
24617 }
24618 run_test 300m "setstriped directory on single MDT FS"
24619
24620 cleanup_300n() {
24621         local list=$(comma_list $(mdts_nodes))
24622
24623         trap 0
24624         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24625 }
24626
24627 test_300n() {
24628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24630         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24631                 skip "Need MDS version at least 2.7.55"
24632         remote_mds_nodsh && skip "remote MDS with nodsh"
24633
24634         local stripe_index
24635         local list=$(comma_list $(mdts_nodes))
24636
24637         trap cleanup_300n RETURN EXIT
24638         mkdir -p $DIR/$tdir
24639         chmod 777 $DIR/$tdir
24640         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24641                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24642                 error "create striped dir succeeds with gid=0"
24643
24644         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24645         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24646                 error "create striped dir fails with gid=-1"
24647
24648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24649         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24650                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24651                 error "set default striped dir succeeds with gid=0"
24652
24653
24654         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24655         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24656                 error "set default striped dir fails with gid=-1"
24657
24658
24659         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24660         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24661                                         error "create test_dir fails"
24662         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24663                                         error "create test_dir1 fails"
24664         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24665                                         error "create test_dir2 fails"
24666         cleanup_300n
24667 }
24668 run_test 300n "non-root user to create dir under striped dir with default EA"
24669
24670 test_300o() {
24671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24673         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24674                 skip "Need MDS version at least 2.7.55"
24675
24676         local numfree1
24677         local numfree2
24678
24679         mkdir -p $DIR/$tdir
24680
24681         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24682         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24683         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24684                 skip "not enough free inodes $numfree1 $numfree2"
24685         fi
24686
24687         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24688         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24689         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24690                 skip "not enough free space $numfree1 $numfree2"
24691         fi
24692
24693         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24694                 error "setdirstripe fails"
24695
24696         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24697                 error "create dirs fails"
24698
24699         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24700         ls $DIR/$tdir/striped_dir > /dev/null ||
24701                 error "ls striped dir fails"
24702         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24703                 error "unlink big striped dir fails"
24704 }
24705 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24706
24707 test_300p() {
24708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24710         remote_mds_nodsh && skip "remote MDS with nodsh"
24711
24712         mkdir_on_mdt0 $DIR/$tdir
24713
24714         #define OBD_FAIL_OUT_ENOSPC     0x1704
24715         do_facet mds2 lctl set_param fail_loc=0x80001704
24716         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24717                  && error "create striped directory should fail"
24718
24719         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24720
24721         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24722         true
24723 }
24724 run_test 300p "create striped directory without space"
24725
24726 test_300q() {
24727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24728         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24729
24730         local fd=$(free_fd)
24731         local cmd="exec $fd<$tdir"
24732         cd $DIR
24733         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24734         eval $cmd
24735         cmd="exec $fd<&-"
24736         trap "eval $cmd" EXIT
24737         cd $tdir || error "cd $tdir fails"
24738         rmdir  ../$tdir || error "rmdir $tdir fails"
24739         mkdir local_dir && error "create dir succeeds"
24740         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24741         eval $cmd
24742         return 0
24743 }
24744 run_test 300q "create remote directory under orphan directory"
24745
24746 test_300r() {
24747         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24748                 skip "Need MDS version at least 2.7.55" && return
24749         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24750
24751         mkdir $DIR/$tdir
24752
24753         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24754                 error "set striped dir error"
24755
24756         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24757                 error "getstripeddir fails"
24758
24759         local stripe_count
24760         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24761                       awk '/lmv_stripe_count:/ { print $2 }')
24762
24763         [ $MDSCOUNT -ne $stripe_count ] &&
24764                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24765
24766         rm -rf $DIR/$tdir/striped_dir ||
24767                 error "unlink striped dir fails"
24768 }
24769 run_test 300r "test -1 striped directory"
24770
24771 test_300s_helper() {
24772         local count=$1
24773
24774         local stripe_dir=$DIR/$tdir/striped_dir.$count
24775
24776         $LFS mkdir -c $count $stripe_dir ||
24777                 error "lfs mkdir -c error"
24778
24779         $LFS getdirstripe $stripe_dir ||
24780                 error "lfs getdirstripe fails"
24781
24782         local stripe_count
24783         stripe_count=$($LFS getdirstripe $stripe_dir |
24784                       awk '/lmv_stripe_count:/ { print $2 }')
24785
24786         [ $count -ne $stripe_count ] &&
24787                 error_noexit "bad stripe count $stripe_count expected $count"
24788
24789         local dupe_stripes
24790         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24791                 awk '/0x/ {count[$1] += 1}; END {
24792                         for (idx in count) {
24793                                 if (count[idx]>1) {
24794                                         print "index " idx " count " count[idx]
24795                                 }
24796                         }
24797                 }')
24798
24799         if [[ -n "$dupe_stripes" ]] ; then
24800                 lfs getdirstripe $stripe_dir
24801                 error_noexit "Dupe MDT above: $dupe_stripes "
24802         fi
24803
24804         rm -rf $stripe_dir ||
24805                 error_noexit "unlink $stripe_dir fails"
24806 }
24807
24808 test_300s() {
24809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24810                 skip "Need MDS version at least 2.7.55" && return
24811         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24812
24813         mkdir $DIR/$tdir
24814         for count in $(seq 2 $MDSCOUNT); do
24815                 test_300s_helper $count
24816         done
24817 }
24818 run_test 300s "test lfs mkdir -c without -i"
24819
24820 test_300t() {
24821         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24822                 skip "need MDS 2.14.55 or later"
24823         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24824
24825         local testdir="$DIR/$tdir/striped_dir"
24826         local dir1=$testdir/dir1
24827         local dir2=$testdir/dir2
24828
24829         mkdir -p $testdir
24830
24831         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24832                 error "failed to set default stripe count for $testdir"
24833
24834         mkdir $dir1
24835         local stripe_count=$($LFS getdirstripe -c $dir1)
24836
24837         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24838
24839         local max_count=$((MDSCOUNT - 1))
24840         local mdts=$(comma_list $(mdts_nodes))
24841
24842         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24843         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24844
24845         mkdir $dir2
24846         stripe_count=$($LFS getdirstripe -c $dir2)
24847
24848         (( $stripe_count == $max_count )) || error "wrong stripe count"
24849 }
24850 run_test 300t "test max_mdt_stripecount"
24851
24852 prepare_remote_file() {
24853         mkdir $DIR/$tdir/src_dir ||
24854                 error "create remote source failed"
24855
24856         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24857                  error "cp to remote source failed"
24858         touch $DIR/$tdir/src_dir/a
24859
24860         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24861                 error "create remote target dir failed"
24862
24863         touch $DIR/$tdir/tgt_dir/b
24864
24865         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24866                 error "rename dir cross MDT failed!"
24867
24868         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24869                 error "src_child still exists after rename"
24870
24871         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24872                 error "missing file(a) after rename"
24873
24874         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24875                 error "diff after rename"
24876 }
24877
24878 test_310a() {
24879         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24881
24882         local remote_file=$DIR/$tdir/tgt_dir/b
24883
24884         mkdir -p $DIR/$tdir
24885
24886         prepare_remote_file || error "prepare remote file failed"
24887
24888         #open-unlink file
24889         $OPENUNLINK $remote_file $remote_file ||
24890                 error "openunlink $remote_file failed"
24891         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24892 }
24893 run_test 310a "open unlink remote file"
24894
24895 test_310b() {
24896         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24898
24899         local remote_file=$DIR/$tdir/tgt_dir/b
24900
24901         mkdir -p $DIR/$tdir
24902
24903         prepare_remote_file || error "prepare remote file failed"
24904
24905         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24906         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24907         $CHECKSTAT -t file $remote_file || error "check file failed"
24908 }
24909 run_test 310b "unlink remote file with multiple links while open"
24910
24911 test_310c() {
24912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24913         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24914
24915         local remote_file=$DIR/$tdir/tgt_dir/b
24916
24917         mkdir -p $DIR/$tdir
24918
24919         prepare_remote_file || error "prepare remote file failed"
24920
24921         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24922         multiop_bg_pause $remote_file O_uc ||
24923                         error "mulitop failed for remote file"
24924         MULTIPID=$!
24925         $MULTIOP $DIR/$tfile Ouc
24926         kill -USR1 $MULTIPID
24927         wait $MULTIPID
24928 }
24929 run_test 310c "open-unlink remote file with multiple links"
24930
24931 #LU-4825
24932 test_311() {
24933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24934         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24935         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24936                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24937         remote_mds_nodsh && skip "remote MDS with nodsh"
24938
24939         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24940         local mdts=$(comma_list $(mdts_nodes))
24941
24942         mkdir -p $DIR/$tdir
24943         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24944         createmany -o $DIR/$tdir/$tfile. 1000
24945
24946         # statfs data is not real time, let's just calculate it
24947         old_iused=$((old_iused + 1000))
24948
24949         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24950                         osp.*OST0000*MDT0000.create_count")
24951         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24952                                 osp.*OST0000*MDT0000.max_create_count")
24953         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24954
24955         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24956         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24957         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24958
24959         unlinkmany $DIR/$tdir/$tfile. 1000
24960
24961         do_nodes $mdts "$LCTL set_param -n \
24962                         osp.*OST0000*.max_create_count=$max_count"
24963         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24964                 do_nodes $mdts "$LCTL set_param -n \
24965                                 osp.*OST0000*.create_count=$count"
24966         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24967                         grep "=0" && error "create_count is zero"
24968
24969         local new_iused
24970         for i in $(seq 120); do
24971                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24972                 # system may be too busy to destroy all objs in time, use
24973                 # a somewhat small value to not fail autotest
24974                 [ $((old_iused - new_iused)) -gt 400 ] && break
24975                 sleep 1
24976         done
24977
24978         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24979         [ $((old_iused - new_iused)) -gt 400 ] ||
24980                 error "objs not destroyed after unlink"
24981 }
24982 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24983
24984 zfs_get_objid()
24985 {
24986         local ost=$1
24987         local tf=$2
24988         local fid=($($LFS getstripe $tf | grep 0x))
24989         local seq=${fid[3]#0x}
24990         local objid=${fid[1]}
24991
24992         local vdevdir=$(dirname $(facet_vdevice $ost))
24993         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24994         local zfs_zapid=$(do_facet $ost $cmd |
24995                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24996                           awk '/Object/{getline; print $1}')
24997         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24998                           awk "/$objid = /"'{printf $3}')
24999
25000         echo $zfs_objid
25001 }
25002
25003 zfs_object_blksz() {
25004         local ost=$1
25005         local objid=$2
25006
25007         local vdevdir=$(dirname $(facet_vdevice $ost))
25008         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25009         local blksz=$(do_facet $ost $cmd $objid |
25010                       awk '/dblk/{getline; printf $4}')
25011
25012         case "${blksz: -1}" in
25013                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25014                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25015                 *) ;;
25016         esac
25017
25018         echo $blksz
25019 }
25020
25021 test_312() { # LU-4856
25022         remote_ost_nodsh && skip "remote OST with nodsh"
25023         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25024
25025         local max_blksz=$(do_facet ost1 \
25026                           $ZFS get -p recordsize $(facet_device ost1) |
25027                           awk '!/VALUE/{print $3}')
25028         local tf=$DIR/$tfile
25029
25030         $LFS setstripe -c1 $tf
25031         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25032
25033         # Get ZFS object id
25034         local zfs_objid=$(zfs_get_objid $facet $tf)
25035         # block size change by sequential overwrite
25036         local bs
25037
25038         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25039                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25040
25041                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25042                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25043         done
25044         rm -f $tf
25045
25046         $LFS setstripe -c1 $tf
25047         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25048
25049         # block size change by sequential append write
25050         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25051         zfs_objid=$(zfs_get_objid $facet $tf)
25052         local count
25053
25054         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25055                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25056                         oflag=sync conv=notrunc
25057
25058                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25059                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25060                         error "blksz error, actual $blksz, " \
25061                                 "expected: 2 * $count * $PAGE_SIZE"
25062         done
25063         rm -f $tf
25064
25065         # random write
25066         $LFS setstripe -c1 $tf
25067         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25068         zfs_objid=$(zfs_get_objid $facet $tf)
25069
25070         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25071         blksz=$(zfs_object_blksz $facet $zfs_objid)
25072         (( blksz == PAGE_SIZE )) ||
25073                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25074
25075         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25076         blksz=$(zfs_object_blksz $facet $zfs_objid)
25077         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25078
25079         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25080         blksz=$(zfs_object_blksz $facet $zfs_objid)
25081         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25082 }
25083 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25084
25085 test_313() {
25086         remote_ost_nodsh && skip "remote OST with nodsh"
25087
25088         local file=$DIR/$tfile
25089
25090         rm -f $file
25091         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25092
25093         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25094         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25095         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25096                 error "write should failed"
25097         do_facet ost1 "$LCTL set_param fail_loc=0"
25098         rm -f $file
25099 }
25100 run_test 313 "io should fail after last_rcvd update fail"
25101
25102 test_314() {
25103         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25104
25105         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25106         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25107         rm -f $DIR/$tfile
25108         wait_delete_completed
25109         do_facet ost1 "$LCTL set_param fail_loc=0"
25110 }
25111 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25112
25113 test_315() { # LU-618
25114         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25115
25116         local file=$DIR/$tfile
25117         rm -f $file
25118
25119         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25120                 error "multiop file write failed"
25121         $MULTIOP $file oO_RDONLY:r4063232_c &
25122         PID=$!
25123
25124         sleep 2
25125
25126         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25127         kill -USR1 $PID
25128
25129         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25130         rm -f $file
25131 }
25132 run_test 315 "read should be accounted"
25133
25134 test_316() {
25135         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25136         large_xattr_enabled || skip "ea_inode feature disabled"
25137
25138         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25139         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25140         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25141         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25142
25143         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25144 }
25145 run_test 316 "lfs migrate of file with large_xattr enabled"
25146
25147 test_317() {
25148         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25149                 skip "Need MDS version at least 2.11.53"
25150         if [ "$ost1_FSTYPE" == "zfs" ]; then
25151                 skip "LU-10370: no implementation for ZFS"
25152         fi
25153
25154         local trunc_sz
25155         local grant_blk_size
25156
25157         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25158                         awk '/grant_block_size:/ { print $2; exit; }')
25159         #
25160         # Create File of size 5M. Truncate it to below size's and verify
25161         # blocks count.
25162         #
25163         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25164                 error "Create file $DIR/$tfile failed"
25165         stack_trap "rm -f $DIR/$tfile" EXIT
25166
25167         for trunc_sz in 2097152 4097 4000 509 0; do
25168                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25169                         error "truncate $tfile to $trunc_sz failed"
25170                 local sz=$(stat --format=%s $DIR/$tfile)
25171                 local blk=$(stat --format=%b $DIR/$tfile)
25172                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25173                                      grant_blk_size) * 8))
25174
25175                 if [[ $blk -ne $trunc_blk ]]; then
25176                         $(which stat) $DIR/$tfile
25177                         error "Expected Block $trunc_blk got $blk for $tfile"
25178                 fi
25179
25180                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25181                         error "Expected Size $trunc_sz got $sz for $tfile"
25182         done
25183
25184         #
25185         # sparse file test
25186         # Create file with a hole and write actual 65536 bytes which aligned
25187         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25188         #
25189         local bs=65536
25190         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25191                 error "Create file : $DIR/$tfile"
25192
25193         #
25194         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25195         # blocks. The block count must drop to 8.
25196         #
25197         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25198                 ((bs - grant_blk_size) + 1)))
25199         $TRUNCATE $DIR/$tfile $trunc_sz ||
25200                 error "truncate $tfile to $trunc_sz failed"
25201
25202         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25203         sz=$(stat --format=%s $DIR/$tfile)
25204         blk=$(stat --format=%b $DIR/$tfile)
25205
25206         if [[ $blk -ne $trunc_bsz ]]; then
25207                 $(which stat) $DIR/$tfile
25208                 error "Expected Block $trunc_bsz got $blk for $tfile"
25209         fi
25210
25211         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25212                 error "Expected Size $trunc_sz got $sz for $tfile"
25213 }
25214 run_test 317 "Verify blocks get correctly update after truncate"
25215
25216 test_318() {
25217         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25218         local old_max_active=$($LCTL get_param -n \
25219                             ${llite_name}.max_read_ahead_async_active \
25220                             2>/dev/null)
25221
25222         $LCTL set_param llite.*.max_read_ahead_async_active=256
25223         local max_active=$($LCTL get_param -n \
25224                            ${llite_name}.max_read_ahead_async_active \
25225                            2>/dev/null)
25226         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25227
25228         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25229                 error "set max_read_ahead_async_active should succeed"
25230
25231         $LCTL set_param llite.*.max_read_ahead_async_active=512
25232         max_active=$($LCTL get_param -n \
25233                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25234         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25235
25236         # restore @max_active
25237         [ $old_max_active -ne 0 ] && $LCTL set_param \
25238                 llite.*.max_read_ahead_async_active=$old_max_active
25239
25240         local old_threshold=$($LCTL get_param -n \
25241                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25242         local max_per_file_mb=$($LCTL get_param -n \
25243                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25244
25245         local invalid=$(($max_per_file_mb + 1))
25246         $LCTL set_param \
25247                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25248                         && error "set $invalid should fail"
25249
25250         local valid=$(($invalid - 1))
25251         $LCTL set_param \
25252                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25253                         error "set $valid should succeed"
25254         local threshold=$($LCTL get_param -n \
25255                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25256         [ $threshold -eq $valid ] || error \
25257                 "expect threshold $valid got $threshold"
25258         $LCTL set_param \
25259                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25260 }
25261 run_test 318 "Verify async readahead tunables"
25262
25263 test_319() {
25264         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25265
25266         local before=$(date +%s)
25267         local evict
25268         local mdir=$DIR/$tdir
25269         local file=$mdir/xxx
25270
25271         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25272         touch $file
25273
25274 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25275         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25276         $LFS migrate -m1 $mdir &
25277
25278         sleep 1
25279         dd if=$file of=/dev/null
25280         wait
25281         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25282           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25283
25284         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25285 }
25286 run_test 319 "lost lease lock on migrate error"
25287
25288 test_398a() { # LU-4198
25289         local ost1_imp=$(get_osc_import_name client ost1)
25290         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25291                          cut -d'.' -f2)
25292
25293         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25294         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25295
25296         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25297         # request a new lock on client
25298         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25299
25300         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25301         #local lock_count=$($LCTL get_param -n \
25302         #                  ldlm.namespaces.$imp_name.lru_size)
25303         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25304
25305         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25306
25307         # no lock cached, should use lockless DIO and not enqueue new lock
25308         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25309                 conv=notrunc ||
25310                 error "dio write failed"
25311         lock_count=$($LCTL get_param -n \
25312                      ldlm.namespaces.$imp_name.lru_size)
25313         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25314
25315         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25316
25317         # no lock cached, should use locked DIO append
25318         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25319                 conv=notrunc || error "DIO append failed"
25320         lock_count=$($LCTL get_param -n \
25321                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25322         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25323 }
25324 run_test 398a "direct IO should cancel lock otherwise lockless"
25325
25326 test_398b() { # LU-4198
25327         local before=$(date +%s)
25328         local njobs=4
25329         local size=48
25330
25331         which fio || skip_env "no fio installed"
25332         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25334
25335         # Single page, multiple pages, stripe size, 4*stripe size
25336         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25337                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25338                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25339                         --numjobs=$njobs --fallocate=none \
25340                         --iodepth=16 --allow_file_create=0 \
25341                         --size=$((size/njobs))M \
25342                         --filename=$DIR/$tfile &
25343                 bg_pid=$!
25344
25345                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25346                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25347                         --numjobs=$njobs --fallocate=none \
25348                         --iodepth=16 --allow_file_create=0 \
25349                         --size=$((size/njobs))M \
25350                         --filename=$DIR/$tfile || true
25351                 wait $bg_pid
25352         done
25353
25354         evict=$(do_facet client $LCTL get_param \
25355                 osc.$FSNAME-OST*-osc-*/state |
25356             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25357
25358         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25359                 (do_facet client $LCTL get_param \
25360                         osc.$FSNAME-OST*-osc-*/state;
25361                     error "eviction happened: $evict before:$before")
25362
25363         rm -f $DIR/$tfile
25364 }
25365 run_test 398b "DIO and buffer IO race"
25366
25367 test_398c() { # LU-4198
25368         local ost1_imp=$(get_osc_import_name client ost1)
25369         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25370                          cut -d'.' -f2)
25371
25372         which fio || skip_env "no fio installed"
25373
25374         saved_debug=$($LCTL get_param -n debug)
25375         $LCTL set_param debug=0
25376
25377         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25378         ((size /= 1024)) # by megabytes
25379         ((size /= 2)) # write half of the OST at most
25380         [ $size -gt 40 ] && size=40 #reduce test time anyway
25381
25382         $LFS setstripe -c 1 $DIR/$tfile
25383
25384         # it seems like ldiskfs reserves more space than necessary if the
25385         # writing blocks are not mapped, so it extends the file firstly
25386         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25387         cancel_lru_locks osc
25388
25389         # clear and verify rpc_stats later
25390         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25391
25392         local njobs=4
25393         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25394         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25395                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25396                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25397                 --filename=$DIR/$tfile
25398         [ $? -eq 0 ] || error "fio write error"
25399
25400         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25401                 error "Locks were requested while doing AIO"
25402
25403         # get the percentage of 1-page I/O
25404         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25405                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25406                 awk '{print $7}')
25407         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25408
25409         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25410         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25411                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25412                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25413                 --filename=$DIR/$tfile
25414         [ $? -eq 0 ] || error "fio mixed read write error"
25415
25416         echo "AIO with large block size ${size}M"
25417         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25418                 --numjobs=1 --fallocate=none --ioengine=libaio \
25419                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25420                 --filename=$DIR/$tfile
25421         [ $? -eq 0 ] || error "fio large block size failed"
25422
25423         rm -f $DIR/$tfile
25424         $LCTL set_param debug="$saved_debug"
25425 }
25426 run_test 398c "run fio to test AIO"
25427
25428 test_398d() { #  LU-13846
25429         which aiocp || skip_env "no aiocp installed"
25430         local aio_file=$DIR/$tfile.aio
25431
25432         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25433
25434         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25435         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25436         stack_trap "rm -f $DIR/$tfile $aio_file"
25437
25438         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25439
25440         # make sure we don't crash and fail properly
25441         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25442                 error "aio not aligned with PAGE SIZE should fail"
25443
25444         rm -f $DIR/$tfile $aio_file
25445 }
25446 run_test 398d "run aiocp to verify block size > stripe size"
25447
25448 test_398e() {
25449         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25450         touch $DIR/$tfile.new
25451         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25452 }
25453 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25454
25455 test_398f() { #  LU-14687
25456         which aiocp || skip_env "no aiocp installed"
25457         local aio_file=$DIR/$tfile.aio
25458
25459         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25460
25461         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25462         stack_trap "rm -f $DIR/$tfile $aio_file"
25463
25464         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25465         $LCTL set_param fail_loc=0x1418
25466         # make sure we don't crash and fail properly
25467         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25468                 error "aio with page allocation failure succeeded"
25469         $LCTL set_param fail_loc=0
25470         diff $DIR/$tfile $aio_file
25471         [[ $? != 0 ]] || error "no diff after failed aiocp"
25472 }
25473 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25474
25475 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25476 # stripe and i/o size must be > stripe size
25477 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25478 # single RPC in flight.  This test shows async DIO submission is working by
25479 # showing multiple RPCs in flight.
25480 test_398g() { #  LU-13798
25481         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25482
25483         # We need to do some i/o first to acquire enough grant to put our RPCs
25484         # in flight; otherwise a new connection may not have enough grant
25485         # available
25486         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25487                 error "parallel dio failed"
25488         stack_trap "rm -f $DIR/$tfile"
25489
25490         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25491         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25492         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25493         stack_trap "$LCTL set_param -n $pages_per_rpc"
25494
25495         # Recreate file so it's empty
25496         rm -f $DIR/$tfile
25497         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25498         #Pause rpc completion to guarantee we see multiple rpcs in flight
25499         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25500         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25501         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25502
25503         # Clear rpc stats
25504         $LCTL set_param osc.*.rpc_stats=c
25505
25506         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25507                 error "parallel dio failed"
25508         stack_trap "rm -f $DIR/$tfile"
25509
25510         $LCTL get_param osc.*-OST0000-*.rpc_stats
25511         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25512                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25513                 grep "8:" | awk '{print $8}')
25514         # We look at the "8 rpcs in flight" field, and verify A) it is present
25515         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25516         # as expected for an 8M DIO to a file with 1M stripes.
25517         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25518
25519         # Verify turning off parallel dio works as expected
25520         # Clear rpc stats
25521         $LCTL set_param osc.*.rpc_stats=c
25522         $LCTL set_param llite.*.parallel_dio=0
25523         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25524
25525         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25526                 error "dio with parallel dio disabled failed"
25527
25528         # Ideally, we would see only one RPC in flight here, but there is an
25529         # unavoidable race between i/o completion and RPC in flight counting,
25530         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25531         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25532         # So instead we just verify it's always < 8.
25533         $LCTL get_param osc.*-OST0000-*.rpc_stats
25534         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25535                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25536                 grep '^$' -B1 | grep . | awk '{print $1}')
25537         [ $ret != "8:" ] ||
25538                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25539 }
25540 run_test 398g "verify parallel dio async RPC submission"
25541
25542 test_398h() { #  LU-13798
25543         local dio_file=$DIR/$tfile.dio
25544
25545         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25546
25547         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25548         stack_trap "rm -f $DIR/$tfile $dio_file"
25549
25550         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25551                 error "parallel dio failed"
25552         diff $DIR/$tfile $dio_file
25553         [[ $? == 0 ]] || error "file diff after aiocp"
25554 }
25555 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25556
25557 test_398i() { #  LU-13798
25558         local dio_file=$DIR/$tfile.dio
25559
25560         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25561
25562         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25563         stack_trap "rm -f $DIR/$tfile $dio_file"
25564
25565         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25566         $LCTL set_param fail_loc=0x1418
25567         # make sure we don't crash and fail properly
25568         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25569                 error "parallel dio page allocation failure succeeded"
25570         diff $DIR/$tfile $dio_file
25571         [[ $? != 0 ]] || error "no diff after failed aiocp"
25572 }
25573 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25574
25575 test_398j() { #  LU-13798
25576         # Stripe size > RPC size but less than i/o size tests split across
25577         # stripes and RPCs for individual i/o op
25578         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25579
25580         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25581         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25582         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25583         stack_trap "$LCTL set_param -n $pages_per_rpc"
25584
25585         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25586                 error "parallel dio write failed"
25587         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25588
25589         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25590                 error "parallel dio read failed"
25591         diff $DIR/$tfile $DIR/$tfile.2
25592         [[ $? == 0 ]] || error "file diff after parallel dio read"
25593 }
25594 run_test 398j "test parallel dio where stripe size > rpc_size"
25595
25596 test_398k() { #  LU-13798
25597         wait_delete_completed
25598         wait_mds_ost_sync
25599
25600         # 4 stripe file; we will cause out of space on OST0
25601         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25602
25603         # Fill OST0 (if it's not too large)
25604         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25605                    head -n1)
25606         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25607                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25608         fi
25609         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25610         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25611                 error "dd should fill OST0"
25612         stack_trap "rm -f $DIR/$tfile.1"
25613
25614         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25615         err=$?
25616
25617         ls -la $DIR/$tfile
25618         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25619                 error "file is not 0 bytes in size"
25620
25621         # dd above should not succeed, but don't error until here so we can
25622         # get debug info above
25623         [[ $err != 0 ]] ||
25624                 error "parallel dio write with enospc succeeded"
25625         stack_trap "rm -f $DIR/$tfile"
25626 }
25627 run_test 398k "test enospc on first stripe"
25628
25629 test_398l() { #  LU-13798
25630         wait_delete_completed
25631         wait_mds_ost_sync
25632
25633         # 4 stripe file; we will cause out of space on OST0
25634         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25635         # happens on the second i/o chunk we issue
25636         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25637
25638         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25639         stack_trap "rm -f $DIR/$tfile"
25640
25641         # Fill OST0 (if it's not too large)
25642         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25643                    head -n1)
25644         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25645                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25646         fi
25647         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25648         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25649                 error "dd should fill OST0"
25650         stack_trap "rm -f $DIR/$tfile.1"
25651
25652         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25653         err=$?
25654         stack_trap "rm -f $DIR/$tfile.2"
25655
25656         # Check that short write completed as expected
25657         ls -la $DIR/$tfile.2
25658         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25659                 error "file is not 1M in size"
25660
25661         # dd above should not succeed, but don't error until here so we can
25662         # get debug info above
25663         [[ $err != 0 ]] ||
25664                 error "parallel dio write with enospc succeeded"
25665
25666         # Truncate source file to same length as output file and diff them
25667         $TRUNCATE $DIR/$tfile 1048576
25668         diff $DIR/$tfile $DIR/$tfile.2
25669         [[ $? == 0 ]] || error "data incorrect after short write"
25670 }
25671 run_test 398l "test enospc on intermediate stripe/RPC"
25672
25673 test_398m() { #  LU-13798
25674         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25675
25676         # Set up failure on OST0, the first stripe:
25677         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25678         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25679         # OST0 is on ost1, OST1 is on ost2.
25680         # So this fail_val specifies OST0
25681         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25682         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25683
25684         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25685                 error "parallel dio write with failure on first stripe succeeded"
25686         stack_trap "rm -f $DIR/$tfile"
25687         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25688
25689         # Place data in file for read
25690         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25691                 error "parallel dio write failed"
25692
25693         # Fail read on OST0, first stripe
25694         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25695         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25696         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25697                 error "parallel dio read with error on first stripe succeeded"
25698         rm -f $DIR/$tfile.2
25699         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25700
25701         # Switch to testing on OST1, second stripe
25702         # Clear file contents, maintain striping
25703         echo > $DIR/$tfile
25704         # Set up failure on OST1, second stripe:
25705         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25706         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25707
25708         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25709                 error "parallel dio write with failure on second stripe succeeded"
25710         stack_trap "rm -f $DIR/$tfile"
25711         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25712
25713         # Place data in file for read
25714         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25715                 error "parallel dio write failed"
25716
25717         # Fail read on OST1, second stripe
25718         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25719         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25720         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25721                 error "parallel dio read with error on second stripe succeeded"
25722         rm -f $DIR/$tfile.2
25723         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25724 }
25725 run_test 398m "test RPC failures with parallel dio"
25726
25727 # Parallel submission of DIO should not cause problems for append, but it's
25728 # important to verify.
25729 test_398n() { #  LU-13798
25730         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25731
25732         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25733                 error "dd to create source file failed"
25734         stack_trap "rm -f $DIR/$tfile"
25735
25736         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25737                 error "parallel dio write with failure on second stripe succeeded"
25738         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25739         diff $DIR/$tfile $DIR/$tfile.1
25740         [[ $? == 0 ]] || error "data incorrect after append"
25741
25742 }
25743 run_test 398n "test append with parallel DIO"
25744
25745 test_398o() {
25746         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25747 }
25748 run_test 398o "right kms with DIO"
25749
25750 test_fake_rw() {
25751         local read_write=$1
25752         if [ "$read_write" = "write" ]; then
25753                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25754         elif [ "$read_write" = "read" ]; then
25755                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25756         else
25757                 error "argument error"
25758         fi
25759
25760         # turn off debug for performance testing
25761         local saved_debug=$($LCTL get_param -n debug)
25762         $LCTL set_param debug=0
25763
25764         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25765
25766         # get ost1 size - $FSNAME-OST0000
25767         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25768         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25769         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25770
25771         if [ "$read_write" = "read" ]; then
25772                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25773         fi
25774
25775         local start_time=$(date +%s.%N)
25776         $dd_cmd bs=1M count=$blocks oflag=sync ||
25777                 error "real dd $read_write error"
25778         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25779
25780         if [ "$read_write" = "write" ]; then
25781                 rm -f $DIR/$tfile
25782         fi
25783
25784         # define OBD_FAIL_OST_FAKE_RW           0x238
25785         do_facet ost1 $LCTL set_param fail_loc=0x238
25786
25787         local start_time=$(date +%s.%N)
25788         $dd_cmd bs=1M count=$blocks oflag=sync ||
25789                 error "fake dd $read_write error"
25790         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25791
25792         if [ "$read_write" = "write" ]; then
25793                 # verify file size
25794                 cancel_lru_locks osc
25795                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25796                         error "$tfile size not $blocks MB"
25797         fi
25798         do_facet ost1 $LCTL set_param fail_loc=0
25799
25800         echo "fake $read_write $duration_fake vs. normal $read_write" \
25801                 "$duration in seconds"
25802         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25803                 error_not_in_vm "fake write is slower"
25804
25805         $LCTL set_param -n debug="$saved_debug"
25806         rm -f $DIR/$tfile
25807 }
25808 test_399a() { # LU-7655 for OST fake write
25809         remote_ost_nodsh && skip "remote OST with nodsh"
25810
25811         test_fake_rw write
25812 }
25813 run_test 399a "fake write should not be slower than normal write"
25814
25815 test_399b() { # LU-8726 for OST fake read
25816         remote_ost_nodsh && skip "remote OST with nodsh"
25817         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25818                 skip_env "ldiskfs only test"
25819         fi
25820
25821         test_fake_rw read
25822 }
25823 run_test 399b "fake read should not be slower than normal read"
25824
25825 test_400a() { # LU-1606, was conf-sanity test_74
25826         if ! which $CC > /dev/null 2>&1; then
25827                 skip_env "$CC is not installed"
25828         fi
25829
25830         local extra_flags=''
25831         local out=$TMP/$tfile
25832         local prefix=/usr/include/lustre
25833         local prog
25834
25835         # Oleg removes .c files in his test rig so test if any c files exist
25836         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25837                 skip_env "Needed .c test files are missing"
25838
25839         if ! [[ -d $prefix ]]; then
25840                 # Assume we're running in tree and fixup the include path.
25841                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25842                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25843                 extra_flags+=" -L$LUSTRE/utils/.libs"
25844         fi
25845
25846         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25847                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25848                         error "client api broken"
25849         done
25850         rm -f $out
25851 }
25852 run_test 400a "Lustre client api program can compile and link"
25853
25854 test_400b() { # LU-1606, LU-5011
25855         local header
25856         local out=$TMP/$tfile
25857         local prefix=/usr/include/linux/lustre
25858
25859         # We use a hard coded prefix so that this test will not fail
25860         # when run in tree. There are headers in lustre/include/lustre/
25861         # that are not packaged (like lustre_idl.h) and have more
25862         # complicated include dependencies (like config.h and lnet/types.h).
25863         # Since this test about correct packaging we just skip them when
25864         # they don't exist (see below) rather than try to fixup cppflags.
25865
25866         if ! which $CC > /dev/null 2>&1; then
25867                 skip_env "$CC is not installed"
25868         fi
25869
25870         for header in $prefix/*.h; do
25871                 if ! [[ -f "$header" ]]; then
25872                         continue
25873                 fi
25874
25875                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25876                         continue # lustre_ioctl.h is internal header
25877                 fi
25878
25879                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25880                         error "cannot compile '$header'"
25881         done
25882         rm -f $out
25883 }
25884 run_test 400b "packaged headers can be compiled"
25885
25886 test_401a() { #LU-7437
25887         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25888         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25889
25890         #count the number of parameters by "list_param -R"
25891         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25892         #count the number of parameters by listing proc files
25893         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25894         echo "proc_dirs='$proc_dirs'"
25895         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25896         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25897                       sort -u | wc -l)
25898
25899         [ $params -eq $procs ] ||
25900                 error "found $params parameters vs. $procs proc files"
25901
25902         # test the list_param -D option only returns directories
25903         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25904         #count the number of parameters by listing proc directories
25905         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25906                 sort -u | wc -l)
25907
25908         [ $params -eq $procs ] ||
25909                 error "found $params parameters vs. $procs proc files"
25910 }
25911 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25912
25913 test_401b() {
25914         # jobid_var may not allow arbitrary values, so use jobid_name
25915         # if available
25916         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25917                 local testname=jobid_name tmp='testing%p'
25918         else
25919                 local testname=jobid_var tmp=testing
25920         fi
25921
25922         local save=$($LCTL get_param -n $testname)
25923
25924         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25925                 error "no error returned when setting bad parameters"
25926
25927         local jobid_new=$($LCTL get_param -n foe $testname baz)
25928         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25929
25930         $LCTL set_param -n fog=bam $testname=$save bat=fog
25931         local jobid_old=$($LCTL get_param -n foe $testname bag)
25932         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25933 }
25934 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25935
25936 test_401c() {
25937         # jobid_var may not allow arbitrary values, so use jobid_name
25938         # if available
25939         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25940                 local testname=jobid_name
25941         else
25942                 local testname=jobid_var
25943         fi
25944
25945         local jobid_var_old=$($LCTL get_param -n $testname)
25946         local jobid_var_new
25947
25948         $LCTL set_param $testname= &&
25949                 error "no error returned for 'set_param a='"
25950
25951         jobid_var_new=$($LCTL get_param -n $testname)
25952         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25953                 error "$testname was changed by setting without value"
25954
25955         $LCTL set_param $testname &&
25956                 error "no error returned for 'set_param a'"
25957
25958         jobid_var_new=$($LCTL get_param -n $testname)
25959         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25960                 error "$testname was changed by setting without value"
25961 }
25962 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25963
25964 test_401d() {
25965         # jobid_var may not allow arbitrary values, so use jobid_name
25966         # if available
25967         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25968                 local testname=jobid_name new_value='foo=bar%p'
25969         else
25970                 local testname=jobid_var new_valuie=foo=bar
25971         fi
25972
25973         local jobid_var_old=$($LCTL get_param -n $testname)
25974         local jobid_var_new
25975
25976         $LCTL set_param $testname=$new_value ||
25977                 error "'set_param a=b' did not accept a value containing '='"
25978
25979         jobid_var_new=$($LCTL get_param -n $testname)
25980         [[ "$jobid_var_new" == "$new_value" ]] ||
25981                 error "'set_param a=b' failed on a value containing '='"
25982
25983         # Reset the $testname to test the other format
25984         $LCTL set_param $testname=$jobid_var_old
25985         jobid_var_new=$($LCTL get_param -n $testname)
25986         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25987                 error "failed to reset $testname"
25988
25989         $LCTL set_param $testname $new_value ||
25990                 error "'set_param a b' did not accept a value containing '='"
25991
25992         jobid_var_new=$($LCTL get_param -n $testname)
25993         [[ "$jobid_var_new" == "$new_value" ]] ||
25994                 error "'set_param a b' failed on a value containing '='"
25995
25996         $LCTL set_param $testname $jobid_var_old
25997         jobid_var_new=$($LCTL get_param -n $testname)
25998         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25999                 error "failed to reset $testname"
26000 }
26001 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26002
26003 test_401e() { # LU-14779
26004         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26005                 error "lctl list_param MGC* failed"
26006         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26007         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26008                 error "lctl get_param lru_size failed"
26009 }
26010 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26011
26012 test_402() {
26013         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26014         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26015                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26016         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26017                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26018                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26019         remote_mds_nodsh && skip "remote MDS with nodsh"
26020
26021         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26022 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26023         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26024         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26025                 echo "Touch failed - OK"
26026 }
26027 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26028
26029 test_403() {
26030         local file1=$DIR/$tfile.1
26031         local file2=$DIR/$tfile.2
26032         local tfile=$TMP/$tfile
26033
26034         rm -f $file1 $file2 $tfile
26035
26036         touch $file1
26037         ln $file1 $file2
26038
26039         # 30 sec OBD_TIMEOUT in ll_getattr()
26040         # right before populating st_nlink
26041         $LCTL set_param fail_loc=0x80001409
26042         stat -c %h $file1 > $tfile &
26043
26044         # create an alias, drop all locks and reclaim the dentry
26045         < $file2
26046         cancel_lru_locks mdc
26047         cancel_lru_locks osc
26048         sysctl -w vm.drop_caches=2
26049
26050         wait
26051
26052         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26053
26054         rm -f $tfile $file1 $file2
26055 }
26056 run_test 403 "i_nlink should not drop to zero due to aliasing"
26057
26058 test_404() { # LU-6601
26059         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26060                 skip "Need server version newer than 2.8.52"
26061         remote_mds_nodsh && skip "remote MDS with nodsh"
26062
26063         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26064                 awk '/osp .*-osc-MDT/ { print $4}')
26065
26066         local osp
26067         for osp in $mosps; do
26068                 echo "Deactivate: " $osp
26069                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26070                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26071                         awk -vp=$osp '$4 == p { print $2 }')
26072                 [ $stat = IN ] || {
26073                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26074                         error "deactivate error"
26075                 }
26076                 echo "Activate: " $osp
26077                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26078                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26079                         awk -vp=$osp '$4 == p { print $2 }')
26080                 [ $stat = UP ] || {
26081                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26082                         error "activate error"
26083                 }
26084         done
26085 }
26086 run_test 404 "validate manual {de}activated works properly for OSPs"
26087
26088 test_405() {
26089         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26090         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26091                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26092                         skip "Layout swap lock is not supported"
26093
26094         check_swap_layouts_support
26095         check_swap_layout_no_dom $DIR
26096
26097         test_mkdir $DIR/$tdir
26098         swap_lock_test -d $DIR/$tdir ||
26099                 error "One layout swap locked test failed"
26100 }
26101 run_test 405 "Various layout swap lock tests"
26102
26103 test_406() {
26104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26105         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26106         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26108         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26109                 skip "Need MDS version at least 2.8.50"
26110
26111         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26112         local test_pool=$TESTNAME
26113
26114         pool_add $test_pool || error "pool_add failed"
26115         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26116                 error "pool_add_targets failed"
26117
26118         save_layout_restore_at_exit $MOUNT
26119
26120         # parent set default stripe count only, child will stripe from both
26121         # parent and fs default
26122         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26123                 error "setstripe $MOUNT failed"
26124         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26125         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26126         for i in $(seq 10); do
26127                 local f=$DIR/$tdir/$tfile.$i
26128                 touch $f || error "touch failed"
26129                 local count=$($LFS getstripe -c $f)
26130                 [ $count -eq $OSTCOUNT ] ||
26131                         error "$f stripe count $count != $OSTCOUNT"
26132                 local offset=$($LFS getstripe -i $f)
26133                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26134                 local size=$($LFS getstripe -S $f)
26135                 [ $size -eq $((def_stripe_size * 2)) ] ||
26136                         error "$f stripe size $size != $((def_stripe_size * 2))"
26137                 local pool=$($LFS getstripe -p $f)
26138                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26139         done
26140
26141         # change fs default striping, delete parent default striping, now child
26142         # will stripe from new fs default striping only
26143         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26144                 error "change $MOUNT default stripe failed"
26145         $LFS setstripe -c 0 $DIR/$tdir ||
26146                 error "delete $tdir default stripe failed"
26147         for i in $(seq 11 20); do
26148                 local f=$DIR/$tdir/$tfile.$i
26149                 touch $f || error "touch $f failed"
26150                 local count=$($LFS getstripe -c $f)
26151                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26152                 local offset=$($LFS getstripe -i $f)
26153                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26154                 local size=$($LFS getstripe -S $f)
26155                 [ $size -eq $def_stripe_size ] ||
26156                         error "$f stripe size $size != $def_stripe_size"
26157                 local pool=$($LFS getstripe -p $f)
26158                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26159         done
26160
26161         unlinkmany $DIR/$tdir/$tfile. 1 20
26162
26163         local f=$DIR/$tdir/$tfile
26164         pool_remove_all_targets $test_pool $f
26165         pool_remove $test_pool $f
26166 }
26167 run_test 406 "DNE support fs default striping"
26168
26169 test_407() {
26170         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26171         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26172                 skip "Need MDS version at least 2.8.55"
26173         remote_mds_nodsh && skip "remote MDS with nodsh"
26174
26175         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26176                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26177         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26178                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26179         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26180
26181         #define OBD_FAIL_DT_TXN_STOP    0x2019
26182         for idx in $(seq $MDSCOUNT); do
26183                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26184         done
26185         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26186         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26187                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26188         true
26189 }
26190 run_test 407 "transaction fail should cause operation fail"
26191
26192 test_408() {
26193         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26194
26195         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26196         lctl set_param fail_loc=0x8000040a
26197         # let ll_prepare_partial_page() fail
26198         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26199
26200         rm -f $DIR/$tfile
26201
26202         # create at least 100 unused inodes so that
26203         # shrink_icache_memory(0) should not return 0
26204         touch $DIR/$tfile-{0..100}
26205         rm -f $DIR/$tfile-{0..100}
26206         sync
26207
26208         echo 2 > /proc/sys/vm/drop_caches
26209 }
26210 run_test 408 "drop_caches should not hang due to page leaks"
26211
26212 test_409()
26213 {
26214         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26215
26216         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26217         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26218         touch $DIR/$tdir/guard || error "(2) Fail to create"
26219
26220         local PREFIX=$(str_repeat 'A' 128)
26221         echo "Create 1K hard links start at $(date)"
26222         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26223                 error "(3) Fail to hard link"
26224
26225         echo "Links count should be right although linkEA overflow"
26226         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26227         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26228         [ $linkcount -eq 1001 ] ||
26229                 error "(5) Unexpected hard links count: $linkcount"
26230
26231         echo "List all links start at $(date)"
26232         ls -l $DIR/$tdir/foo > /dev/null ||
26233                 error "(6) Fail to list $DIR/$tdir/foo"
26234
26235         echo "Unlink hard links start at $(date)"
26236         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26237                 error "(7) Fail to unlink"
26238         echo "Unlink hard links finished at $(date)"
26239 }
26240 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26241
26242 test_410()
26243 {
26244         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26245                 skip "Need client version at least 2.9.59"
26246         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26247                 skip "Need MODULES build"
26248
26249         # Create a file, and stat it from the kernel
26250         local testfile=$DIR/$tfile
26251         touch $testfile
26252
26253         local run_id=$RANDOM
26254         local my_ino=$(stat --format "%i" $testfile)
26255
26256         # Try to insert the module. This will always fail as the
26257         # module is designed to not be inserted.
26258         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26259             &> /dev/null
26260
26261         # Anything but success is a test failure
26262         dmesg | grep -q \
26263             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26264             error "no inode match"
26265 }
26266 run_test 410 "Test inode number returned from kernel thread"
26267
26268 cleanup_test411_cgroup() {
26269         trap 0
26270         rmdir "$1"
26271 }
26272
26273 test_411() {
26274         local cg_basedir=/sys/fs/cgroup/memory
26275         # LU-9966
26276         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26277                 skip "no setup for cgroup"
26278
26279         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26280                 error "test file creation failed"
26281         cancel_lru_locks osc
26282
26283         # Create a very small memory cgroup to force a slab allocation error
26284         local cgdir=$cg_basedir/osc_slab_alloc
26285         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26286         trap "cleanup_test411_cgroup $cgdir" EXIT
26287         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26288         echo 1M > $cgdir/memory.limit_in_bytes
26289
26290         # Should not LBUG, just be killed by oom-killer
26291         # dd will return 0 even allocation failure in some environment.
26292         # So don't check return value
26293         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26294         cleanup_test411_cgroup $cgdir
26295
26296         return 0
26297 }
26298 run_test 411 "Slab allocation error with cgroup does not LBUG"
26299
26300 test_412() {
26301         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26302         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26303                 skip "Need server version at least 2.10.55"
26304
26305         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26306                 error "mkdir failed"
26307         $LFS getdirstripe $DIR/$tdir
26308         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26309         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26310                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26311         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26312         [ $stripe_count -eq 2 ] ||
26313                 error "expect 2 get $stripe_count"
26314
26315         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26316
26317         local index
26318         local index2
26319
26320         # subdirs should be on the same MDT as parent
26321         for i in $(seq 0 $((MDSCOUNT - 1))); do
26322                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26323                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26324                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26325                 (( index == i )) || error "mdt$i/sub on MDT$index"
26326         done
26327
26328         # stripe offset -1, ditto
26329         for i in {1..10}; do
26330                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26331                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26332                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26333                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26334                 (( index == index2 )) ||
26335                         error "qos$i on MDT$index, sub on MDT$index2"
26336         done
26337
26338         local testdir=$DIR/$tdir/inherit
26339
26340         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26341         # inherit 2 levels
26342         for i in 1 2; do
26343                 testdir=$testdir/s$i
26344                 mkdir $testdir || error "mkdir $testdir failed"
26345                 index=$($LFS getstripe -m $testdir)
26346                 (( index == 1 )) ||
26347                         error "$testdir on MDT$index"
26348         done
26349
26350         # not inherit any more
26351         testdir=$testdir/s3
26352         mkdir $testdir || error "mkdir $testdir failed"
26353         getfattr -d -m dmv $testdir | grep dmv &&
26354                 error "default LMV set on $testdir" || true
26355 }
26356 run_test 412 "mkdir on specific MDTs"
26357
26358 TEST413_COUNT=${TEST413_COUNT:-200}
26359
26360 #
26361 # set_maxage() is used by test_413 only.
26362 # This is a helper function to set maxage. Does not return any value.
26363 # Input: maxage to set
26364 #
26365 set_maxage() {
26366         local lmv_qos_maxage
26367         local lod_qos_maxage
26368         local new_maxage=$1
26369
26370         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26371         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26372         stack_trap "$LCTL set_param \
26373                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26374         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26375                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26376         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26377                 lod.*.mdt_qos_maxage=$new_maxage
26378         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26379                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26380 }
26381
26382 generate_uneven_mdts() {
26383         local threshold=$1
26384         local ffree
26385         local bavail
26386         local max
26387         local min
26388         local max_index
26389         local min_index
26390         local tmp
26391         local i
26392
26393         echo
26394         echo "Check for uneven MDTs: "
26395
26396         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26397         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26398         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26399
26400         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26401         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26402         max_index=0
26403         min_index=0
26404         for ((i = 1; i < ${#ffree[@]}; i++)); do
26405                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26406                 if [ $tmp -gt $max ]; then
26407                         max=$tmp
26408                         max_index=$i
26409                 fi
26410                 if [ $tmp -lt $min ]; then
26411                         min=$tmp
26412                         min_index=$i
26413                 fi
26414         done
26415
26416         (( min > 0 )) || skip "low space on MDT$min_index"
26417         (( ${ffree[min_index]} > 0 )) ||
26418                 skip "no free files on MDT$min_index"
26419         (( ${ffree[min_index]} < 10000000 )) ||
26420                 skip "too many free files on MDT$min_index"
26421
26422         # Check if we need to generate uneven MDTs
26423         local diff=$(((max - min) * 100 / min))
26424         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26425         local testdir # individual folder within $testdirp
26426         local start
26427         local cmd
26428
26429         # fallocate is faster to consume space on MDT, if available
26430         if check_fallocate_supported mds$((min_index + 1)); then
26431                 cmd="fallocate -l 128K "
26432         else
26433                 cmd="dd if=/dev/zero bs=128K count=1 of="
26434         fi
26435
26436         echo "using cmd $cmd"
26437         for (( i = 0; diff < threshold; i++ )); do
26438                 testdir=${testdirp}/$i
26439                 [ -d $testdir ] && continue
26440
26441                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26442
26443                 mkdir -p $testdirp
26444                 # generate uneven MDTs, create till $threshold% diff
26445                 echo -n "weight diff=$diff% must be > $threshold% ..."
26446                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26447                 $LFS mkdir -i $min_index $testdir ||
26448                         error "mkdir $testdir failed"
26449                 $LFS setstripe -E 1M -L mdt $testdir ||
26450                         error "setstripe $testdir failed"
26451                 start=$SECONDS
26452                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26453                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26454                 done
26455                 sync; sleep 1; sync
26456
26457                 # wait for QOS to update
26458                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26459
26460                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26461                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26462                 max=$(((${ffree[max_index]} >> 8) *
26463                         (${bavail[max_index]} * bsize >> 16)))
26464                 min=$(((${ffree[min_index]} >> 8) *
26465                         (${bavail[min_index]} * bsize >> 16)))
26466                 (( min > 0 )) || skip "low space on MDT$min_index"
26467                 diff=$(((max - min) * 100 / min))
26468         done
26469
26470         echo "MDT filesfree available: ${ffree[*]}"
26471         echo "MDT blocks available: ${bavail[*]}"
26472         echo "weight diff=$diff%"
26473 }
26474
26475 test_qos_mkdir() {
26476         local mkdir_cmd=$1
26477         local stripe_count=$2
26478         local mdts=$(comma_list $(mdts_nodes))
26479
26480         local testdir
26481         local lmv_qos_prio_free
26482         local lmv_qos_threshold_rr
26483         local lod_qos_prio_free
26484         local lod_qos_threshold_rr
26485         local total
26486         local count
26487         local i
26488
26489         # @total is total directories created if it's testing plain
26490         # directories, otherwise it's total stripe object count for
26491         # striped directories test.
26492         # remote/striped directory unlinking is slow on zfs and may
26493         # timeout, test with fewer directories
26494         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26495
26496         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26497         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26498         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26499                 head -n1)
26500         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26501         stack_trap "$LCTL set_param \
26502                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26503         stack_trap "$LCTL set_param \
26504                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26505
26506         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26507                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26508         lod_qos_prio_free=${lod_qos_prio_free%%%}
26509         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26510                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26511         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26512         stack_trap "do_nodes $mdts $LCTL set_param \
26513                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26514         stack_trap "do_nodes $mdts $LCTL set_param \
26515                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26516
26517         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26518         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26519
26520         testdir=$DIR/$tdir-s$stripe_count/rr
26521
26522         local stripe_index=$($LFS getstripe -m $testdir)
26523         local test_mkdir_rr=true
26524
26525         getfattr -d -m dmv -e hex $testdir | grep dmv
26526         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26527                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26528                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26529                         test_mkdir_rr=false
26530         fi
26531
26532         echo
26533         $test_mkdir_rr &&
26534                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26535                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26536
26537         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26538         for (( i = 0; i < total / stripe_count; i++ )); do
26539                 eval $mkdir_cmd $testdir/subdir$i ||
26540                         error "$mkdir_cmd subdir$i failed"
26541         done
26542
26543         for (( i = 0; i < $MDSCOUNT; i++ )); do
26544                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26545                 echo "$count directories created on MDT$i"
26546                 if $test_mkdir_rr; then
26547                         (( count == total / stripe_count / MDSCOUNT )) ||
26548                                 error "subdirs are not evenly distributed"
26549                 elif (( i == stripe_index )); then
26550                         (( count == total / stripe_count )) ||
26551                                 error "$count subdirs created on MDT$i"
26552                 else
26553                         (( count == 0 )) ||
26554                                 error "$count subdirs created on MDT$i"
26555                 fi
26556
26557                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26558                         count=$($LFS getdirstripe $testdir/* |
26559                                 grep -c -P "^\s+$i\t")
26560                         echo "$count stripes created on MDT$i"
26561                         # deviation should < 5% of average
26562                         delta=$((count - total / MDSCOUNT))
26563                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26564                                 error "stripes are not evenly distributed"
26565                 fi
26566         done
26567
26568         echo
26569         echo "Check for uneven MDTs: "
26570
26571         local ffree
26572         local bavail
26573         local max
26574         local min
26575         local max_index
26576         local min_index
26577         local tmp
26578
26579         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26580         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26581         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26582
26583         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26584         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26585         max_index=0
26586         min_index=0
26587         for ((i = 1; i < ${#ffree[@]}; i++)); do
26588                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26589                 if [ $tmp -gt $max ]; then
26590                         max=$tmp
26591                         max_index=$i
26592                 fi
26593                 if [ $tmp -lt $min ]; then
26594                         min=$tmp
26595                         min_index=$i
26596                 fi
26597         done
26598         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26599
26600         (( min > 0 )) || skip "low space on MDT$min_index"
26601         (( ${ffree[min_index]} < 10000000 )) ||
26602                 skip "too many free files on MDT$min_index"
26603
26604         generate_uneven_mdts 120
26605
26606         echo "MDT filesfree available: ${ffree[*]}"
26607         echo "MDT blocks available: ${bavail[*]}"
26608         echo "weight diff=$(((max - min) * 100 / min))%"
26609         echo
26610         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26611
26612         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26613         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26614         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26615         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26616         # decrease statfs age, so that it can be updated in time
26617         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26618         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26619
26620         sleep 1
26621
26622         testdir=$DIR/$tdir-s$stripe_count/qos
26623
26624         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26625         for (( i = 0; i < total / stripe_count; i++ )); do
26626                 eval $mkdir_cmd $testdir/subdir$i ||
26627                         error "$mkdir_cmd subdir$i failed"
26628         done
26629
26630         max=0
26631         for (( i = 0; i < $MDSCOUNT; i++ )); do
26632                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26633                 (( count > max )) && max=$count
26634                 echo "$count directories created on MDT$i : curmax=$max"
26635         done
26636
26637         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26638
26639         # D-value should > 10% of average
26640         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26641                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26642
26643         # ditto for stripes
26644         if (( stripe_count > 1 )); then
26645                 max=0
26646                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26647                         count=$($LFS getdirstripe $testdir/* |
26648                                 grep -c -P "^\s+$i\t")
26649                         (( count > max )) && max=$count
26650                         echo "$count stripes created on MDT$i"
26651                 done
26652
26653                 min=$($LFS getdirstripe $testdir/* |
26654                         grep -c -P "^\s+$min_index\t")
26655                 (( max - min > total / MDSCOUNT / 10 )) ||
26656                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26657         fi
26658 }
26659
26660 most_full_mdt() {
26661         local ffree
26662         local bavail
26663         local bsize
26664         local min
26665         local min_index
26666         local tmp
26667
26668         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26669         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26670         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26671
26672         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26673         min_index=0
26674         for ((i = 1; i < ${#ffree[@]}; i++)); do
26675                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26676                 (( tmp < min )) && min=$tmp && min_index=$i
26677         done
26678
26679         echo -n $min_index
26680 }
26681
26682 test_413a() {
26683         [ $MDSCOUNT -lt 2 ] &&
26684                 skip "We need at least 2 MDTs for this test"
26685
26686         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26687                 skip "Need server version at least 2.12.52"
26688
26689         local stripe_max=$((MDSCOUNT - 1))
26690         local stripe_count
26691
26692         # let caller set maxage for latest result
26693         set_maxage 1
26694
26695         # fill MDT unevenly
26696         generate_uneven_mdts 120
26697
26698         # test 4-stripe directory at most, otherwise it's too slow
26699         # We are being very defensive. Although Autotest uses 4 MDTs.
26700         # We make sure stripe_max does not go over 4.
26701         (( stripe_max > 4 )) && stripe_max=4
26702         # unlinking striped directory is slow on zfs, and may timeout, only test
26703         # plain directory
26704         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26705         for stripe_count in $(seq 1 $stripe_max); do
26706                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26707                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26708                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26709                         error "mkdir failed"
26710                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26711         done
26712 }
26713 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26714
26715 test_413b() {
26716         [ $MDSCOUNT -lt 2 ] &&
26717                 skip "We need at least 2 MDTs for this test"
26718
26719         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26720                 skip "Need server version at least 2.12.52"
26721
26722         local stripe_max=$((MDSCOUNT - 1))
26723         local testdir
26724         local stripe_count
26725
26726         # let caller set maxage for latest result
26727         set_maxage 1
26728
26729         # fill MDT unevenly
26730         generate_uneven_mdts 120
26731
26732         # test 4-stripe directory at most, otherwise it's too slow
26733         # We are being very defensive. Although Autotest uses 4 MDTs.
26734         # We make sure stripe_max does not go over 4.
26735         (( stripe_max > 4 )) && stripe_max=4
26736         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26737         for stripe_count in $(seq 1 $stripe_max); do
26738                 testdir=$DIR/$tdir-s$stripe_count
26739                 mkdir $testdir || error "mkdir $testdir failed"
26740                 mkdir $testdir/rr || error "mkdir rr failed"
26741                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26742                         error "mkdir qos failed"
26743                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26744                         $testdir/rr || error "setdirstripe rr failed"
26745                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26746                         error "setdirstripe failed"
26747                 test_qos_mkdir "mkdir" $stripe_count
26748         done
26749 }
26750 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26751
26752 test_413c() {
26753         (( $MDSCOUNT >= 2 )) ||
26754                 skip "We need at least 2 MDTs for this test"
26755
26756         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26757                 skip "Need server version at least 2.14.51"
26758
26759         local testdir
26760         local inherit
26761         local inherit_rr
26762         local lmv_qos_maxage
26763         local lod_qos_maxage
26764
26765         # let caller set maxage for latest result
26766         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26767         $LCTL set_param lmv.*.qos_maxage=1
26768         stack_trap "$LCTL set_param \
26769                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26770         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26771                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26772         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26773                 lod.*.mdt_qos_maxage=1
26774         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26775                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26776
26777         # fill MDT unevenly
26778         generate_uneven_mdts 120
26779
26780         testdir=$DIR/${tdir}-s1
26781         mkdir $testdir || error "mkdir $testdir failed"
26782         mkdir $testdir/rr || error "mkdir rr failed"
26783         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26784         # default max_inherit is -1, default max_inherit_rr is 0
26785         $LFS setdirstripe -D -c 1 $testdir/rr ||
26786                 error "setdirstripe rr failed"
26787         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26788                 error "setdirstripe qos failed"
26789         test_qos_mkdir "mkdir" 1
26790
26791         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26792         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26793         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26794         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26795         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26796
26797         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26798         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26799         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26800         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26801         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26802         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26803         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26804                 error "level2 shouldn't have default LMV" || true
26805 }
26806 run_test 413c "mkdir with default LMV max inherit rr"
26807
26808 test_413d() {
26809         (( MDSCOUNT >= 2 )) ||
26810                 skip "We need at least 2 MDTs for this test"
26811
26812         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26813                 skip "Need server version at least 2.14.51"
26814
26815         local lmv_qos_threshold_rr
26816
26817         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26818                 head -n1)
26819         stack_trap "$LCTL set_param \
26820                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26821
26822         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26823         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26824         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26825                 error "$tdir shouldn't have default LMV"
26826         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26827                 error "mkdir sub failed"
26828
26829         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26830
26831         (( count == 100 )) || error "$count subdirs on MDT0"
26832 }
26833 run_test 413d "inherit ROOT default LMV"
26834
26835 test_413e() {
26836         (( MDSCOUNT >= 2 )) ||
26837                 skip "We need at least 2 MDTs for this test"
26838         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26839                 skip "Need server version at least 2.14.55"
26840
26841         local testdir=$DIR/$tdir
26842         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26843         local max_inherit
26844         local sub_max_inherit
26845
26846         mkdir -p $testdir || error "failed to create $testdir"
26847
26848         # set default max-inherit to -1 if stripe count is 0 or 1
26849         $LFS setdirstripe -D -c 1 $testdir ||
26850                 error "failed to set default LMV"
26851         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26852         (( max_inherit == -1 )) ||
26853                 error "wrong max_inherit value $max_inherit"
26854
26855         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26856         $LFS setdirstripe -D -c -1 $testdir ||
26857                 error "failed to set default LMV"
26858         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26859         (( max_inherit > 0 )) ||
26860                 error "wrong max_inherit value $max_inherit"
26861
26862         # and the subdir will decrease the max_inherit by 1
26863         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26864         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26865         (( sub_max_inherit == max_inherit - 1)) ||
26866                 error "wrong max-inherit of subdir $sub_max_inherit"
26867
26868         # check specified --max-inherit and warning message
26869         stack_trap "rm -f $tmpfile"
26870         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26871                 error "failed to set default LMV"
26872         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26873         (( max_inherit == -1 )) ||
26874                 error "wrong max_inherit value $max_inherit"
26875
26876         # check the warning messages
26877         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26878                 error "failed to detect warning string"
26879         fi
26880 }
26881 run_test 413e "check default max-inherit value"
26882
26883 test_fs_dmv_inherit()
26884 {
26885         local testdir=$DIR/$tdir
26886
26887         local count
26888         local inherit
26889         local inherit_rr
26890
26891         for i in 1 2; do
26892                 mkdir $testdir || error "mkdir $testdir failed"
26893                 count=$($LFS getdirstripe -D -c $testdir)
26894                 (( count == 1 )) ||
26895                         error "$testdir default LMV count mismatch $count != 1"
26896                 inherit=$($LFS getdirstripe -D -X $testdir)
26897                 (( inherit == 3 - i )) ||
26898                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26899                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26900                 (( inherit_rr == 3 - i )) ||
26901                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26902                 testdir=$testdir/sub
26903         done
26904
26905         mkdir $testdir || error "mkdir $testdir failed"
26906         count=$($LFS getdirstripe -D -c $testdir)
26907         (( count == 0 )) ||
26908                 error "$testdir default LMV count not zero: $count"
26909 }
26910
26911 test_413f() {
26912         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26913
26914         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26915                 skip "Need server version at least 2.14.55"
26916
26917         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26918                 error "dump $DIR default LMV failed"
26919         stack_trap "setfattr --restore=$TMP/dmv.ea"
26920
26921         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26922                 error "set $DIR default LMV failed"
26923
26924         test_fs_dmv_inherit
26925 }
26926 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26927
26928 test_413g() {
26929         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26930
26931         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26932         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26933                 error "dump $DIR default LMV failed"
26934         stack_trap "setfattr --restore=$TMP/dmv.ea"
26935
26936         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26937                 error "set $DIR default LMV failed"
26938
26939         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26940                 error "mount $MOUNT2 failed"
26941         stack_trap "umount_client $MOUNT2"
26942
26943         local saved_DIR=$DIR
26944
26945         export DIR=$MOUNT2
26946
26947         stack_trap "export DIR=$saved_DIR"
26948
26949         # first check filesystem-wide default LMV inheritance
26950         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26951
26952         # then check subdirs are spread to all MDTs
26953         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26954
26955         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26956
26957         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26958 }
26959 run_test 413g "enforce ROOT default LMV on subdir mount"
26960
26961 test_413h() {
26962         (( MDSCOUNT >= 2 )) ||
26963                 skip "We need at least 2 MDTs for this test"
26964
26965         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26966                 skip "Need server version at least 2.15.50.6"
26967
26968         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26969
26970         stack_trap "$LCTL set_param \
26971                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26972         $LCTL set_param lmv.*.qos_maxage=1
26973
26974         local depth=5
26975         local rr_depth=4
26976         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26977         local count=$((MDSCOUNT * 20))
26978
26979         generate_uneven_mdts 50
26980
26981         mkdir -p $dir || error "mkdir $dir failed"
26982         stack_trap "rm -rf $dir"
26983         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26984                 --max-inherit-rr=$rr_depth $dir
26985
26986         for ((d=0; d < depth + 2; d++)); do
26987                 log "dir=$dir:"
26988                 for ((sub=0; sub < count; sub++)); do
26989                         mkdir $dir/d$sub
26990                 done
26991                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26992                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26993                 # subdirs within $rr_depth should be created round-robin
26994                 if (( d < rr_depth )); then
26995                         (( ${num[0]} != count )) ||
26996                                 error "all objects created on MDT ${num[1]}"
26997                 fi
26998
26999                 dir=$dir/d0
27000         done
27001 }
27002 run_test 413h "don't stick to parent for round-robin dirs"
27003
27004 test_413i() {
27005         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27006
27007         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27008                 skip "Need server version at least 2.14.55"
27009
27010         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27011                 error "dump $DIR default LMV failed"
27012         stack_trap "setfattr --restore=$TMP/dmv.ea"
27013
27014         local testdir=$DIR/$tdir
27015         local def_max_rr=1
27016         local def_max=3
27017         local count
27018
27019         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27020                 --max-inherit-rr=$def_max_rr $DIR ||
27021                 error "set $DIR default LMV failed"
27022
27023         for i in $(seq 2 3); do
27024                 def_max=$((def_max - 1))
27025                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27026
27027                 mkdir $testdir
27028                 # RR is decremented and keeps zeroed once exhausted
27029                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27030                 (( count == def_max_rr )) ||
27031                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27032
27033                 # max-inherit is decremented
27034                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27035                 (( count == def_max )) ||
27036                         error_noexit "$testdir: max-inherit $count != $def_max"
27037
27038                 testdir=$testdir/d$i
27039         done
27040
27041         # d3 is the last inherited from ROOT, no inheritance anymore
27042         # i.e. no the default layout anymore
27043         mkdir -p $testdir/d4/d5
27044         count=$($LFS getdirstripe -D --max-inherit $testdir)
27045         (( count == -1 )) ||
27046                 error_noexit "$testdir: max-inherit $count != -1"
27047
27048         local p_count=$($LFS getdirstripe -i $testdir)
27049
27050         for i in $(seq 4 5); do
27051                 testdir=$testdir/d$i
27052
27053                 # the root default layout is not applied once exhausted
27054                 count=$($LFS getdirstripe -i $testdir)
27055                 (( count == p_count )) ||
27056                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27057         done
27058
27059         $LFS setdirstripe -i 0 $DIR/d2
27060         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27061         (( count == -1 )) ||
27062                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27063 }
27064 run_test 413i "check default layout inheritance"
27065
27066 test_413z() {
27067         local pids=""
27068         local subdir
27069         local pid
27070
27071         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27072                 unlinkmany $subdir/f. $TEST413_COUNT &
27073                 pids="$pids $!"
27074         done
27075
27076         for pid in $pids; do
27077                 wait $pid
27078         done
27079
27080         true
27081 }
27082 run_test 413z "413 test cleanup"
27083
27084 test_414() {
27085 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27086         $LCTL set_param fail_loc=0x80000521
27087         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27088         rm -f $DIR/$tfile
27089 }
27090 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27091
27092 test_415() {
27093         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27094         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27095                 skip "Need server version at least 2.11.52"
27096
27097         # LU-11102
27098         local total=500
27099         local max=120
27100
27101         # this test may be slow on ZFS
27102         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27103
27104         # though this test is designed for striped directory, let's test normal
27105         # directory too since lock is always saved as CoS lock.
27106         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27107         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27108         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27109         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27110         wait_delete_completed_mds
27111
27112         # run a loop without concurrent touch to measure rename duration.
27113         # only for test debug/robustness, NOT part of COS functional test.
27114         local start_time=$SECONDS
27115         for ((i = 0; i < total; i++)); do
27116                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27117                         > /dev/null
27118         done
27119         local baseline=$((SECONDS - start_time))
27120         echo "rename $total files without 'touch' took $baseline sec"
27121
27122         (
27123                 while true; do
27124                         touch $DIR/$tdir
27125                 done
27126         ) &
27127         local setattr_pid=$!
27128
27129         # rename files back to original name so unlinkmany works
27130         start_time=$SECONDS
27131         for ((i = 0; i < total; i++)); do
27132                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27133                         > /dev/null
27134         done
27135         local duration=$((SECONDS - start_time))
27136
27137         kill -9 $setattr_pid
27138
27139         echo "rename $total files with 'touch' took $duration sec"
27140         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27141         (( duration <= max )) || error "rename took $duration > $max sec"
27142 }
27143 run_test 415 "lock revoke is not missing"
27144
27145 test_416() {
27146         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27147                 skip "Need server version at least 2.11.55"
27148
27149         # define OBD_FAIL_OSD_TXN_START    0x19a
27150         do_facet mds1 lctl set_param fail_loc=0x19a
27151
27152         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27153
27154         true
27155 }
27156 run_test 416 "transaction start failure won't cause system hung"
27157
27158 cleanup_417() {
27159         trap 0
27160         do_nodes $(comma_list $(mdts_nodes)) \
27161                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27162         do_nodes $(comma_list $(mdts_nodes)) \
27163                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27164         do_nodes $(comma_list $(mdts_nodes)) \
27165                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27166 }
27167
27168 test_417() {
27169         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27170         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27171                 skip "Need MDS version at least 2.11.56"
27172
27173         trap cleanup_417 RETURN EXIT
27174
27175         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27176         do_nodes $(comma_list $(mdts_nodes)) \
27177                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27178         $LFS migrate -m 0 $DIR/$tdir.1 &&
27179                 error "migrate dir $tdir.1 should fail"
27180
27181         do_nodes $(comma_list $(mdts_nodes)) \
27182                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27183         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27184                 error "create remote dir $tdir.2 should fail"
27185
27186         do_nodes $(comma_list $(mdts_nodes)) \
27187                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27188         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27189                 error "create striped dir $tdir.3 should fail"
27190         true
27191 }
27192 run_test 417 "disable remote dir, striped dir and dir migration"
27193
27194 # Checks that the outputs of df [-i] and lfs df [-i] match
27195 #
27196 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27197 check_lfs_df() {
27198         local dir=$2
27199         local inodes
27200         local df_out
27201         local lfs_df_out
27202         local count
27203         local passed=false
27204
27205         # blocks or inodes
27206         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27207
27208         for count in {1..100}; do
27209                 do_nodes "$CLIENTS" \
27210                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27211                 sync; sleep 0.2
27212
27213                 # read the lines of interest
27214                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27215                         error "df $inodes $dir | tail -n +2 failed"
27216                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27217                         error "lfs df $inodes $dir | grep summary: failed"
27218
27219                 # skip first substrings of each output as they are different
27220                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27221                 # compare the two outputs
27222                 passed=true
27223                 #  skip "available" on MDT until LU-13997 is fixed.
27224                 #for i in {1..5}; do
27225                 for i in 1 2 4 5; do
27226                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27227                 done
27228                 $passed && break
27229         done
27230
27231         if ! $passed; then
27232                 df -P $inodes $dir
27233                 echo
27234                 lfs df $inodes $dir
27235                 error "df and lfs df $1 output mismatch: "      \
27236                       "df ${inodes}: ${df_out[*]}, "            \
27237                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27238         fi
27239 }
27240
27241 test_418() {
27242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27243
27244         local dir=$DIR/$tdir
27245         local numfiles=$((RANDOM % 4096 + 2))
27246         local numblocks=$((RANDOM % 256 + 1))
27247
27248         wait_delete_completed
27249         test_mkdir $dir
27250
27251         # check block output
27252         check_lfs_df blocks $dir
27253         # check inode output
27254         check_lfs_df inodes $dir
27255
27256         # create a single file and retest
27257         echo "Creating a single file and testing"
27258         createmany -o $dir/$tfile- 1 &>/dev/null ||
27259                 error "creating 1 file in $dir failed"
27260         check_lfs_df blocks $dir
27261         check_lfs_df inodes $dir
27262
27263         # create a random number of files
27264         echo "Creating $((numfiles - 1)) files and testing"
27265         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27266                 error "creating $((numfiles - 1)) files in $dir failed"
27267
27268         # write a random number of blocks to the first test file
27269         echo "Writing $numblocks 4K blocks and testing"
27270         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27271                 count=$numblocks &>/dev/null ||
27272                 error "dd to $dir/${tfile}-0 failed"
27273
27274         # retest
27275         check_lfs_df blocks $dir
27276         check_lfs_df inodes $dir
27277
27278         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27279                 error "unlinking $numfiles files in $dir failed"
27280 }
27281 run_test 418 "df and lfs df outputs match"
27282
27283 test_419()
27284 {
27285         local dir=$DIR/$tdir
27286
27287         mkdir -p $dir
27288         touch $dir/file
27289
27290         cancel_lru_locks mdc
27291
27292         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27293         $LCTL set_param fail_loc=0x1410
27294         cat $dir/file
27295         $LCTL set_param fail_loc=0
27296         rm -rf $dir
27297 }
27298 run_test 419 "Verify open file by name doesn't crash kernel"
27299
27300 test_420()
27301 {
27302         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27303                 skip "Need MDS version at least 2.12.53"
27304
27305         local SAVE_UMASK=$(umask)
27306         local dir=$DIR/$tdir
27307         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27308
27309         mkdir -p $dir
27310         umask 0000
27311         mkdir -m03777 $dir/testdir
27312         ls -dn $dir/testdir
27313         # Need to remove trailing '.' when SELinux is enabled
27314         local dirperms=$(ls -dn $dir/testdir |
27315                          awk '{ sub(/\.$/, "", $1); print $1}')
27316         [ $dirperms == "drwxrwsrwt" ] ||
27317                 error "incorrect perms on $dir/testdir"
27318
27319         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27320                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27321         ls -n $dir/testdir/testfile
27322         local fileperms=$(ls -n $dir/testdir/testfile |
27323                           awk '{ sub(/\.$/, "", $1); print $1}')
27324         [ $fileperms == "-rwxr-xr-x" ] ||
27325                 error "incorrect perms on $dir/testdir/testfile"
27326
27327         umask $SAVE_UMASK
27328 }
27329 run_test 420 "clear SGID bit on non-directories for non-members"
27330
27331 test_421a() {
27332         local cnt
27333         local fid1
27334         local fid2
27335
27336         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27337                 skip "Need MDS version at least 2.12.54"
27338
27339         test_mkdir $DIR/$tdir
27340         createmany -o $DIR/$tdir/f 3
27341         cnt=$(ls -1 $DIR/$tdir | wc -l)
27342         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27343
27344         fid1=$(lfs path2fid $DIR/$tdir/f1)
27345         fid2=$(lfs path2fid $DIR/$tdir/f2)
27346         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27347
27348         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27349         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27350
27351         cnt=$(ls -1 $DIR/$tdir | wc -l)
27352         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27353
27354         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27355         createmany -o $DIR/$tdir/f 3
27356         cnt=$(ls -1 $DIR/$tdir | wc -l)
27357         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27358
27359         fid1=$(lfs path2fid $DIR/$tdir/f1)
27360         fid2=$(lfs path2fid $DIR/$tdir/f2)
27361         echo "remove using fsname $FSNAME"
27362         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27363
27364         cnt=$(ls -1 $DIR/$tdir | wc -l)
27365         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27366 }
27367 run_test 421a "simple rm by fid"
27368
27369 test_421b() {
27370         local cnt
27371         local FID1
27372         local FID2
27373
27374         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27375                 skip "Need MDS version at least 2.12.54"
27376
27377         test_mkdir $DIR/$tdir
27378         createmany -o $DIR/$tdir/f 3
27379         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27380         MULTIPID=$!
27381
27382         FID1=$(lfs path2fid $DIR/$tdir/f1)
27383         FID2=$(lfs path2fid $DIR/$tdir/f2)
27384         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27385
27386         kill -USR1 $MULTIPID
27387         wait
27388
27389         cnt=$(ls $DIR/$tdir | wc -l)
27390         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27391 }
27392 run_test 421b "rm by fid on open file"
27393
27394 test_421c() {
27395         local cnt
27396         local FIDS
27397
27398         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27399                 skip "Need MDS version at least 2.12.54"
27400
27401         test_mkdir $DIR/$tdir
27402         createmany -o $DIR/$tdir/f 3
27403         touch $DIR/$tdir/$tfile
27404         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27405         cnt=$(ls -1 $DIR/$tdir | wc -l)
27406         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27407
27408         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27409         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27410
27411         cnt=$(ls $DIR/$tdir | wc -l)
27412         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27413 }
27414 run_test 421c "rm by fid against hardlinked files"
27415
27416 test_421d() {
27417         local cnt
27418         local FIDS
27419
27420         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27421                 skip "Need MDS version at least 2.12.54"
27422
27423         test_mkdir $DIR/$tdir
27424         createmany -o $DIR/$tdir/f 4097
27425         cnt=$(ls -1 $DIR/$tdir | wc -l)
27426         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27427
27428         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27429         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27430
27431         cnt=$(ls $DIR/$tdir | wc -l)
27432         rm -rf $DIR/$tdir
27433         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27434 }
27435 run_test 421d "rmfid en masse"
27436
27437 test_421e() {
27438         local cnt
27439         local FID
27440
27441         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27442         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27443                 skip "Need MDS version at least 2.12.54"
27444
27445         mkdir -p $DIR/$tdir
27446         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27447         createmany -o $DIR/$tdir/striped_dir/f 512
27448         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27449         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27450
27451         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27452                 sed "s/[/][^:]*://g")
27453         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27454
27455         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27456         rm -rf $DIR/$tdir
27457         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27458 }
27459 run_test 421e "rmfid in DNE"
27460
27461 test_421f() {
27462         local cnt
27463         local FID
27464
27465         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27466                 skip "Need MDS version at least 2.12.54"
27467
27468         test_mkdir $DIR/$tdir
27469         touch $DIR/$tdir/f
27470         cnt=$(ls -1 $DIR/$tdir | wc -l)
27471         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27472
27473         FID=$(lfs path2fid $DIR/$tdir/f)
27474         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27475         # rmfid should fail
27476         cnt=$(ls -1 $DIR/$tdir | wc -l)
27477         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27478
27479         chmod a+rw $DIR/$tdir
27480         ls -la $DIR/$tdir
27481         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27482         # rmfid should fail
27483         cnt=$(ls -1 $DIR/$tdir | wc -l)
27484         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27485
27486         rm -f $DIR/$tdir/f
27487         $RUNAS touch $DIR/$tdir/f
27488         FID=$(lfs path2fid $DIR/$tdir/f)
27489         echo "rmfid as root"
27490         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27491         cnt=$(ls -1 $DIR/$tdir | wc -l)
27492         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27493
27494         rm -f $DIR/$tdir/f
27495         $RUNAS touch $DIR/$tdir/f
27496         cnt=$(ls -1 $DIR/$tdir | wc -l)
27497         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27498         FID=$(lfs path2fid $DIR/$tdir/f)
27499         # rmfid w/o user_fid2path mount option should fail
27500         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27501         cnt=$(ls -1 $DIR/$tdir | wc -l)
27502         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27503
27504         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27505         stack_trap "rmdir $tmpdir"
27506         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27507                 error "failed to mount client'"
27508         stack_trap "umount_client $tmpdir"
27509
27510         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27511         # rmfid should succeed
27512         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27513         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27514
27515         # rmfid shouldn't allow to remove files due to dir's permission
27516         chmod a+rwx $tmpdir/$tdir
27517         touch $tmpdir/$tdir/f
27518         ls -la $tmpdir/$tdir
27519         FID=$(lfs path2fid $tmpdir/$tdir/f)
27520         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27521         return 0
27522 }
27523 run_test 421f "rmfid checks permissions"
27524
27525 test_421g() {
27526         local cnt
27527         local FIDS
27528
27529         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27530         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27531                 skip "Need MDS version at least 2.12.54"
27532
27533         mkdir -p $DIR/$tdir
27534         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27535         createmany -o $DIR/$tdir/striped_dir/f 512
27536         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27537         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27538
27539         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27540                 sed "s/[/][^:]*://g")
27541
27542         rm -f $DIR/$tdir/striped_dir/f1*
27543         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27544         removed=$((512 - cnt))
27545
27546         # few files have been just removed, so we expect
27547         # rmfid to fail on their fids
27548         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27549         [ $removed != $errors ] && error "$errors != $removed"
27550
27551         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27552         rm -rf $DIR/$tdir
27553         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27554 }
27555 run_test 421g "rmfid to return errors properly"
27556
27557 test_421h() {
27558         local mount_other
27559         local mount_ret
27560         local rmfid_ret
27561         local old_fid
27562         local fidA
27563         local fidB
27564         local fidC
27565         local fidD
27566
27567         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27568                 skip "Need MDS version at least 2.15.53"
27569
27570         test_mkdir $DIR/$tdir
27571         test_mkdir $DIR/$tdir/subdir
27572         touch $DIR/$tdir/subdir/file0
27573         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27574         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27575         rm -f $DIR/$tdir/subdir/file0
27576         touch $DIR/$tdir/subdir/fileA
27577         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27578         echo File $DIR/$tdir/subdir/fileA FID $fidA
27579         touch $DIR/$tdir/subdir/fileB
27580         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27581         echo File $DIR/$tdir/subdir/fileB FID $fidB
27582         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27583         touch $DIR/$tdir/subdir/fileC
27584         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27585         echo File $DIR/$tdir/subdir/fileC FID $fidC
27586         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27587         touch $DIR/$tdir/fileD
27588         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27589         echo File $DIR/$tdir/fileD FID $fidD
27590
27591         # mount another client mount point with subdirectory mount
27592         export FILESET=/$tdir/subdir
27593         mount_other=${MOUNT}_other
27594         mount_client $mount_other ${MOUNT_OPTS}
27595         mount_ret=$?
27596         export FILESET=""
27597         (( mount_ret == 0 )) || error "mount $mount_other failed"
27598
27599         echo Removing FIDs:
27600         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27601         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27602         rmfid_ret=$?
27603
27604         umount_client $mount_other || error "umount $mount_other failed"
27605
27606         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27607
27608         # fileA should have been deleted
27609         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27610
27611         # fileB should have been deleted
27612         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27613
27614         # fileC should not have been deleted, fid also exists outside of fileset
27615         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27616
27617         # fileD should not have been deleted, it exists outside of fileset
27618         stat $DIR/$tdir/fileD || error "fileD deleted"
27619 }
27620 run_test 421h "rmfid with fileset mount"
27621
27622 test_422() {
27623         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27624         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27625         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27626         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27627         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27628
27629         local amc=$(at_max_get client)
27630         local amo=$(at_max_get mds1)
27631         local timeout=`lctl get_param -n timeout`
27632
27633         at_max_set 0 client
27634         at_max_set 0 mds1
27635
27636 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27637         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27638                         fail_val=$(((2*timeout + 10)*1000))
27639         touch $DIR/$tdir/d3/file &
27640         sleep 2
27641 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27642         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27643                         fail_val=$((2*timeout + 5))
27644         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27645         local pid=$!
27646         sleep 1
27647         kill -9 $pid
27648         sleep $((2 * timeout))
27649         echo kill $pid
27650         kill -9 $pid
27651         lctl mark touch
27652         touch $DIR/$tdir/d2/file3
27653         touch $DIR/$tdir/d2/file4
27654         touch $DIR/$tdir/d2/file5
27655
27656         wait
27657         at_max_set $amc client
27658         at_max_set $amo mds1
27659
27660         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27661         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27662                 error "Watchdog is always throttled"
27663 }
27664 run_test 422 "kill a process with RPC in progress"
27665
27666 stat_test() {
27667     df -h $MOUNT &
27668     df -h $MOUNT &
27669     df -h $MOUNT &
27670     df -h $MOUNT &
27671     df -h $MOUNT &
27672     df -h $MOUNT &
27673 }
27674
27675 test_423() {
27676     local _stats
27677     # ensure statfs cache is expired
27678     sleep 2;
27679
27680     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27681     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27682
27683     return 0
27684 }
27685 run_test 423 "statfs should return a right data"
27686
27687 test_424() {
27688 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27689         $LCTL set_param fail_loc=0x80000522
27690         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27691         rm -f $DIR/$tfile
27692 }
27693 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27694
27695 test_425() {
27696         test_mkdir -c -1 $DIR/$tdir
27697         $LFS setstripe -c -1 $DIR/$tdir
27698
27699         lru_resize_disable "" 100
27700         stack_trap "lru_resize_enable" EXIT
27701
27702         sleep 5
27703
27704         for i in $(seq $((MDSCOUNT * 125))); do
27705                 local t=$DIR/$tdir/$tfile_$i
27706
27707                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27708                         error_noexit "Create file $t"
27709         done
27710         stack_trap "rm -rf $DIR/$tdir" EXIT
27711
27712         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27713                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27714                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27715
27716                 [ $lock_count -le $lru_size ] ||
27717                         error "osc lock count $lock_count > lru size $lru_size"
27718         done
27719
27720         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27721                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27722                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27723
27724                 [ $lock_count -le $lru_size ] ||
27725                         error "mdc lock count $lock_count > lru size $lru_size"
27726         done
27727 }
27728 run_test 425 "lock count should not exceed lru size"
27729
27730 test_426() {
27731         splice-test -r $DIR/$tfile
27732         splice-test -rd $DIR/$tfile
27733         splice-test $DIR/$tfile
27734         splice-test -d $DIR/$tfile
27735 }
27736 run_test 426 "splice test on Lustre"
27737
27738 test_427() {
27739         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27740         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27741                 skip "Need MDS version at least 2.12.4"
27742         local log
27743
27744         mkdir $DIR/$tdir
27745         mkdir $DIR/$tdir/1
27746         mkdir $DIR/$tdir/2
27747         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27748         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27749
27750         $LFS getdirstripe $DIR/$tdir/1/dir
27751
27752         #first setfattr for creating updatelog
27753         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27754
27755 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27756         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27757         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27758         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27759
27760         sleep 2
27761         fail mds2
27762         wait_recovery_complete mds2 $((2*TIMEOUT))
27763
27764         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27765         echo $log | grep "get update log failed" &&
27766                 error "update log corruption is detected" || true
27767 }
27768 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27769
27770 test_428() {
27771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27772         local cache_limit=$CACHE_MAX
27773
27774         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27775         $LCTL set_param -n llite.*.max_cached_mb=64
27776
27777         mkdir $DIR/$tdir
27778         $LFS setstripe -c 1 $DIR/$tdir
27779         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27780         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27781         #test write
27782         for f in $(seq 4); do
27783                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27784         done
27785         wait
27786
27787         cancel_lru_locks osc
27788         # Test read
27789         for f in $(seq 4); do
27790                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27791         done
27792         wait
27793 }
27794 run_test 428 "large block size IO should not hang"
27795
27796 test_429() { # LU-7915 / LU-10948
27797         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27798         local testfile=$DIR/$tfile
27799         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27800         local new_flag=1
27801         local first_rpc
27802         local second_rpc
27803         local third_rpc
27804
27805         $LCTL get_param $ll_opencache_threshold_count ||
27806                 skip "client does not have opencache parameter"
27807
27808         set_opencache $new_flag
27809         stack_trap "restore_opencache"
27810         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27811                 error "enable opencache failed"
27812         touch $testfile
27813         # drop MDC DLM locks
27814         cancel_lru_locks mdc
27815         # clear MDC RPC stats counters
27816         $LCTL set_param $mdc_rpcstats=clear
27817
27818         # According to the current implementation, we need to run 3 times
27819         # open & close file to verify if opencache is enabled correctly.
27820         # 1st, RPCs are sent for lookup/open and open handle is released on
27821         #      close finally.
27822         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27823         #      so open handle won't be released thereafter.
27824         # 3rd, No RPC is sent out.
27825         $MULTIOP $testfile oc || error "multiop failed"
27826         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27827         echo "1st: $first_rpc RPCs in flight"
27828
27829         $MULTIOP $testfile oc || error "multiop failed"
27830         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27831         echo "2nd: $second_rpc RPCs in flight"
27832
27833         $MULTIOP $testfile oc || error "multiop failed"
27834         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27835         echo "3rd: $third_rpc RPCs in flight"
27836
27837         #verify no MDC RPC is sent
27838         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27839 }
27840 run_test 429 "verify if opencache flag on client side does work"
27841
27842 lseek_test_430() {
27843         local offset
27844         local file=$1
27845
27846         # data at [200K, 400K)
27847         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27848                 error "256K->512K dd fails"
27849         # data at [2M, 3M)
27850         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27851                 error "2M->3M dd fails"
27852         # data at [4M, 5M)
27853         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27854                 error "4M->5M dd fails"
27855         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27856         # start at first component hole #1
27857         printf "Seeking hole from 1000 ... "
27858         offset=$(lseek_test -l 1000 $file)
27859         echo $offset
27860         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27861         printf "Seeking data from 1000 ... "
27862         offset=$(lseek_test -d 1000 $file)
27863         echo $offset
27864         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27865
27866         # start at first component data block
27867         printf "Seeking hole from 300000 ... "
27868         offset=$(lseek_test -l 300000 $file)
27869         echo $offset
27870         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27871         printf "Seeking data from 300000 ... "
27872         offset=$(lseek_test -d 300000 $file)
27873         echo $offset
27874         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27875
27876         # start at the first component but beyond end of object size
27877         printf "Seeking hole from 1000000 ... "
27878         offset=$(lseek_test -l 1000000 $file)
27879         echo $offset
27880         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27881         printf "Seeking data from 1000000 ... "
27882         offset=$(lseek_test -d 1000000 $file)
27883         echo $offset
27884         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27885
27886         # start at second component stripe 2 (empty file)
27887         printf "Seeking hole from 1500000 ... "
27888         offset=$(lseek_test -l 1500000 $file)
27889         echo $offset
27890         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27891         printf "Seeking data from 1500000 ... "
27892         offset=$(lseek_test -d 1500000 $file)
27893         echo $offset
27894         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27895
27896         # start at second component stripe 1 (all data)
27897         printf "Seeking hole from 3000000 ... "
27898         offset=$(lseek_test -l 3000000 $file)
27899         echo $offset
27900         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27901         printf "Seeking data from 3000000 ... "
27902         offset=$(lseek_test -d 3000000 $file)
27903         echo $offset
27904         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27905
27906         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27907                 error "2nd dd fails"
27908         echo "Add data block at 640K...1280K"
27909
27910         # start at before new data block, in hole
27911         printf "Seeking hole from 600000 ... "
27912         offset=$(lseek_test -l 600000 $file)
27913         echo $offset
27914         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27915         printf "Seeking data from 600000 ... "
27916         offset=$(lseek_test -d 600000 $file)
27917         echo $offset
27918         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27919
27920         # start at the first component new data block
27921         printf "Seeking hole from 1000000 ... "
27922         offset=$(lseek_test -l 1000000 $file)
27923         echo $offset
27924         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27925         printf "Seeking data from 1000000 ... "
27926         offset=$(lseek_test -d 1000000 $file)
27927         echo $offset
27928         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27929
27930         # start at second component stripe 2, new data
27931         printf "Seeking hole from 1200000 ... "
27932         offset=$(lseek_test -l 1200000 $file)
27933         echo $offset
27934         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27935         printf "Seeking data from 1200000 ... "
27936         offset=$(lseek_test -d 1200000 $file)
27937         echo $offset
27938         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27939
27940         # start beyond file end
27941         printf "Using offset > filesize ... "
27942         lseek_test -l 4000000 $file && error "lseek should fail"
27943         printf "Using offset > filesize ... "
27944         lseek_test -d 4000000 $file && error "lseek should fail"
27945
27946         printf "Done\n\n"
27947 }
27948
27949 test_430a() {
27950         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27951                 skip "MDT does not support SEEK_HOLE"
27952
27953         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27954                 skip "OST does not support SEEK_HOLE"
27955
27956         local file=$DIR/$tdir/$tfile
27957
27958         mkdir -p $DIR/$tdir
27959
27960         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27961         # OST stripe #1 will have continuous data at [1M, 3M)
27962         # OST stripe #2 is empty
27963         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27964         lseek_test_430 $file
27965         rm $file
27966         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27967         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27968         lseek_test_430 $file
27969         rm $file
27970         $LFS setstripe -c2 -S 512K $file
27971         echo "Two stripes, stripe size 512K"
27972         lseek_test_430 $file
27973         rm $file
27974         # FLR with stale mirror
27975         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27976                        -N -c2 -S 1M $file
27977         echo "Mirrored file:"
27978         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27979         echo "Plain 2 stripes 1M"
27980         lseek_test_430 $file
27981         rm $file
27982 }
27983 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27984
27985 test_430b() {
27986         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27987                 skip "OST does not support SEEK_HOLE"
27988
27989         local offset
27990         local file=$DIR/$tdir/$tfile
27991
27992         mkdir -p $DIR/$tdir
27993         # Empty layout lseek should fail
27994         $MCREATE $file
27995         # seek from 0
27996         printf "Seeking hole from 0 ... "
27997         lseek_test -l 0 $file && error "lseek should fail"
27998         printf "Seeking data from 0 ... "
27999         lseek_test -d 0 $file && error "lseek should fail"
28000         rm $file
28001
28002         # 1M-hole file
28003         $LFS setstripe -E 1M -c2 -E eof $file
28004         $TRUNCATE $file 1048576
28005         printf "Seeking hole from 1000000 ... "
28006         offset=$(lseek_test -l 1000000 $file)
28007         echo $offset
28008         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28009         printf "Seeking data from 1000000 ... "
28010         lseek_test -d 1000000 $file && error "lseek should fail"
28011         rm $file
28012
28013         # full component followed by non-inited one
28014         $LFS setstripe -E 1M -c2 -E eof $file
28015         dd if=/dev/urandom of=$file bs=1M count=1
28016         printf "Seeking hole from 1000000 ... "
28017         offset=$(lseek_test -l 1000000 $file)
28018         echo $offset
28019         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28020         printf "Seeking hole from 1048576 ... "
28021         lseek_test -l 1048576 $file && error "lseek should fail"
28022         # init second component and truncate back
28023         echo "123" >> $file
28024         $TRUNCATE $file 1048576
28025         printf "Seeking hole from 1000000 ... "
28026         offset=$(lseek_test -l 1000000 $file)
28027         echo $offset
28028         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28029         printf "Seeking hole from 1048576 ... "
28030         lseek_test -l 1048576 $file && error "lseek should fail"
28031         # boundary checks for big values
28032         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28033         offset=$(lseek_test -d 0 $file.10g)
28034         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28035         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28036         offset=$(lseek_test -d 0 $file.100g)
28037         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28038         return 0
28039 }
28040 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28041
28042 test_430c() {
28043         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28044                 skip "OST does not support SEEK_HOLE"
28045
28046         local file=$DIR/$tdir/$tfile
28047         local start
28048
28049         mkdir -p $DIR/$tdir
28050         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28051
28052         # cp version 8.33+ prefers lseek over fiemap
28053         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28054                 start=$SECONDS
28055                 time cp $file /dev/null
28056                 (( SECONDS - start < 5 )) ||
28057                         error "cp: too long runtime $((SECONDS - start))"
28058
28059         fi
28060         # tar version 1.29+ supports SEEK_HOLE/DATA
28061         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28062                 start=$SECONDS
28063                 time tar cS $file - | cat > /dev/null
28064                 (( SECONDS - start < 5 )) ||
28065                         error "tar: too long runtime $((SECONDS - start))"
28066         fi
28067 }
28068 run_test 430c "lseek: external tools check"
28069
28070 test_431() { # LU-14187
28071         local file=$DIR/$tdir/$tfile
28072
28073         mkdir -p $DIR/$tdir
28074         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28075         dd if=/dev/urandom of=$file bs=4k count=1
28076         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28077         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28078         #define OBD_FAIL_OST_RESTART_IO 0x251
28079         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28080         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28081         cp $file $file.0
28082         cancel_lru_locks
28083         sync_all_data
28084         echo 3 > /proc/sys/vm/drop_caches
28085         diff  $file $file.0 || error "data diff"
28086 }
28087 run_test 431 "Restart transaction for IO"
28088
28089 cleanup_test_432() {
28090         do_facet mgs $LCTL nodemap_activate 0
28091         wait_nm_sync active
28092 }
28093
28094 test_432() {
28095         local tmpdir=$TMP/dir432
28096
28097         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28098                 skip "Need MDS version at least 2.14.52"
28099
28100         stack_trap cleanup_test_432 EXIT
28101         mkdir $DIR/$tdir
28102         mkdir $tmpdir
28103
28104         do_facet mgs $LCTL nodemap_activate 1
28105         wait_nm_sync active
28106         do_facet mgs $LCTL nodemap_modify --name default \
28107                 --property admin --value 1
28108         do_facet mgs $LCTL nodemap_modify --name default \
28109                 --property trusted --value 1
28110         cancel_lru_locks mdc
28111         wait_nm_sync default admin_nodemap
28112         wait_nm_sync default trusted_nodemap
28113
28114         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28115                grep -ci "Operation not permitted") -ne 0 ]; then
28116                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28117         fi
28118 }
28119 run_test 432 "mv dir from outside Lustre"
28120
28121 test_433() {
28122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28123
28124         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28125                 skip "inode cache not supported"
28126
28127         $LCTL set_param llite.*.inode_cache=0
28128         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28129
28130         local count=256
28131         local before
28132         local after
28133
28134         cancel_lru_locks mdc
28135         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28136         createmany -m $DIR/$tdir/f $count
28137         createmany -d $DIR/$tdir/d $count
28138         ls -l $DIR/$tdir > /dev/null
28139         stack_trap "rm -rf $DIR/$tdir"
28140
28141         before=$(num_objects)
28142         cancel_lru_locks mdc
28143         after=$(num_objects)
28144
28145         # sometimes even @before is less than 2 * count
28146         while (( before - after < count )); do
28147                 sleep 1
28148                 after=$(num_objects)
28149                 wait=$((wait + 1))
28150                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28151                 if (( wait > 60 )); then
28152                         error "inode slab grew from $before to $after"
28153                 fi
28154         done
28155
28156         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28157 }
28158 run_test 433 "ldlm lock cancel releases dentries and inodes"
28159
28160 test_434() {
28161         local file
28162         local getxattr_count
28163         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28164         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28165
28166         [[ $(getenforce) == "Disabled" ]] ||
28167                 skip "lsm selinux module have to be disabled for this test"
28168
28169         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28170                 error "fail to create $DIR/$tdir/ on MDT0000"
28171
28172         touch $DIR/$tdir/$tfile-{001..100}
28173
28174         # disable the xattr cache
28175         save_lustre_params client "llite.*.xattr_cache" > $p
28176         lctl set_param llite.*.xattr_cache=0
28177         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28178
28179         # clear clients mdc stats
28180         clear_stats $mdc_stat_param ||
28181                 error "fail to clear stats on mdc MDT0000"
28182
28183         for file in $DIR/$tdir/$tfile-{001..100}; do
28184                 getfattr -n security.selinux $file |&
28185                         grep -q "Operation not supported" ||
28186                         error "getxattr on security.selinux should return EOPNOTSUPP"
28187         done
28188
28189         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28190         (( getxattr_count < 100 )) ||
28191                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28192 }
28193 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28194
28195 test_440() {
28196         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28197                 source $LUSTRE/scripts/bash-completion/lustre
28198         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28199                 source /usr/share/bash-completion/completions/lustre
28200         else
28201                 skip "bash completion scripts not found"
28202         fi
28203
28204         local lctl_completions
28205         local lfs_completions
28206
28207         lctl_completions=$(_lustre_cmds lctl)
28208         if [[ ! $lctl_completions =~ "get_param" ]]; then
28209                 error "lctl bash completion failed"
28210         fi
28211
28212         lfs_completions=$(_lustre_cmds lfs)
28213         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28214                 error "lfs bash completion failed"
28215         fi
28216 }
28217 run_test 440 "bash completion for lfs, lctl"
28218
28219 prep_801() {
28220         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28221         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28222                 skip "Need server version at least 2.9.55"
28223
28224         start_full_debug_logging
28225 }
28226
28227 post_801() {
28228         stop_full_debug_logging
28229 }
28230
28231 barrier_stat() {
28232         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28233                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28234                            awk '/The barrier for/ { print $7 }')
28235                 echo $st
28236         else
28237                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28238                 echo \'$st\'
28239         fi
28240 }
28241
28242 barrier_expired() {
28243         local expired
28244
28245         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28246                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28247                           awk '/will be expired/ { print $7 }')
28248         else
28249                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28250         fi
28251
28252         echo $expired
28253 }
28254
28255 test_801a() {
28256         prep_801
28257
28258         echo "Start barrier_freeze at: $(date)"
28259         #define OBD_FAIL_BARRIER_DELAY          0x2202
28260         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28261         # Do not reduce barrier time - See LU-11873
28262         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28263
28264         sleep 2
28265         local b_status=$(barrier_stat)
28266         echo "Got barrier status at: $(date)"
28267         [ "$b_status" = "'freezing_p1'" ] ||
28268                 error "(1) unexpected barrier status $b_status"
28269
28270         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28271         wait
28272         b_status=$(barrier_stat)
28273         [ "$b_status" = "'frozen'" ] ||
28274                 error "(2) unexpected barrier status $b_status"
28275
28276         local expired=$(barrier_expired)
28277         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28278         sleep $((expired + 3))
28279
28280         b_status=$(barrier_stat)
28281         [ "$b_status" = "'expired'" ] ||
28282                 error "(3) unexpected barrier status $b_status"
28283
28284         # Do not reduce barrier time - See LU-11873
28285         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28286                 error "(4) fail to freeze barrier"
28287
28288         b_status=$(barrier_stat)
28289         [ "$b_status" = "'frozen'" ] ||
28290                 error "(5) unexpected barrier status $b_status"
28291
28292         echo "Start barrier_thaw at: $(date)"
28293         #define OBD_FAIL_BARRIER_DELAY          0x2202
28294         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28295         do_facet mgs $LCTL barrier_thaw $FSNAME &
28296
28297         sleep 2
28298         b_status=$(barrier_stat)
28299         echo "Got barrier status at: $(date)"
28300         [ "$b_status" = "'thawing'" ] ||
28301                 error "(6) unexpected barrier status $b_status"
28302
28303         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28304         wait
28305         b_status=$(barrier_stat)
28306         [ "$b_status" = "'thawed'" ] ||
28307                 error "(7) unexpected barrier status $b_status"
28308
28309         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28310         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28311         do_facet mgs $LCTL barrier_freeze $FSNAME
28312
28313         b_status=$(barrier_stat)
28314         [ "$b_status" = "'failed'" ] ||
28315                 error "(8) unexpected barrier status $b_status"
28316
28317         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28318         do_facet mgs $LCTL barrier_thaw $FSNAME
28319
28320         post_801
28321 }
28322 run_test 801a "write barrier user interfaces and stat machine"
28323
28324 test_801b() {
28325         prep_801
28326
28327         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28328         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28329         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28330         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28331         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28332
28333         cancel_lru_locks mdc
28334
28335         # 180 seconds should be long enough
28336         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28337
28338         local b_status=$(barrier_stat)
28339         [ "$b_status" = "'frozen'" ] ||
28340                 error "(6) unexpected barrier status $b_status"
28341
28342         mkdir $DIR/$tdir/d0/d10 &
28343         mkdir_pid=$!
28344
28345         touch $DIR/$tdir/d1/f13 &
28346         touch_pid=$!
28347
28348         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28349         ln_pid=$!
28350
28351         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28352         mv_pid=$!
28353
28354         rm -f $DIR/$tdir/d4/f12 &
28355         rm_pid=$!
28356
28357         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28358
28359         # To guarantee taht the 'stat' is not blocked
28360         b_status=$(barrier_stat)
28361         [ "$b_status" = "'frozen'" ] ||
28362                 error "(8) unexpected barrier status $b_status"
28363
28364         # let above commands to run at background
28365         sleep 5
28366
28367         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28368         ps -p $touch_pid || error "(10) touch should be blocked"
28369         ps -p $ln_pid || error "(11) link should be blocked"
28370         ps -p $mv_pid || error "(12) rename should be blocked"
28371         ps -p $rm_pid || error "(13) unlink should be blocked"
28372
28373         b_status=$(barrier_stat)
28374         [ "$b_status" = "'frozen'" ] ||
28375                 error "(14) unexpected barrier status $b_status"
28376
28377         do_facet mgs $LCTL barrier_thaw $FSNAME
28378         b_status=$(barrier_stat)
28379         [ "$b_status" = "'thawed'" ] ||
28380                 error "(15) unexpected barrier status $b_status"
28381
28382         wait $mkdir_pid || error "(16) mkdir should succeed"
28383         wait $touch_pid || error "(17) touch should succeed"
28384         wait $ln_pid || error "(18) link should succeed"
28385         wait $mv_pid || error "(19) rename should succeed"
28386         wait $rm_pid || error "(20) unlink should succeed"
28387
28388         post_801
28389 }
28390 run_test 801b "modification will be blocked by write barrier"
28391
28392 test_801c() {
28393         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28394
28395         prep_801
28396
28397         stop mds2 || error "(1) Fail to stop mds2"
28398
28399         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28400
28401         local b_status=$(barrier_stat)
28402         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28403                 do_facet mgs $LCTL barrier_thaw $FSNAME
28404                 error "(2) unexpected barrier status $b_status"
28405         }
28406
28407         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28408                 error "(3) Fail to rescan barrier bitmap"
28409
28410         # Do not reduce barrier time - See LU-11873
28411         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28412
28413         b_status=$(barrier_stat)
28414         [ "$b_status" = "'frozen'" ] ||
28415                 error "(4) unexpected barrier status $b_status"
28416
28417         do_facet mgs $LCTL barrier_thaw $FSNAME
28418         b_status=$(barrier_stat)
28419         [ "$b_status" = "'thawed'" ] ||
28420                 error "(5) unexpected barrier status $b_status"
28421
28422         local devname=$(mdsdevname 2)
28423
28424         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28425
28426         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28427                 error "(7) Fail to rescan barrier bitmap"
28428
28429         post_801
28430 }
28431 run_test 801c "rescan barrier bitmap"
28432
28433 test_802b() {
28434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28435         remote_mds_nodsh && skip "remote MDS with nodsh"
28436
28437         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28438                 skip "readonly option not available"
28439
28440         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28441
28442         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28443                 error "(2) Fail to copy"
28444
28445         # write back all cached data before setting MDT to readonly
28446         cancel_lru_locks
28447         sync_all_data
28448
28449         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28450         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28451
28452         echo "Modify should be refused"
28453         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28454
28455         echo "Read should be allowed"
28456         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28457                 error "(7) Read should succeed under ro mode"
28458
28459         # disable readonly
28460         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28461 }
28462 run_test 802b "be able to set MDTs to readonly"
28463
28464 test_803a() {
28465         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28466         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28467                 skip "MDS needs to be newer than 2.10.54"
28468
28469         mkdir_on_mdt0 $DIR/$tdir
28470         # Create some objects on all MDTs to trigger related logs objects
28471         for idx in $(seq $MDSCOUNT); do
28472                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28473                         $DIR/$tdir/dir${idx} ||
28474                         error "Fail to create $DIR/$tdir/dir${idx}"
28475         done
28476
28477         wait_delete_completed # ensure old test cleanups are finished
28478         sleep 3
28479         echo "before create:"
28480         $LFS df -i $MOUNT
28481         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28482
28483         for i in {1..10}; do
28484                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28485                         error "Fail to create $DIR/$tdir/foo$i"
28486         done
28487
28488         # sync ZFS-on-MDS to refresh statfs data
28489         wait_zfs_commit mds1
28490         sleep 3
28491         echo "after create:"
28492         $LFS df -i $MOUNT
28493         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28494
28495         # allow for an llog to be cleaned up during the test
28496         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28497                 error "before ($before_used) + 10 > after ($after_used)"
28498
28499         for i in {1..10}; do
28500                 rm -rf $DIR/$tdir/foo$i ||
28501                         error "Fail to remove $DIR/$tdir/foo$i"
28502         done
28503
28504         # sync ZFS-on-MDS to refresh statfs data
28505         wait_zfs_commit mds1
28506         wait_delete_completed
28507         sleep 3 # avoid MDT return cached statfs
28508         echo "after unlink:"
28509         $LFS df -i $MOUNT
28510         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28511
28512         # allow for an llog to be created during the test
28513         [ $after_used -le $((before_used + 1)) ] ||
28514                 error "after ($after_used) > before ($before_used) + 1"
28515 }
28516 run_test 803a "verify agent object for remote object"
28517
28518 test_803b() {
28519         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28520         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28521                 skip "MDS needs to be newer than 2.13.56"
28522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28523
28524         for i in $(seq 0 $((MDSCOUNT - 1))); do
28525                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28526         done
28527
28528         local before=0
28529         local after=0
28530
28531         local tmp
28532
28533         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28534         for i in $(seq 0 $((MDSCOUNT - 1))); do
28535                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28536                         awk '/getattr/ { print $2 }')
28537                 before=$((before + tmp))
28538         done
28539         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28540         for i in $(seq 0 $((MDSCOUNT - 1))); do
28541                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28542                         awk '/getattr/ { print $2 }')
28543                 after=$((after + tmp))
28544         done
28545
28546         [ $before -eq $after ] || error "getattr count $before != $after"
28547 }
28548 run_test 803b "remote object can getattr from cache"
28549
28550 test_804() {
28551         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28552         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28553                 skip "MDS needs to be newer than 2.10.54"
28554         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28555
28556         mkdir -p $DIR/$tdir
28557         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28558                 error "Fail to create $DIR/$tdir/dir0"
28559
28560         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28561         local dev=$(mdsdevname 2)
28562
28563         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28564                 grep ${fid} || error "NOT found agent entry for dir0"
28565
28566         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28567                 error "Fail to create $DIR/$tdir/dir1"
28568
28569         touch $DIR/$tdir/dir1/foo0 ||
28570                 error "Fail to create $DIR/$tdir/dir1/foo0"
28571         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28572         local rc=0
28573
28574         for idx in $(seq $MDSCOUNT); do
28575                 dev=$(mdsdevname $idx)
28576                 do_facet mds${idx} \
28577                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28578                         grep ${fid} && rc=$idx
28579         done
28580
28581         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28582                 error "Fail to rename foo0 to foo1"
28583         if [ $rc -eq 0 ]; then
28584                 for idx in $(seq $MDSCOUNT); do
28585                         dev=$(mdsdevname $idx)
28586                         do_facet mds${idx} \
28587                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28588                         grep ${fid} && rc=$idx
28589                 done
28590         fi
28591
28592         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28593                 error "Fail to rename foo1 to foo2"
28594         if [ $rc -eq 0 ]; then
28595                 for idx in $(seq $MDSCOUNT); do
28596                         dev=$(mdsdevname $idx)
28597                         do_facet mds${idx} \
28598                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28599                         grep ${fid} && rc=$idx
28600                 done
28601         fi
28602
28603         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28604
28605         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28606                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28607         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28608                 error "Fail to rename foo2 to foo0"
28609         unlink $DIR/$tdir/dir1/foo0 ||
28610                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28611         rm -rf $DIR/$tdir/dir0 ||
28612                 error "Fail to rm $DIR/$tdir/dir0"
28613
28614         for idx in $(seq $MDSCOUNT); do
28615                 rc=0
28616
28617                 stop mds${idx}
28618                 dev=$(mdsdevname $idx)
28619                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28620                         rc=$?
28621                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28622                         error "mount mds$idx failed"
28623                 df $MOUNT > /dev/null 2>&1
28624
28625                 # e2fsck should not return error
28626                 [ $rc -eq 0 ] ||
28627                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28628         done
28629 }
28630 run_test 804 "verify agent entry for remote entry"
28631
28632 cleanup_805() {
28633         do_facet $SINGLEMDS zfs set quota=$old $fsset
28634         unlinkmany $DIR/$tdir/f- 1000000
28635         trap 0
28636 }
28637
28638 test_805() {
28639         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28640         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28641         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28642                 skip "netfree not implemented before 0.7"
28643         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28644                 skip "Need MDS version at least 2.10.57"
28645
28646         local fsset
28647         local freekb
28648         local usedkb
28649         local old
28650         local quota
28651         local pref="osd-zfs.$FSNAME-MDT0000."
28652
28653         # limit available space on MDS dataset to meet nospace issue
28654         # quickly. then ZFS 0.7.2 can use reserved space if asked
28655         # properly (using netfree flag in osd_declare_destroy()
28656         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28657         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28658                 gawk '{print $3}')
28659         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28660         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28661         let "usedkb=usedkb-freekb"
28662         let "freekb=freekb/2"
28663         if let "freekb > 5000"; then
28664                 let "freekb=5000"
28665         fi
28666         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28667         trap cleanup_805 EXIT
28668         mkdir_on_mdt0 $DIR/$tdir
28669         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28670                 error "Can't set PFL layout"
28671         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28672         rm -rf $DIR/$tdir || error "not able to remove"
28673         do_facet $SINGLEMDS zfs set quota=$old $fsset
28674         trap 0
28675 }
28676 run_test 805 "ZFS can remove from full fs"
28677
28678 # Size-on-MDS test
28679 check_lsom_data()
28680 {
28681         local file=$1
28682         local expect=$(stat -c %s $file)
28683
28684         check_lsom_size $1 $expect
28685
28686         local blocks=$($LFS getsom -b $file)
28687         expect=$(stat -c %b $file)
28688         [[ $blocks == $expect ]] ||
28689                 error "$file expected blocks: $expect, got: $blocks"
28690 }
28691
28692 check_lsom_size()
28693 {
28694         local size
28695         local expect=$2
28696
28697         cancel_lru_locks mdc
28698
28699         size=$($LFS getsom -s $1)
28700         [[ $size == $expect ]] ||
28701                 error "$file expected size: $expect, got: $size"
28702 }
28703
28704 test_806() {
28705         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28706                 skip "Need MDS version at least 2.11.52"
28707
28708         local bs=1048576
28709
28710         touch $DIR/$tfile || error "touch $tfile failed"
28711
28712         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28713         save_lustre_params client "llite.*.xattr_cache" > $save
28714         lctl set_param llite.*.xattr_cache=0
28715         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28716
28717         # single-threaded write
28718         echo "Test SOM for single-threaded write"
28719         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28720                 error "write $tfile failed"
28721         check_lsom_size $DIR/$tfile $bs
28722
28723         local num=32
28724         local size=$(($num * $bs))
28725         local offset=0
28726         local i
28727
28728         echo "Test SOM for single client multi-threaded($num) write"
28729         $TRUNCATE $DIR/$tfile 0
28730         for ((i = 0; i < $num; i++)); do
28731                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28732                 local pids[$i]=$!
28733                 offset=$((offset + $bs))
28734         done
28735         for (( i=0; i < $num; i++ )); do
28736                 wait ${pids[$i]}
28737         done
28738         check_lsom_size $DIR/$tfile $size
28739
28740         $TRUNCATE $DIR/$tfile 0
28741         for ((i = 0; i < $num; i++)); do
28742                 offset=$((offset - $bs))
28743                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28744                 local pids[$i]=$!
28745         done
28746         for (( i=0; i < $num; i++ )); do
28747                 wait ${pids[$i]}
28748         done
28749         check_lsom_size $DIR/$tfile $size
28750
28751         # multi-client writes
28752         num=$(get_node_count ${CLIENTS//,/ })
28753         size=$(($num * $bs))
28754         offset=0
28755         i=0
28756
28757         echo "Test SOM for multi-client ($num) writes"
28758         $TRUNCATE $DIR/$tfile 0
28759         for client in ${CLIENTS//,/ }; do
28760                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28761                 local pids[$i]=$!
28762                 i=$((i + 1))
28763                 offset=$((offset + $bs))
28764         done
28765         for (( i=0; i < $num; i++ )); do
28766                 wait ${pids[$i]}
28767         done
28768         check_lsom_size $DIR/$tfile $offset
28769
28770         i=0
28771         $TRUNCATE $DIR/$tfile 0
28772         for client in ${CLIENTS//,/ }; do
28773                 offset=$((offset - $bs))
28774                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28775                 local pids[$i]=$!
28776                 i=$((i + 1))
28777         done
28778         for (( i=0; i < $num; i++ )); do
28779                 wait ${pids[$i]}
28780         done
28781         check_lsom_size $DIR/$tfile $size
28782
28783         # verify truncate
28784         echo "Test SOM for truncate"
28785         $TRUNCATE $DIR/$tfile 1048576
28786         check_lsom_size $DIR/$tfile 1048576
28787         $TRUNCATE $DIR/$tfile 1234
28788         check_lsom_size $DIR/$tfile 1234
28789
28790         # verify SOM blocks count
28791         echo "Verify SOM block count"
28792         $TRUNCATE $DIR/$tfile 0
28793         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28794                 error "failed to write file $tfile"
28795         check_lsom_data $DIR/$tfile
28796 }
28797 run_test 806 "Verify Lazy Size on MDS"
28798
28799 test_807() {
28800         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28801         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28802                 skip "Need MDS version at least 2.11.52"
28803
28804         # Registration step
28805         changelog_register || error "changelog_register failed"
28806         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28807         changelog_users $SINGLEMDS | grep -q $cl_user ||
28808                 error "User $cl_user not found in changelog_users"
28809
28810         rm -rf $DIR/$tdir || error "rm $tdir failed"
28811         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28812         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28813         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28814         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28815                 error "truncate $tdir/trunc failed"
28816
28817         local bs=1048576
28818         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28819                 error "write $tfile failed"
28820
28821         # multi-client wirtes
28822         local num=$(get_node_count ${CLIENTS//,/ })
28823         local offset=0
28824         local i=0
28825
28826         echo "Test SOM for multi-client ($num) writes"
28827         touch $DIR/$tfile || error "touch $tfile failed"
28828         $TRUNCATE $DIR/$tfile 0
28829         for client in ${CLIENTS//,/ }; do
28830                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28831                 local pids[$i]=$!
28832                 i=$((i + 1))
28833                 offset=$((offset + $bs))
28834         done
28835         for (( i=0; i < $num; i++ )); do
28836                 wait ${pids[$i]}
28837         done
28838
28839         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28840         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28841         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28842         check_lsom_data $DIR/$tdir/trunc
28843         check_lsom_data $DIR/$tdir/single_dd
28844         check_lsom_data $DIR/$tfile
28845
28846         rm -rf $DIR/$tdir
28847         # Deregistration step
28848         changelog_deregister || error "changelog_deregister failed"
28849 }
28850 run_test 807 "verify LSOM syncing tool"
28851
28852 check_som_nologged()
28853 {
28854         local lines=$($LFS changelog $FSNAME-MDT0000 |
28855                 grep 'x=trusted.som' | wc -l)
28856         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28857 }
28858
28859 test_808() {
28860         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28861                 skip "Need MDS version at least 2.11.55"
28862
28863         # Registration step
28864         changelog_register || error "changelog_register failed"
28865
28866         touch $DIR/$tfile || error "touch $tfile failed"
28867         check_som_nologged
28868
28869         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28870                 error "write $tfile failed"
28871         check_som_nologged
28872
28873         $TRUNCATE $DIR/$tfile 1234
28874         check_som_nologged
28875
28876         $TRUNCATE $DIR/$tfile 1048576
28877         check_som_nologged
28878
28879         # Deregistration step
28880         changelog_deregister || error "changelog_deregister failed"
28881 }
28882 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28883
28884 check_som_nodata()
28885 {
28886         $LFS getsom $1
28887         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28888 }
28889
28890 test_809() {
28891         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28892                 skip "Need MDS version at least 2.11.56"
28893
28894         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28895                 error "failed to create DoM-only file $DIR/$tfile"
28896         touch $DIR/$tfile || error "touch $tfile failed"
28897         check_som_nodata $DIR/$tfile
28898
28899         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28900                 error "write $tfile failed"
28901         check_som_nodata $DIR/$tfile
28902
28903         $TRUNCATE $DIR/$tfile 1234
28904         check_som_nodata $DIR/$tfile
28905
28906         $TRUNCATE $DIR/$tfile 4097
28907         check_som_nodata $DIR/$file
28908 }
28909 run_test 809 "Verify no SOM xattr store for DoM-only files"
28910
28911 test_810() {
28912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28913         $GSS && skip_env "could not run with gss"
28914         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28915                 skip "OST < 2.12.58 doesn't align checksum"
28916
28917         set_checksums 1
28918         stack_trap "set_checksums $ORIG_CSUM" EXIT
28919         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28920
28921         local csum
28922         local before
28923         local after
28924         for csum in $CKSUM_TYPES; do
28925                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28926                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28927                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28928                         eval set -- $i
28929                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28930                         before=$(md5sum $DIR/$tfile)
28931                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28932                         after=$(md5sum $DIR/$tfile)
28933                         [ "$before" == "$after" ] ||
28934                                 error "$csum: $before != $after bs=$1 seek=$2"
28935                 done
28936         done
28937 }
28938 run_test 810 "partial page writes on ZFS (LU-11663)"
28939
28940 test_812a() {
28941         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28942                 skip "OST < 2.12.51 doesn't support this fail_loc"
28943
28944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28945         # ensure ost1 is connected
28946         stat $DIR/$tfile >/dev/null || error "can't stat"
28947         wait_osc_import_state client ost1 FULL
28948         # no locks, no reqs to let the connection idle
28949         cancel_lru_locks osc
28950
28951         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28952 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28953         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28954         wait_osc_import_state client ost1 CONNECTING
28955         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28956
28957         stat $DIR/$tfile >/dev/null || error "can't stat file"
28958 }
28959 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28960
28961 test_812b() { # LU-12378
28962         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28963                 skip "OST < 2.12.51 doesn't support this fail_loc"
28964
28965         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28966         # ensure ost1 is connected
28967         stat $DIR/$tfile >/dev/null || error "can't stat"
28968         wait_osc_import_state client ost1 FULL
28969         # no locks, no reqs to let the connection idle
28970         cancel_lru_locks osc
28971
28972         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28973 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28974         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28975         wait_osc_import_state client ost1 CONNECTING
28976         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28977
28978         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28979         wait_osc_import_state client ost1 IDLE
28980 }
28981 run_test 812b "do not drop no resend request for idle connect"
28982
28983 test_812c() {
28984         local old
28985
28986         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28987
28988         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28989         $LFS getstripe $DIR/$tfile
28990         $LCTL set_param osc.*.idle_timeout=10
28991         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28992         # ensure ost1 is connected
28993         stat $DIR/$tfile >/dev/null || error "can't stat"
28994         wait_osc_import_state client ost1 FULL
28995         # no locks, no reqs to let the connection idle
28996         cancel_lru_locks osc
28997
28998 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28999         $LCTL set_param fail_loc=0x80000533
29000         sleep 15
29001         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29002 }
29003 run_test 812c "idle import vs lock enqueue race"
29004
29005 test_813() {
29006         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29007         [ -z "$file_heat_sav" ] && skip "no file heat support"
29008
29009         local readsample
29010         local writesample
29011         local readbyte
29012         local writebyte
29013         local readsample1
29014         local writesample1
29015         local readbyte1
29016         local writebyte1
29017
29018         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29019         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29020
29021         $LCTL set_param -n llite.*.file_heat=1
29022         echo "Turn on file heat"
29023         echo "Period second: $period_second, Decay percentage: $decay_pct"
29024
29025         echo "QQQQ" > $DIR/$tfile
29026         echo "QQQQ" > $DIR/$tfile
29027         echo "QQQQ" > $DIR/$tfile
29028         cat $DIR/$tfile > /dev/null
29029         cat $DIR/$tfile > /dev/null
29030         cat $DIR/$tfile > /dev/null
29031         cat $DIR/$tfile > /dev/null
29032
29033         local out=$($LFS heat_get $DIR/$tfile)
29034
29035         $LFS heat_get $DIR/$tfile
29036         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29037         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29038         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29039         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29040
29041         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29042         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29043         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29044         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29045
29046         sleep $((period_second + 3))
29047         echo "Sleep $((period_second + 3)) seconds..."
29048         # The recursion formula to calculate the heat of the file f is as
29049         # follow:
29050         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29051         # Where Hi is the heat value in the period between time points i*I and
29052         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29053         # to the weight of Ci.
29054         out=$($LFS heat_get $DIR/$tfile)
29055         $LFS heat_get $DIR/$tfile
29056         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29057         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29058         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29059         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29060
29061         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29062                 error "read sample ($readsample) is wrong"
29063         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29064                 error "write sample ($writesample) is wrong"
29065         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29066                 error "read bytes ($readbyte) is wrong"
29067         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29068                 error "write bytes ($writebyte) is wrong"
29069
29070         echo "QQQQ" > $DIR/$tfile
29071         echo "QQQQ" > $DIR/$tfile
29072         echo "QQQQ" > $DIR/$tfile
29073         cat $DIR/$tfile > /dev/null
29074         cat $DIR/$tfile > /dev/null
29075         cat $DIR/$tfile > /dev/null
29076         cat $DIR/$tfile > /dev/null
29077
29078         sleep $((period_second + 3))
29079         echo "Sleep $((period_second + 3)) seconds..."
29080
29081         out=$($LFS heat_get $DIR/$tfile)
29082         $LFS heat_get $DIR/$tfile
29083         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29084         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29085         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29086         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29087
29088         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29089                 4 * $decay_pct) / 100") -eq 1 ] ||
29090                 error "read sample ($readsample1) is wrong"
29091         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29092                 3 * $decay_pct) / 100") -eq 1 ] ||
29093                 error "write sample ($writesample1) is wrong"
29094         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29095                 20 * $decay_pct) / 100") -eq 1 ] ||
29096                 error "read bytes ($readbyte1) is wrong"
29097         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29098                 15 * $decay_pct) / 100") -eq 1 ] ||
29099                 error "write bytes ($writebyte1) is wrong"
29100
29101         echo "Turn off file heat for the file $DIR/$tfile"
29102         $LFS heat_set -o $DIR/$tfile
29103
29104         echo "QQQQ" > $DIR/$tfile
29105         echo "QQQQ" > $DIR/$tfile
29106         echo "QQQQ" > $DIR/$tfile
29107         cat $DIR/$tfile > /dev/null
29108         cat $DIR/$tfile > /dev/null
29109         cat $DIR/$tfile > /dev/null
29110         cat $DIR/$tfile > /dev/null
29111
29112         out=$($LFS heat_get $DIR/$tfile)
29113         $LFS heat_get $DIR/$tfile
29114         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29115         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29116         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29117         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29118
29119         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29120         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29121         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29122         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29123
29124         echo "Trun on file heat for the file $DIR/$tfile"
29125         $LFS heat_set -O $DIR/$tfile
29126
29127         echo "QQQQ" > $DIR/$tfile
29128         echo "QQQQ" > $DIR/$tfile
29129         echo "QQQQ" > $DIR/$tfile
29130         cat $DIR/$tfile > /dev/null
29131         cat $DIR/$tfile > /dev/null
29132         cat $DIR/$tfile > /dev/null
29133         cat $DIR/$tfile > /dev/null
29134
29135         out=$($LFS heat_get $DIR/$tfile)
29136         $LFS heat_get $DIR/$tfile
29137         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29138         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29139         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29140         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29141
29142         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29143         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29144         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29145         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29146
29147         $LFS heat_set -c $DIR/$tfile
29148         $LCTL set_param -n llite.*.file_heat=0
29149         echo "Turn off file heat support for the Lustre filesystem"
29150
29151         echo "QQQQ" > $DIR/$tfile
29152         echo "QQQQ" > $DIR/$tfile
29153         echo "QQQQ" > $DIR/$tfile
29154         cat $DIR/$tfile > /dev/null
29155         cat $DIR/$tfile > /dev/null
29156         cat $DIR/$tfile > /dev/null
29157         cat $DIR/$tfile > /dev/null
29158
29159         out=$($LFS heat_get $DIR/$tfile)
29160         $LFS heat_get $DIR/$tfile
29161         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29162         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29163         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29164         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29165
29166         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29167         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29168         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29169         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29170
29171         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29172         rm -f $DIR/$tfile
29173 }
29174 run_test 813 "File heat verfication"
29175
29176 test_814()
29177 {
29178         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29179         echo -n y >> $DIR/$tfile
29180         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29181         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29182 }
29183 run_test 814 "sparse cp works as expected (LU-12361)"
29184
29185 test_815()
29186 {
29187         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29188         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29189 }
29190 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29191
29192 test_816() {
29193         local ost1_imp=$(get_osc_import_name client ost1)
29194         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29195                          cut -d'.' -f2)
29196
29197         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29198         # ensure ost1 is connected
29199
29200         stat $DIR/$tfile >/dev/null || error "can't stat"
29201         wait_osc_import_state client ost1 FULL
29202         # no locks, no reqs to let the connection idle
29203         cancel_lru_locks osc
29204         lru_resize_disable osc
29205         local before
29206         local now
29207         before=$($LCTL get_param -n \
29208                  ldlm.namespaces.$imp_name.lru_size)
29209
29210         wait_osc_import_state client ost1 IDLE
29211         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29212         now=$($LCTL get_param -n \
29213               ldlm.namespaces.$imp_name.lru_size)
29214         [ $before == $now ] || error "lru_size changed $before != $now"
29215 }
29216 run_test 816 "do not reset lru_resize on idle reconnect"
29217
29218 cleanup_817() {
29219         umount $tmpdir
29220         exportfs -u localhost:$DIR/nfsexp
29221         rm -rf $DIR/nfsexp
29222 }
29223
29224 test_817() {
29225         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29226
29227         mkdir -p $DIR/nfsexp
29228         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29229                 error "failed to export nfs"
29230
29231         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29232         stack_trap cleanup_817 EXIT
29233
29234         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29235                 error "failed to mount nfs to $tmpdir"
29236
29237         cp /bin/true $tmpdir
29238         $DIR/nfsexp/true || error "failed to execute 'true' command"
29239 }
29240 run_test 817 "nfsd won't cache write lock for exec file"
29241
29242 test_818() {
29243         test_mkdir -i0 -c1 $DIR/$tdir
29244         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29245         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29246         stop $SINGLEMDS
29247
29248         # restore osp-syn threads
29249         stack_trap "fail $SINGLEMDS"
29250
29251         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29252         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29253         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29254                 error "start $SINGLEMDS failed"
29255         rm -rf $DIR/$tdir
29256
29257         local testid=$(echo $TESTNAME | tr '_' ' ')
29258
29259         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29260                 grep "run LFSCK" || error "run LFSCK is not suggested"
29261 }
29262 run_test 818 "unlink with failed llog"
29263
29264 test_819a() {
29265         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29266         cancel_lru_locks osc
29267         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29268         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29269         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29270         rm -f $TDIR/$tfile
29271 }
29272 run_test 819a "too big niobuf in read"
29273
29274 test_819b() {
29275         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29276         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29277         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29278         cancel_lru_locks osc
29279         sleep 1
29280         rm -f $TDIR/$tfile
29281 }
29282 run_test 819b "too big niobuf in write"
29283
29284
29285 function test_820_start_ost() {
29286         sleep 5
29287
29288         for num in $(seq $OSTCOUNT); do
29289                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29290         done
29291 }
29292
29293 test_820() {
29294         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29295
29296         mkdir $DIR/$tdir
29297         umount_client $MOUNT || error "umount failed"
29298         for num in $(seq $OSTCOUNT); do
29299                 stop ost$num
29300         done
29301
29302         # mount client with no active OSTs
29303         # so that the client can't initialize max LOV EA size
29304         # from OSC notifications
29305         mount_client $MOUNT || error "mount failed"
29306         # delay OST starting to keep this 0 max EA size for a while
29307         test_820_start_ost &
29308
29309         # create a directory on MDS2
29310         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29311                 error "Failed to create directory"
29312         # open intent should update default EA size
29313         # see mdc_update_max_ea_from_body()
29314         # notice this is the very first RPC to MDS2
29315         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29316         ret=$?
29317         echo $out
29318         # With SSK, this situation can lead to -EPERM being returned.
29319         # In that case, simply retry.
29320         if [ $ret -ne 0 ] && $SHARED_KEY; then
29321                 if echo "$out" | grep -q "not permitted"; then
29322                         cp /etc/services $DIR/$tdir/mds2
29323                         ret=$?
29324                 fi
29325         fi
29326         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29327 }
29328 run_test 820 "update max EA from open intent"
29329
29330 test_823() {
29331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29332         local OST_MAX_PRECREATE=20000
29333
29334         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29335                 skip "Need MDS version at least 2.14.56"
29336
29337         save_lustre_params mds1 \
29338                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29339         do_facet $SINGLEMDS "$LCTL set_param -n \
29340                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29341         do_facet $SINGLEMDS "$LCTL set_param -n \
29342                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29343
29344         stack_trap "restore_lustre_params < $p; rm $p"
29345
29346         do_facet $SINGLEMDS "$LCTL set_param -n \
29347                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29348
29349         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29350                       osp.$FSNAME-OST0000*MDT0000.create_count")
29351         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29352                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29353         local expect_count=$(((($max/2)/256) * 256))
29354
29355         log "setting create_count to 100200:"
29356         log " -result- count: $count with max: $max, expecting: $expect_count"
29357
29358         [[ $count -eq expect_count ]] ||
29359                 error "Create count not set to max precreate."
29360 }
29361 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29362
29363 test_831() {
29364         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29365                 skip "Need MDS version 2.14.56"
29366
29367         local sync_changes=$(do_facet $SINGLEMDS \
29368                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29369
29370         [ "$sync_changes" -gt 100 ] &&
29371                 skip "Sync changes $sync_changes > 100 already"
29372
29373         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29374
29375         $LFS mkdir -i 0 $DIR/$tdir
29376         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29377
29378         save_lustre_params mds1 \
29379                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29380         save_lustre_params mds1 \
29381                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29382
29383         do_facet mds1 "$LCTL set_param -n \
29384                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29385                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29386         stack_trap "restore_lustre_params < $p" EXIT
29387
29388         createmany -o $DIR/$tdir/f- 1000
29389         unlinkmany $DIR/$tdir/f- 1000 &
29390         local UNLINK_PID=$!
29391
29392         while sleep 1; do
29393                 sync_changes=$(do_facet mds1 \
29394                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29395                 # the check in the code is racy, fail the test
29396                 # if the value above the limit by 10.
29397                 [ $sync_changes -gt 110 ] && {
29398                         kill -2 $UNLINK_PID
29399                         wait
29400                         error "osp changes throttling failed, $sync_changes>110"
29401                 }
29402                 kill -0 $UNLINK_PID 2> /dev/null || break
29403         done
29404         wait
29405 }
29406 run_test 831 "throttling unlink/setattr queuing on OSP"
29407
29408 test_832() {
29409         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29410         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29411                 skip "Need MDS version 2.15.52+"
29412         is_rmentry_supported || skip "rm_entry not supported"
29413
29414         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29415         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29416         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29417                 error "mkdir remote_dir failed"
29418         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29419                 error "mkdir striped_dir failed"
29420         touch $DIR/$tdir/file || error "touch file failed"
29421         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29422         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29423 }
29424 run_test 832 "lfs rm_entry"
29425
29426 #
29427 # tests that do cleanup/setup should be run at the end
29428 #
29429
29430 test_900() {
29431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29432         local ls
29433
29434         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29435         $LCTL set_param fail_loc=0x903
29436
29437         cancel_lru_locks MGC
29438
29439         FAIL_ON_ERROR=true cleanup
29440         FAIL_ON_ERROR=true setup
29441 }
29442 run_test 900 "umount should not race with any mgc requeue thread"
29443
29444 # LUS-6253/LU-11185
29445 test_901() {
29446         local old
29447         local count
29448         local oldc
29449         local newc
29450         local olds
29451         local news
29452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29453
29454         # some get_param have a bug to handle dot in param name
29455         cancel_lru_locks MGC
29456         old=$(mount -t lustre | wc -l)
29457         # 1 config+sptlrpc
29458         # 2 params
29459         # 3 nodemap
29460         # 4 IR
29461         old=$((old * 4))
29462         oldc=0
29463         count=0
29464         while [ $old -ne $oldc ]; do
29465                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29466                 sleep 1
29467                 ((count++))
29468                 if [ $count -ge $TIMEOUT ]; then
29469                         error "too large timeout"
29470                 fi
29471         done
29472         umount_client $MOUNT || error "umount failed"
29473         mount_client $MOUNT || error "mount failed"
29474         cancel_lru_locks MGC
29475         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29476
29477         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29478
29479         return 0
29480 }
29481 run_test 901 "don't leak a mgc lock on client umount"
29482
29483 # LU-13377
29484 test_902() {
29485         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29486                 skip "client does not have LU-13377 fix"
29487         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29488         $LCTL set_param fail_loc=0x1415
29489         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29490         cancel_lru_locks osc
29491         rm -f $DIR/$tfile
29492 }
29493 run_test 902 "test short write doesn't hang lustre"
29494
29495 # LU-14711
29496 test_903() {
29497         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29498         echo "blah" > $DIR/${tfile}-2
29499         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29500         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29501         $LCTL set_param fail_loc=0x417 fail_val=20
29502
29503         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29504         sleep 1 # To start the destroy
29505         wait_destroy_complete 150 || error "Destroy taking too long"
29506         cat $DIR/$tfile > /dev/null || error "Evicted"
29507 }
29508 run_test 903 "Test long page discard does not cause evictions"
29509
29510 test_904() {
29511         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29512         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29513                 grep -q project || skip "skip project quota not supported"
29514
29515         local testfile="$DIR/$tdir/$tfile"
29516         local xattr="trusted.projid"
29517         local projid
29518         local mdts=$(comma_list $(mdts_nodes))
29519         local saved=$(do_facet mds1 $LCTL get_param -n \
29520                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29521
29522         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29523         stack_trap "do_nodes $mdts $LCTL set_param \
29524                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29525
29526         mkdir -p $DIR/$tdir
29527         touch $testfile
29528         #hide projid xattr on server
29529         $LFS project -p 1 $testfile ||
29530                 error "set $testfile project id failed"
29531         getfattr -m - $testfile | grep $xattr &&
29532                 error "do not show trusted.projid when disabled on server"
29533         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29534         #should be hidden when projid is 0
29535         $LFS project -p 0 $testfile ||
29536                 error "set $testfile project id failed"
29537         getfattr -m - $testfile | grep $xattr &&
29538                 error "do not show trusted.projid with project ID 0"
29539
29540         #still can getxattr explicitly
29541         projid=$(getfattr -n $xattr $testfile |
29542                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29543         [ $projid == "0" ] ||
29544                 error "projid expected 0 not $projid"
29545
29546         #set the projid via setxattr
29547         setfattr -n $xattr -v "1000" $testfile ||
29548                 error "setattr failed with $?"
29549         projid=($($LFS project $testfile))
29550         [ ${projid[0]} == "1000" ] ||
29551                 error "projid expected 1000 not $projid"
29552
29553         #check the new projid via getxattr
29554         $LFS project -p 1001 $testfile ||
29555                 error "set $testfile project id failed"
29556         getfattr -m - $testfile | grep $xattr ||
29557                 error "should show trusted.projid when project ID != 0"
29558         projid=$(getfattr -n $xattr $testfile |
29559                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29560         [ $projid == "1001" ] ||
29561                 error "projid expected 1001 not $projid"
29562
29563         #try to set invalid projid
29564         setfattr -n $xattr -v "4294967295" $testfile &&
29565                 error "set invalid projid should fail"
29566
29567         #remove the xattr means setting projid to 0
29568         setfattr -x $xattr $testfile ||
29569                 error "setfattr failed with $?"
29570         projid=($($LFS project $testfile))
29571         [ ${projid[0]} == "0" ] ||
29572                 error "projid expected 0 not $projid"
29573
29574         #should be hidden when parent has inherit flag and same projid
29575         $LFS project -srp 1002 $DIR/$tdir ||
29576                 error "set $tdir project id failed"
29577         getfattr -m - $testfile | grep $xattr &&
29578                 error "do not show trusted.projid with inherit flag"
29579
29580         #still can getxattr explicitly
29581         projid=$(getfattr -n $xattr $testfile |
29582                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29583         [ $projid == "1002" ] ||
29584                 error "projid expected 1002 not $projid"
29585 }
29586 run_test 904 "virtual project ID xattr"
29587
29588 # LU-8582
29589 test_905() {
29590         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29591                 skip "lustre < 2.8.54 does not support ladvise"
29592
29593         remote_ost_nodsh && skip "remote OST with nodsh"
29594         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29595
29596         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29597
29598         #define OBD_FAIL_OST_OPCODE 0x253
29599         # OST_LADVISE = 21
29600         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29601         $LFS ladvise -a willread $DIR/$tfile &&
29602                 error "unexpected success of ladvise with fault injection"
29603         $LFS ladvise -a willread $DIR/$tfile |&
29604                 grep -q "Operation not supported"
29605         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29606 }
29607 run_test 905 "bad or new opcode should not stuck client"
29608
29609 test_906() {
29610         grep -q io_uring_setup /proc/kallsyms ||
29611                 skip "Client OS does not support io_uring I/O engine"
29612         io_uring_probe || skip "kernel does not support io_uring fully"
29613         which fio || skip_env "no fio installed"
29614         fio --enghelp | grep -q io_uring ||
29615                 skip_env "fio does not support io_uring I/O engine"
29616
29617         local file=$DIR/$tfile
29618         local ioengine="io_uring"
29619         local numjobs=2
29620         local size=50M
29621
29622         fio --name=seqwrite --ioengine=$ioengine        \
29623                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29624                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29625                 error "fio seqwrite $file failed"
29626
29627         fio --name=seqread --ioengine=$ioengine \
29628                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29629                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29630                 error "fio seqread $file failed"
29631
29632         rm -f $file || error "rm -f $file failed"
29633 }
29634 run_test 906 "Simple test for io_uring I/O engine via fio"
29635
29636 complete $SECONDS
29637 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29638 check_and_cleanup_lustre
29639 if [ "$I_MOUNTED" != "yes" ]; then
29640         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29641 fi
29642 exit_status