Whamcloud - gitweb
LU-11912 ofd: reduce LUSTRE_DATA_SEQ_MAX_WIDTH
[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         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
2516
2517         test_mkdir -p $DIR/$tdir
2518         local setcount=$LOV_MAX_STRIPE_COUNT
2519
2520         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2521                 error "setstripe failed"
2522
2523         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2524         [ $count -eq $setcount ] ||
2525                 error "stripe count $count, should be $setcount"
2526
2527         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2528                 error "overstriped should be set in pattern"
2529
2530         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2531                 error "dd failed"
2532
2533         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2534 }
2535 run_test 27Cd "test maximum stripe count"
2536
2537 test_27Ce() {
2538         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2539                 skip "server does not support overstriping"
2540         test_mkdir -p $DIR/$tdir
2541
2542         pool_add $TESTNAME || error "Pool creation failed"
2543         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2544
2545         local setcount=8
2546
2547         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2548                 error "setstripe failed"
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Ce "test pool with overstriping"
2563
2564 test_27Cf() {
2565         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2566                 skip "server does not support overstriping"
2567         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2568                 skip_env "too many osts, skipping"
2569
2570         test_mkdir -p $DIR/$tdir
2571
2572         local setcount=$(($OSTCOUNT * 2))
2573         [ $setcount -lt 160 ] || large_xattr_enabled ||
2574                 skip_env "ea_inode feature disabled"
2575
2576         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2577                 error "setstripe failed"
2578
2579         echo 1 > $DIR/$tdir/$tfile
2580
2581         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2582         [ $count -eq $setcount ] ||
2583                 error "stripe count $count, should be $setcount"
2584
2585         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2586                 error "overstriped should be set in pattern"
2587
2588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2589                 error "dd failed"
2590
2591         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2592 }
2593 run_test 27Cf "test default inheritance with overstriping"
2594
2595 test_27D() {
2596         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2597         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2598         remote_mds_nodsh && skip "remote MDS with nodsh"
2599
2600         local POOL=${POOL:-testpool}
2601         local first_ost=0
2602         local last_ost=$(($OSTCOUNT - 1))
2603         local ost_step=1
2604         local ost_list=$(seq $first_ost $ost_step $last_ost)
2605         local ost_range="$first_ost $last_ost $ost_step"
2606
2607         test_mkdir $DIR/$tdir
2608         pool_add $POOL || error "pool_add failed"
2609         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2610
2611         local skip27D
2612         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2613                 skip27D+="-s 29"
2614         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2615                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2616                         skip27D+=" -s 30,31"
2617         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2618           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2619                 skip27D+=" -s 32,33"
2620         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2621                 skip27D+=" -s 34"
2622         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2623                 error "llapi_layout_test failed"
2624
2625         destroy_test_pools || error "destroy test pools failed"
2626 }
2627 run_test 27D "validate llapi_layout API"
2628
2629 # Verify that default_easize is increased from its initial value after
2630 # accessing a widely striped file.
2631 test_27E() {
2632         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2633         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2634                 skip "client does not have LU-3338 fix"
2635
2636         # 72 bytes is the minimum space required to store striping
2637         # information for a file striped across one OST:
2638         # (sizeof(struct lov_user_md_v3) +
2639         #  sizeof(struct lov_user_ost_data_v1))
2640         local min_easize=72
2641         $LCTL set_param -n llite.*.default_easize $min_easize ||
2642                 error "lctl set_param failed"
2643         local easize=$($LCTL get_param -n llite.*.default_easize)
2644
2645         [ $easize -eq $min_easize ] ||
2646                 error "failed to set default_easize"
2647
2648         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2649                 error "setstripe failed"
2650         # In order to ensure stat() call actually talks to MDS we need to
2651         # do something drastic to this file to shake off all lock, e.g.
2652         # rename it (kills lookup lock forcing cache cleaning)
2653         mv $DIR/$tfile $DIR/${tfile}-1
2654         ls -l $DIR/${tfile}-1
2655         rm $DIR/${tfile}-1
2656
2657         easize=$($LCTL get_param -n llite.*.default_easize)
2658
2659         [ $easize -gt $min_easize ] ||
2660                 error "default_easize not updated"
2661 }
2662 run_test 27E "check that default extended attribute size properly increases"
2663
2664 test_27F() { # LU-5346/LU-7975
2665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2666         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2667         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2668                 skip "Need MDS version at least 2.8.51"
2669         remote_ost_nodsh && skip "remote OST with nodsh"
2670
2671         test_mkdir $DIR/$tdir
2672         rm -f $DIR/$tdir/f0
2673         $LFS setstripe -c 2 $DIR/$tdir
2674
2675         # stop all OSTs to reproduce situation for LU-7975 ticket
2676         for num in $(seq $OSTCOUNT); do
2677                 stop ost$num
2678         done
2679
2680         # open/create f0 with O_LOV_DELAY_CREATE
2681         # truncate f0 to a non-0 size
2682         # close
2683         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2684
2685         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2686         # open/write it again to force delayed layout creation
2687         cat /etc/hosts > $DIR/$tdir/f0 &
2688         catpid=$!
2689
2690         # restart OSTs
2691         for num in $(seq $OSTCOUNT); do
2692                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2693                         error "ost$num failed to start"
2694         done
2695
2696         wait $catpid || error "cat failed"
2697
2698         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2699         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2700                 error "wrong stripecount"
2701
2702 }
2703 run_test 27F "Client resend delayed layout creation with non-zero size"
2704
2705 test_27G() { #LU-10629
2706         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2707                 skip "Need MDS version at least 2.11.51"
2708         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2709         remote_mds_nodsh && skip "remote MDS with nodsh"
2710         local POOL=${POOL:-testpool}
2711         local ostrange="0 0 1"
2712
2713         test_mkdir $DIR/$tdir
2714         touch $DIR/$tdir/$tfile.nopool
2715         pool_add $POOL || error "pool_add failed"
2716         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2717         $LFS setstripe -p $POOL $DIR/$tdir
2718
2719         local pool=$($LFS getstripe -p $DIR/$tdir)
2720
2721         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2722         touch $DIR/$tdir/$tfile.default
2723         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2724         $LFS find $DIR/$tdir -type f --pool $POOL
2725         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2726         [[ "$found" == "2" ]] ||
2727                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2728
2729         $LFS setstripe -d $DIR/$tdir
2730
2731         pool=$($LFS getstripe -p -d $DIR/$tdir)
2732
2733         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2734 }
2735 run_test 27G "Clear OST pool from stripe"
2736
2737 test_27H() {
2738         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2739                 skip "Need MDS version newer than 2.11.54"
2740         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2741         test_mkdir $DIR/$tdir
2742         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2743         touch $DIR/$tdir/$tfile
2744         $LFS getstripe -c $DIR/$tdir/$tfile
2745         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2746                 error "two-stripe file doesn't have two stripes"
2747
2748         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2749         $LFS getstripe -y $DIR/$tdir/$tfile
2750         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2751              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2752                 error "expected l_ost_idx: [02]$ not matched"
2753
2754         # make sure ost list has been cleared
2755         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2756         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2757                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2758         touch $DIR/$tdir/f3
2759         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2760 }
2761 run_test 27H "Set specific OSTs stripe"
2762
2763 test_27I() {
2764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2766         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2767                 skip "Need MDS version newer than 2.12.52"
2768         local pool=$TESTNAME
2769         local ostrange="1 1 1"
2770
2771         save_layout_restore_at_exit $MOUNT
2772         $LFS setstripe -c 2 -i 0 $MOUNT
2773         pool_add $pool || error "pool_add failed"
2774         pool_add_targets $pool $ostrange ||
2775                 error "pool_add_targets failed"
2776         test_mkdir $DIR/$tdir
2777         $LFS setstripe -p $pool $DIR/$tdir
2778         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2779         $LFS getstripe $DIR/$tdir/$tfile
2780 }
2781 run_test 27I "check that root dir striping does not break parent dir one"
2782
2783 test_27J() {
2784         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2785                 skip "Need MDS version newer than 2.12.51"
2786
2787         test_mkdir $DIR/$tdir
2788         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2789         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2790
2791         # create foreign file (raw way)
2792         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2793                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2794
2795         ! $LFS setstripe --foreign --flags foo \
2796                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2797                         error "creating $tfile with '--flags foo' should fail"
2798
2799         ! $LFS setstripe --foreign --flags 0xffffffff \
2800                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2801                         error "creating $tfile w/ 0xffffffff flags should fail"
2802
2803         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2804                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2805
2806         # verify foreign file (raw way)
2807         parse_foreign_file -f $DIR/$tdir/$tfile |
2808                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2810         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2811                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2812         parse_foreign_file -f $DIR/$tdir/$tfile |
2813                 grep "lov_foreign_size: 73" ||
2814                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2815         parse_foreign_file -f $DIR/$tdir/$tfile |
2816                 grep "lov_foreign_type: 1" ||
2817                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2818         parse_foreign_file -f $DIR/$tdir/$tfile |
2819                 grep "lov_foreign_flags: 0x0000DA08" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2821         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2822                 grep "lov_foreign_value: 0x" |
2823                 sed -e 's/lov_foreign_value: 0x//')
2824         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2825         [[ $lov = ${lov2// /} ]] ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2827
2828         # create foreign file (lfs + API)
2829         $LFS setstripe --foreign=none --flags 0xda08 \
2830                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2831                 error "$DIR/$tdir/${tfile}2: create failed"
2832
2833         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2834                 grep "lfm_magic:.*0x0BD70BD0" ||
2835                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2836         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2837         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2838                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2839         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2840                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2841         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2842                 grep "lfm_flags:.*0x0000DA08" ||
2843                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2844         $LFS getstripe $DIR/$tdir/${tfile}2 |
2845                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2846                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2847
2848         # modify striping should fail
2849         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2850                 error "$DIR/$tdir/$tfile: setstripe should fail"
2851         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2852                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2853
2854         # R/W should fail
2855         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2856         cat $DIR/$tdir/${tfile}2 &&
2857                 error "$DIR/$tdir/${tfile}2: read should fail"
2858         cat /etc/passwd > $DIR/$tdir/$tfile &&
2859                 error "$DIR/$tdir/$tfile: write should fail"
2860         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2861                 error "$DIR/$tdir/${tfile}2: write should fail"
2862
2863         # chmod should work
2864         chmod 222 $DIR/$tdir/$tfile ||
2865                 error "$DIR/$tdir/$tfile: chmod failed"
2866         chmod 222 $DIR/$tdir/${tfile}2 ||
2867                 error "$DIR/$tdir/${tfile}2: chmod failed"
2868
2869         # chown should work
2870         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2871                 error "$DIR/$tdir/$tfile: chown failed"
2872         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2873                 error "$DIR/$tdir/${tfile}2: chown failed"
2874
2875         # rename should work
2876         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2877                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2878         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2879                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2880
2881         #remove foreign file
2882         rm $DIR/$tdir/${tfile}.new ||
2883                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2884         rm $DIR/$tdir/${tfile}2.new ||
2885                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2886 }
2887 run_test 27J "basic ops on file with foreign LOV"
2888
2889 test_27K() {
2890         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2891                 skip "Need MDS version newer than 2.12.49"
2892
2893         test_mkdir $DIR/$tdir
2894         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2895         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2896
2897         # create foreign dir (raw way)
2898         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2899                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2900
2901         ! $LFS setdirstripe --foreign --flags foo \
2902                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2903                         error "creating $tdir with '--flags foo' should fail"
2904
2905         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2906                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2907                         error "creating $tdir w/ 0xffffffff flags should fail"
2908
2909         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2910                 error "create_foreign_dir FAILED"
2911
2912         # verify foreign dir (raw way)
2913         parse_foreign_dir -d $DIR/$tdir/$tdir |
2914                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2915                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2916         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2917                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2918         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2919                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2920         parse_foreign_dir -d $DIR/$tdir/$tdir |
2921                 grep "lmv_foreign_flags: 55813$" ||
2922                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2923         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2924                 grep "lmv_foreign_value: 0x" |
2925                 sed 's/lmv_foreign_value: 0x//')
2926         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2927                 sed 's/ //g')
2928         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2929
2930         # create foreign dir (lfs + API)
2931         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2932                 $DIR/$tdir/${tdir}2 ||
2933                 error "$DIR/$tdir/${tdir}2: create failed"
2934
2935         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2936
2937         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2938                 grep "lfm_magic:.*0x0CD50CD0" ||
2939                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2940         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2941         # - sizeof(lfm_type) - sizeof(lfm_flags)
2942         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2943                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2945                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2947                 grep "lfm_flags:.*0x0000DA05" ||
2948                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2949         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2950                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2951                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2952
2953         # file create in dir should fail
2954         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2955         touch $DIR/$tdir/${tdir}2/$tfile &&
2956                 error "$DIR/${tdir}2: file create should fail"
2957
2958         # chmod should work
2959         chmod 777 $DIR/$tdir/$tdir ||
2960                 error "$DIR/$tdir: chmod failed"
2961         chmod 777 $DIR/$tdir/${tdir}2 ||
2962                 error "$DIR/${tdir}2: chmod failed"
2963
2964         # chown should work
2965         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2966                 error "$DIR/$tdir: chown failed"
2967         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2968                 error "$DIR/${tdir}2: chown failed"
2969
2970         # rename should work
2971         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2972                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2973         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2974                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2975
2976         #remove foreign dir
2977         rmdir $DIR/$tdir/${tdir}.new ||
2978                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2979         rmdir $DIR/$tdir/${tdir}2.new ||
2980                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2981 }
2982 run_test 27K "basic ops on dir with foreign LMV"
2983
2984 test_27L() {
2985         remote_mds_nodsh && skip "remote MDS with nodsh"
2986
2987         local POOL=${POOL:-$TESTNAME}
2988
2989         pool_add $POOL || error "pool_add failed"
2990
2991         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2992                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2993                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2994 }
2995 run_test 27L "lfs pool_list gives correct pool name"
2996
2997 test_27M() {
2998         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2999                 skip "Need MDS version >= than 2.12.57"
3000         remote_mds_nodsh && skip "remote MDS with nodsh"
3001         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3002
3003         # Set default striping on directory
3004         local setcount=4
3005         local stripe_opt
3006         local mdts=$(comma_list $(mdts_nodes))
3007
3008         # if we run against a 2.12 server which lacks overstring support
3009         # then the connect_flag will not report overstriping, even if client
3010         # is 2.14+
3011         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3012                 stripe_opt="-C $setcount"
3013         elif (( $OSTCOUNT >= $setcount )); then
3014                 stripe_opt="-c $setcount"
3015         else
3016                 skip "server does not support overstriping"
3017         fi
3018
3019         test_mkdir $DIR/$tdir
3020
3021         # Validate existing append_* params and ensure restore
3022         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3023         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3024         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3025
3026         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3027         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3028         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3029
3030         $LFS setstripe $stripe_opt $DIR/$tdir
3031
3032         echo 1 > $DIR/$tdir/${tfile}.1
3033         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3034         [ $count -eq $setcount ] ||
3035                 error "(1) stripe count $count, should be $setcount"
3036
3037         local appendcount=$orig_count
3038         echo 1 >> $DIR/$tdir/${tfile}.2_append
3039         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3040         [ $count -eq $appendcount ] ||
3041                 error "(2)stripe count $count, should be $appendcount for append"
3042
3043         # Disable O_APPEND striping, verify it works
3044         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3045
3046         # Should now get the default striping, which is 4
3047         setcount=4
3048         echo 1 >> $DIR/$tdir/${tfile}.3_append
3049         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3050         [ $count -eq $setcount ] ||
3051                 error "(3) stripe count $count, should be $setcount"
3052
3053         # Try changing the stripe count for append files
3054         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3055
3056         # Append striping is now 2 (directory default is still 4)
3057         appendcount=2
3058         echo 1 >> $DIR/$tdir/${tfile}.4_append
3059         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3060         [ $count -eq $appendcount ] ||
3061                 error "(4) stripe count $count, should be $appendcount for append"
3062
3063         # Test append stripe count of -1
3064         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3065         appendcount=$OSTCOUNT
3066         echo 1 >> $DIR/$tdir/${tfile}.5
3067         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3068         [ $count -eq $appendcount ] ||
3069                 error "(5) stripe count $count, should be $appendcount for append"
3070
3071         # Set append striping back to default of 1
3072         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3073
3074         # Try a new default striping, PFL + DOM
3075         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3076
3077         # Create normal DOM file, DOM returns stripe count == 0
3078         setcount=0
3079         touch $DIR/$tdir/${tfile}.6
3080         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3081         [ $count -eq $setcount ] ||
3082                 error "(6) stripe count $count, should be $setcount"
3083
3084         # Show
3085         appendcount=1
3086         echo 1 >> $DIR/$tdir/${tfile}.7_append
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3088         [ $count -eq $appendcount ] ||
3089                 error "(7) stripe count $count, should be $appendcount for append"
3090
3091         # Clean up DOM layout
3092         $LFS setstripe -d $DIR/$tdir
3093
3094         save_layout_restore_at_exit $MOUNT
3095         # Now test that append striping works when layout is from root
3096         $LFS setstripe -c 2 $MOUNT
3097         # Make a special directory for this
3098         mkdir $DIR/${tdir}/${tdir}.2
3099
3100         # Verify for normal file
3101         setcount=2
3102         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3103         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3104         [ $count -eq $setcount ] ||
3105                 error "(8) stripe count $count, should be $setcount"
3106
3107         appendcount=1
3108         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3109         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3110         [ $count -eq $appendcount ] ||
3111                 error "(9) stripe count $count, should be $appendcount for append"
3112
3113         # Now test O_APPEND striping with pools
3114         pool_add $TESTNAME || error "pool creation failed"
3115         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3116         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3117
3118         echo 1 >> $DIR/$tdir/${tfile}.10_append
3119
3120         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3121         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3122
3123         # Check that count is still correct
3124         appendcount=1
3125         echo 1 >> $DIR/$tdir/${tfile}.11_append
3126         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3127         [ $count -eq $appendcount ] ||
3128                 error "(11) stripe count $count, should be $appendcount for append"
3129
3130         # Disable O_APPEND stripe count, verify pool works separately
3131         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3132
3133         echo 1 >> $DIR/$tdir/${tfile}.12_append
3134
3135         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3136         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3137
3138         # Remove pool setting, verify it's not applied
3139         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3140
3141         echo 1 >> $DIR/$tdir/${tfile}.13_append
3142
3143         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3144         [ "$pool" = "" ] || error "(13) pool found: $pool"
3145 }
3146 run_test 27M "test O_APPEND striping"
3147
3148 test_27N() {
3149         combined_mgs_mds && skip "needs separate MGS/MDT"
3150
3151         pool_add $TESTNAME || error "pool_add failed"
3152         do_facet mgs "$LCTL pool_list $FSNAME" |
3153                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3154                 error "lctl pool_list on MGS failed"
3155 }
3156 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3157
3158 clean_foreign_symlink() {
3159         trap 0
3160         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3161         for i in $DIR/$tdir/* ; do
3162                 $LFS unlink_foreign $i || true
3163         done
3164 }
3165
3166 test_27O() {
3167         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3168                 skip "Need MDS version newer than 2.12.51"
3169
3170         test_mkdir $DIR/$tdir
3171         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3172         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3173
3174         trap clean_foreign_symlink EXIT
3175
3176         # enable foreign_symlink behaviour
3177         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3178
3179         # foreign symlink LOV format is a partial path by default
3180
3181         # create foreign file (lfs + API)
3182         $LFS setstripe --foreign=symlink --flags 0xda05 \
3183                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3184                 error "$DIR/$tdir/${tfile}: create failed"
3185
3186         $LFS getstripe -v $DIR/$tdir/${tfile} |
3187                 grep "lfm_magic:.*0x0BD70BD0" ||
3188                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3189         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3190                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3191         $LFS getstripe -v $DIR/$tdir/${tfile} |
3192                 grep "lfm_flags:.*0x0000DA05" ||
3193                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3194         $LFS getstripe $DIR/$tdir/${tfile} |
3195                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3196                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3197
3198         # modify striping should fail
3199         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3200                 error "$DIR/$tdir/$tfile: setstripe should fail"
3201
3202         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3203         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3204         cat /etc/passwd > $DIR/$tdir/$tfile &&
3205                 error "$DIR/$tdir/$tfile: write should fail"
3206
3207         # rename should succeed
3208         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3209                 error "$DIR/$tdir/$tfile: rename has failed"
3210
3211         #remove foreign_symlink file should fail
3212         rm $DIR/$tdir/${tfile}.new &&
3213                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3214
3215         #test fake symlink
3216         mkdir /tmp/${uuid1} ||
3217                 error "/tmp/${uuid1}: mkdir has failed"
3218         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3219                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3220         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3221         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3222                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3223         #read should succeed now
3224         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3225                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3226         #write should succeed now
3227         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3228                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3229         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3230                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3231         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3232                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3233
3234         #check that getstripe still works
3235         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3236                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3237
3238         # chmod should still succeed
3239         chmod 644 $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3241
3242         # chown should still succeed
3243         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3244                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3245
3246         # rename should still succeed
3247         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3248                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3249
3250         #remove foreign_symlink file should still fail
3251         rm $DIR/$tdir/${tfile} &&
3252                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3253
3254         #use special ioctl() to unlink foreign_symlink file
3255         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3256                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3257
3258 }
3259 run_test 27O "basic ops on foreign file of symlink type"
3260
3261 test_27P() {
3262         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3263                 skip "Need MDS version newer than 2.12.49"
3264
3265         test_mkdir $DIR/$tdir
3266         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3267         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3268
3269         trap clean_foreign_symlink EXIT
3270
3271         # enable foreign_symlink behaviour
3272         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3273
3274         # foreign symlink LMV format is a partial path by default
3275
3276         # create foreign dir (lfs + API)
3277         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3278                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3279                 error "$DIR/$tdir/${tdir}: create failed"
3280
3281         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3282
3283         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3284                 grep "lfm_magic:.*0x0CD50CD0" ||
3285                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3286         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3287                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3288         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3289                 grep "lfm_flags:.*0x0000DA05" ||
3290                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3291         $LFS getdirstripe $DIR/$tdir/${tdir} |
3292                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3293                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3294
3295         # file create in dir should fail
3296         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3297         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3298
3299         # rename should succeed
3300         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3301                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3302
3303         #remove foreign_symlink dir should fail
3304         rmdir $DIR/$tdir/${tdir}.new &&
3305                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3306
3307         #test fake symlink
3308         mkdir -p /tmp/${uuid1}/${uuid2} ||
3309                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3310         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3311                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3312         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3313         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3314                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3315         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3316                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3317
3318         #check that getstripe fails now that foreign_symlink enabled
3319         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3320                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3321
3322         # file create in dir should work now
3323         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3324                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3325         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3326                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3327         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3328                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3329
3330         # chmod should still succeed
3331         chmod 755 $DIR/$tdir/${tdir}.new ||
3332                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3333
3334         # chown should still succeed
3335         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3336                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3337
3338         # rename should still succeed
3339         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3340                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3341
3342         #remove foreign_symlink dir should still fail
3343         rmdir $DIR/$tdir/${tdir} &&
3344                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3345
3346         #use special ioctl() to unlink foreign_symlink file
3347         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3348                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3349
3350         #created file should still exist
3351         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3352                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3353         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3354                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3355 }
3356 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3357
3358 test_27Q() {
3359         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3360         stack_trap "rm -f $TMP/$tfile*"
3361
3362         test_mkdir $DIR/$tdir-1
3363         test_mkdir $DIR/$tdir-2
3364
3365         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3366         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3367
3368         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3369         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3370
3371         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3372         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3373
3374         # Create some bad symlinks and ensure that we don't loop
3375         # forever or something. These should return ELOOP (40) and
3376         # ENOENT (2) but I don't want to test for that because there's
3377         # always some weirdo architecture that needs to ruin
3378         # everything by defining these error numbers differently.
3379
3380         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3381         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3382
3383         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3384         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3385
3386         return 0
3387 }
3388 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3389
3390 test_27R() {
3391         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3392                 skip "need MDS 2.14.55 or later"
3393         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3394
3395         local testdir="$DIR/$tdir"
3396         test_mkdir -p $testdir
3397         stack_trap "rm -rf $testdir"
3398         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3399
3400         local f1="$testdir/f1"
3401         touch $f1 || error "failed to touch $f1"
3402         local count=$($LFS getstripe -c $f1)
3403         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3404
3405         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3406         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3407
3408         local maxcount=$(($OSTCOUNT - 1))
3409         local mdts=$(comma_list $(mdts_nodes))
3410         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3411         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3412
3413         local f2="$testdir/f2"
3414         touch $f2 || error "failed to touch $f2"
3415         local count=$($LFS getstripe -c $f2)
3416         (( $count == $maxcount )) || error "wrong stripe count"
3417 }
3418 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3419
3420 test_27T() {
3421         [ $(facet_host client) == $(facet_host ost1) ] &&
3422                 skip "need ost1 and client on different nodes"
3423
3424 #define OBD_FAIL_OSC_NO_GRANT            0x411
3425         $LCTL set_param fail_loc=0x20000411 fail_val=1
3426 #define OBD_FAIL_OST_ENOSPC              0x215
3427         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3428         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3429         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3430                 error "multiop failed"
3431 }
3432 run_test 27T "no eio on close on partial write due to enosp"
3433
3434 test_27U() {
3435         local dir=$DIR/$tdir
3436         local file=$dir/$tfile
3437         local append_pool=${TESTNAME}-append
3438         local normal_pool=${TESTNAME}-normal
3439         local pool
3440         local stripe_count
3441         local stripe_count2
3442         local mdts=$(comma_list $(mdts_nodes))
3443
3444         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3445                 skip "Need MDS version at least 2.15.51 for append pool feature"
3446
3447         # Validate existing append_* params and ensure restore
3448         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3449         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3450         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3451
3452         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3453         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3454         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3455
3456         pool_add $append_pool || error "pool creation failed"
3457         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3458
3459         pool_add $normal_pool || error "pool creation failed"
3460         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3461
3462         test_mkdir $dir
3463         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3464
3465         echo XXX >> $file.1
3466         $LFS getstripe $file.1
3467
3468         pool=$($LFS getstripe -p $file.1)
3469         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3470
3471         stripe_count2=$($LFS getstripe -c $file.1)
3472         ((stripe_count2 == stripe_count)) ||
3473                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3474
3475         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3476
3477         echo XXX >> $file.2
3478         $LFS getstripe $file.2
3479
3480         pool=$($LFS getstripe -p $file.2)
3481         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3482
3483         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3484
3485         echo XXX >> $file.3
3486         $LFS getstripe $file.3
3487
3488         stripe_count2=$($LFS getstripe -c $file.3)
3489         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3490 }
3491 run_test 27U "append pool and stripe count work with composite default layout"
3492
3493 # createtest also checks that device nodes are created and
3494 # then visible correctly (#2091)
3495 test_28() { # bug 2091
3496         test_mkdir $DIR/d28
3497         $CREATETEST $DIR/d28/ct || error "createtest failed"
3498 }
3499 run_test 28 "create/mknod/mkdir with bad file types ============"
3500
3501 test_29() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3505                 disable_opencache
3506                 stack_trap "restore_opencache"
3507         }
3508
3509         sync; sleep 1; sync # flush out any dirty pages from previous tests
3510         cancel_lru_locks
3511         test_mkdir $DIR/d29
3512         touch $DIR/d29/foo
3513         log 'first d29'
3514         ls -l $DIR/d29
3515
3516         declare -i LOCKCOUNTORIG=0
3517         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3518                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3519         done
3520         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3521
3522         declare -i LOCKUNUSEDCOUNTORIG=0
3523         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3524                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3525         done
3526
3527         log 'second d29'
3528         ls -l $DIR/d29
3529         log 'done'
3530
3531         declare -i LOCKCOUNTCURRENT=0
3532         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3533                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3534         done
3535
3536         declare -i LOCKUNUSEDCOUNTCURRENT=0
3537         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3538                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3539         done
3540
3541         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3542                 $LCTL set_param -n ldlm.dump_namespaces ""
3543                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3544                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3545                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3546                 return 2
3547         fi
3548         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3549                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3550                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3551                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3552                 return 3
3553         fi
3554 }
3555 run_test 29 "IT_GETATTR regression  ============================"
3556
3557 test_30a() { # was test_30
3558         cp $(which ls) $DIR || cp /bin/ls $DIR
3559         $DIR/ls / || error "Can't execute binary from lustre"
3560         rm $DIR/ls
3561 }
3562 run_test 30a "execute binary from Lustre (execve) =============="
3563
3564 test_30b() {
3565         cp `which ls` $DIR || cp /bin/ls $DIR
3566         chmod go+rx $DIR/ls
3567         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3568         rm $DIR/ls
3569 }
3570 run_test 30b "execute binary from Lustre as non-root ==========="
3571
3572 test_30c() { # b=22376
3573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3574
3575         cp $(which ls) $DIR || cp /bin/ls $DIR
3576         chmod a-rw $DIR/ls
3577         cancel_lru_locks mdc
3578         cancel_lru_locks osc
3579         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3580         rm -f $DIR/ls
3581 }
3582 run_test 30c "execute binary from Lustre without read perms ===="
3583
3584 test_30d() {
3585         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3586
3587         for i in {1..10}; do
3588                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3589                 local PID=$!
3590                 sleep 1
3591                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3592                 wait $PID || error "executing dd from Lustre failed"
3593                 rm -f $DIR/$tfile
3594         done
3595
3596         rm -f $DIR/dd
3597 }
3598 run_test 30d "execute binary from Lustre while clear locks"
3599
3600 test_31a() {
3601         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3602         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3603 }
3604 run_test 31a "open-unlink file =================================="
3605
3606 test_31b() {
3607         touch $DIR/f31 || error "touch $DIR/f31 failed"
3608         ln $DIR/f31 $DIR/f31b || error "ln failed"
3609         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3610         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3611 }
3612 run_test 31b "unlink file with multiple links while open ======="
3613
3614 test_31c() {
3615         touch $DIR/f31 || error "touch $DIR/f31 failed"
3616         ln $DIR/f31 $DIR/f31c || error "ln failed"
3617         multiop_bg_pause $DIR/f31 O_uc ||
3618                 error "multiop_bg_pause for $DIR/f31 failed"
3619         MULTIPID=$!
3620         $MULTIOP $DIR/f31c Ouc
3621         kill -USR1 $MULTIPID
3622         wait $MULTIPID
3623 }
3624 run_test 31c "open-unlink file with multiple links ============="
3625
3626 test_31d() {
3627         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3628         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3629 }
3630 run_test 31d "remove of open directory ========================="
3631
3632 test_31e() { # bug 2904
3633         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3634 }
3635 run_test 31e "remove of open non-empty directory ==============="
3636
3637 test_31f() { # bug 4554
3638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3639
3640         set -vx
3641         test_mkdir $DIR/d31f
3642         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3643         cp /etc/hosts $DIR/d31f
3644         ls -l $DIR/d31f
3645         $LFS getstripe $DIR/d31f/hosts
3646         multiop_bg_pause $DIR/d31f D_c || return 1
3647         MULTIPID=$!
3648
3649         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3650         test_mkdir $DIR/d31f
3651         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3652         cp /etc/hosts $DIR/d31f
3653         ls -l $DIR/d31f
3654         $LFS getstripe $DIR/d31f/hosts
3655         multiop_bg_pause $DIR/d31f D_c || return 1
3656         MULTIPID2=$!
3657
3658         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3659         wait $MULTIPID || error "first opendir $MULTIPID failed"
3660
3661         sleep 6
3662
3663         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3664         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3665         set +vx
3666 }
3667 run_test 31f "remove of open directory with open-unlink file ==="
3668
3669 test_31g() {
3670         echo "-- cross directory link --"
3671         test_mkdir -c1 $DIR/${tdir}ga
3672         test_mkdir -c1 $DIR/${tdir}gb
3673         touch $DIR/${tdir}ga/f
3674         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3675         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3676         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3677         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3678         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3679 }
3680 run_test 31g "cross directory link==============="
3681
3682 test_31h() {
3683         echo "-- cross directory link --"
3684         test_mkdir -c1 $DIR/${tdir}
3685         test_mkdir -c1 $DIR/${tdir}/dir
3686         touch $DIR/${tdir}/f
3687         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3688         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3689         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3690         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3691         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3692 }
3693 run_test 31h "cross directory link under child==============="
3694
3695 test_31i() {
3696         echo "-- cross directory link --"
3697         test_mkdir -c1 $DIR/$tdir
3698         test_mkdir -c1 $DIR/$tdir/dir
3699         touch $DIR/$tdir/dir/f
3700         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3701         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3702         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3703         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3704         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3705 }
3706 run_test 31i "cross directory link under parent==============="
3707
3708 test_31j() {
3709         test_mkdir -c1 -p $DIR/$tdir
3710         test_mkdir -c1 -p $DIR/$tdir/dir1
3711         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3712         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3713         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3714         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3715         return 0
3716 }
3717 run_test 31j "link for directory==============="
3718
3719 test_31k() {
3720         test_mkdir -c1 -p $DIR/$tdir
3721         touch $DIR/$tdir/s
3722         touch $DIR/$tdir/exist
3723         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3724         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3725         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3726         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3727         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3728         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3729         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3730         return 0
3731 }
3732 run_test 31k "link to file: the same, non-existing, dir==============="
3733
3734 test_31m() {
3735         mkdir $DIR/d31m
3736         touch $DIR/d31m/s
3737         mkdir $DIR/d31m2
3738         touch $DIR/d31m2/exist
3739         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3740         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3741         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3742         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3743         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3744         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3745         return 0
3746 }
3747 run_test 31m "link to file: the same, non-existing, dir==============="
3748
3749 test_31n() {
3750         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3751         nlink=$(stat --format=%h $DIR/$tfile)
3752         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3753         local fd=$(free_fd)
3754         local cmd="exec $fd<$DIR/$tfile"
3755         eval $cmd
3756         cmd="exec $fd<&-"
3757         trap "eval $cmd" EXIT
3758         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3759         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3760         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3761         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3762         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3763         eval $cmd
3764 }
3765 run_test 31n "check link count of unlinked file"
3766
3767 link_one() {
3768         local tempfile=$(mktemp $1_XXXXXX)
3769         mlink $tempfile $1 2> /dev/null &&
3770                 echo "$BASHPID: link $tempfile to $1 succeeded"
3771         munlink $tempfile
3772 }
3773
3774 test_31o() { # LU-2901
3775         test_mkdir $DIR/$tdir
3776         for LOOP in $(seq 100); do
3777                 rm -f $DIR/$tdir/$tfile*
3778                 for THREAD in $(seq 8); do
3779                         link_one $DIR/$tdir/$tfile.$LOOP &
3780                 done
3781                 wait
3782                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3783                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3784                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3785                         break || true
3786         done
3787 }
3788 run_test 31o "duplicate hard links with same filename"
3789
3790 test_31p() {
3791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3792
3793         test_mkdir $DIR/$tdir
3794         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3795         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3796
3797         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3798                 error "open unlink test1 failed"
3799         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3800                 error "open unlink test2 failed"
3801
3802         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3803                 error "test1 still exists"
3804         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3805                 error "test2 still exists"
3806 }
3807 run_test 31p "remove of open striped directory"
3808
3809 test_31q() {
3810         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3811
3812         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3813         index=$($LFS getdirstripe -i $DIR/$tdir)
3814         [ $index -eq 3 ] || error "first stripe index $index != 3"
3815         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3816         [ $index -eq 1 ] || error "second stripe index $index != 1"
3817
3818         # when "-c <stripe_count>" is set, the number of MDTs specified after
3819         # "-i" should equal to the stripe count
3820         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3821 }
3822 run_test 31q "create striped directory on specific MDTs"
3823
3824 #LU-14949
3825 test_31r() {
3826         touch $DIR/$tfile.target
3827         touch $DIR/$tfile.source
3828
3829         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3830         $LCTL set_param fail_loc=0x1419 fail_val=3
3831         cat $DIR/$tfile.target &
3832         CATPID=$!
3833
3834         # Guarantee open is waiting before we get here
3835         sleep 1
3836         mv $DIR/$tfile.source $DIR/$tfile.target
3837
3838         wait $CATPID
3839         RC=$?
3840         if [[ $RC -ne 0 ]]; then
3841                 error "open with cat failed, rc=$RC"
3842         fi
3843 }
3844 run_test 31r "open-rename(replace) race"
3845
3846 cleanup_test32_mount() {
3847         local rc=0
3848         trap 0
3849         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3850         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3851         losetup -d $loopdev || true
3852         rm -rf $DIR/$tdir
3853         return $rc
3854 }
3855
3856 test_32a() {
3857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3858
3859         echo "== more mountpoints and symlinks ================="
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3866                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3867         cleanup_test32_mount
3868 }
3869 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3870
3871 test_32b() {
3872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3873
3874         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3875         trap cleanup_test32_mount EXIT
3876         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3877         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3878                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3879         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3880                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3881         cleanup_test32_mount
3882 }
3883 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3884
3885 test_32c() {
3886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3887
3888         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3889         trap cleanup_test32_mount EXIT
3890         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3893         test_mkdir -p $DIR/$tdir/d2/test_dir
3894         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3895                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3896         cleanup_test32_mount
3897 }
3898 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3899
3900 test_32d() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         test_mkdir -p $DIR/$tdir/d2/test_dir
3909         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3910                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3911         cleanup_test32_mount
3912 }
3913 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3914
3915 test_32e() {
3916         rm -fr $DIR/$tdir
3917         test_mkdir -p $DIR/$tdir/tmp
3918         local tmp_dir=$DIR/$tdir/tmp
3919         ln -s $DIR/$tdir $tmp_dir/symlink11
3920         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3921         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3922         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3923 }
3924 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3925
3926 test_32f() {
3927         rm -fr $DIR/$tdir
3928         test_mkdir -p $DIR/$tdir/tmp
3929         local tmp_dir=$DIR/$tdir/tmp
3930         ln -s $DIR/$tdir $tmp_dir/symlink11
3931         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3932         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3933         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3934 }
3935 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3936
3937 test_32g() {
3938         local tmp_dir=$DIR/$tdir/tmp
3939         test_mkdir -p $tmp_dir
3940         test_mkdir $DIR/${tdir}2
3941         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3942         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3943         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3944         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3945         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3946         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3947 }
3948 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3949
3950 test_32h() {
3951         rm -fr $DIR/$tdir $DIR/${tdir}2
3952         tmp_dir=$DIR/$tdir/tmp
3953         test_mkdir -p $tmp_dir
3954         test_mkdir $DIR/${tdir}2
3955         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3956         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3957         ls $tmp_dir/symlink12 || error "listing symlink12"
3958         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3959 }
3960 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3961
3962 test_32i() {
3963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3964
3965         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3966         trap cleanup_test32_mount EXIT
3967         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3968         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3969                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3970         touch $DIR/$tdir/test_file
3971         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3972                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3973         cleanup_test32_mount
3974 }
3975 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3976
3977 test_32j() {
3978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3979
3980         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3981         trap cleanup_test32_mount EXIT
3982         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3983         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3984                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3985         touch $DIR/$tdir/test_file
3986         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3987                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3988         cleanup_test32_mount
3989 }
3990 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3991
3992 test_32k() {
3993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3994
3995         rm -fr $DIR/$tdir
3996         trap cleanup_test32_mount EXIT
3997         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3998         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3999                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4000         test_mkdir -p $DIR/$tdir/d2
4001         touch $DIR/$tdir/d2/test_file || error "touch failed"
4002         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4003                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4004         cleanup_test32_mount
4005 }
4006 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4007
4008 test_32l() {
4009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4010
4011         rm -fr $DIR/$tdir
4012         trap cleanup_test32_mount EXIT
4013         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4014         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4015                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4016         test_mkdir -p $DIR/$tdir/d2
4017         touch $DIR/$tdir/d2/test_file || error "touch failed"
4018         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4019                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4020         cleanup_test32_mount
4021 }
4022 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4023
4024 test_32m() {
4025         rm -fr $DIR/d32m
4026         test_mkdir -p $DIR/d32m/tmp
4027         TMP_DIR=$DIR/d32m/tmp
4028         ln -s $DIR $TMP_DIR/symlink11
4029         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4030         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4031                 error "symlink11 not a link"
4032         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4033                 error "symlink01 not a link"
4034 }
4035 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4036
4037 test_32n() {
4038         rm -fr $DIR/d32n
4039         test_mkdir -p $DIR/d32n/tmp
4040         TMP_DIR=$DIR/d32n/tmp
4041         ln -s $DIR $TMP_DIR/symlink11
4042         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4043         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4044         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4045 }
4046 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4047
4048 test_32o() {
4049         touch $DIR/$tfile
4050         test_mkdir -p $DIR/d32o/tmp
4051         TMP_DIR=$DIR/d32o/tmp
4052         ln -s $DIR/$tfile $TMP_DIR/symlink12
4053         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4054         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4055                 error "symlink12 not a link"
4056         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4057         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4058                 error "$DIR/d32o/tmp/symlink12 not file type"
4059         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4060                 error "$DIR/d32o/symlink02 not file type"
4061 }
4062 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4063
4064 test_32p() {
4065         log 32p_1
4066         rm -fr $DIR/d32p
4067         log 32p_2
4068         rm -f $DIR/$tfile
4069         log 32p_3
4070         touch $DIR/$tfile
4071         log 32p_4
4072         test_mkdir -p $DIR/d32p/tmp
4073         log 32p_5
4074         TMP_DIR=$DIR/d32p/tmp
4075         log 32p_6
4076         ln -s $DIR/$tfile $TMP_DIR/symlink12
4077         log 32p_7
4078         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4079         log 32p_8
4080         cat $DIR/d32p/tmp/symlink12 ||
4081                 error "Can't open $DIR/d32p/tmp/symlink12"
4082         log 32p_9
4083         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4084         log 32p_10
4085 }
4086 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4087
4088 test_32q() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4092         trap cleanup_test32_mount EXIT
4093         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4094         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4095         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4096                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4097         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4098         cleanup_test32_mount
4099 }
4100 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4101
4102 test_32r() {
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104
4105         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4106         trap cleanup_test32_mount EXIT
4107         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4108         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4109         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4110                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4111         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4112         cleanup_test32_mount
4113 }
4114 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4115
4116 test_33aa() {
4117         rm -f $DIR/$tfile
4118         touch $DIR/$tfile
4119         chmod 444 $DIR/$tfile
4120         chown $RUNAS_ID $DIR/$tfile
4121         log 33_1
4122         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4123         log 33_2
4124 }
4125 run_test 33aa "write file with mode 444 (should return error)"
4126
4127 test_33a() {
4128         rm -fr $DIR/$tdir
4129         test_mkdir $DIR/$tdir
4130         chown $RUNAS_ID $DIR/$tdir
4131         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4132                 error "$RUNAS create $tdir/$tfile failed"
4133         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4134                 error "open RDWR" || true
4135 }
4136 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4137
4138 test_33b() {
4139         rm -fr $DIR/$tdir
4140         test_mkdir $DIR/$tdir
4141         chown $RUNAS_ID $DIR/$tdir
4142         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4143 }
4144 run_test 33b "test open file with malformed flags (No panic)"
4145
4146 test_33c() {
4147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4148         remote_ost_nodsh && skip "remote OST with nodsh"
4149
4150         local ostnum
4151         local ostname
4152         local write_bytes
4153         local all_zeros
4154
4155         all_zeros=true
4156         test_mkdir $DIR/$tdir
4157         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4158
4159         sync
4160         for ostnum in $(seq $OSTCOUNT); do
4161                 # test-framework's OST numbering is one-based, while Lustre's
4162                 # is zero-based
4163                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4164                 # check if at least some write_bytes stats are counted
4165                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4166                               obdfilter.$ostname.stats |
4167                               awk '/^write_bytes/ {print $7}' )
4168                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4169                 if (( ${write_bytes:-0} > 0 )); then
4170                         all_zeros=false
4171                         break
4172                 fi
4173         done
4174
4175         $all_zeros || return 0
4176
4177         # Write four bytes
4178         echo foo > $DIR/$tdir/bar
4179         # Really write them
4180         sync
4181
4182         # Total up write_bytes after writing.  We'd better find non-zeros.
4183         for ostnum in $(seq $OSTCOUNT); do
4184                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4185                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4186                               obdfilter/$ostname/stats |
4187                               awk '/^write_bytes/ {print $7}' )
4188                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4189                 if (( ${write_bytes:-0} > 0 )); then
4190                         all_zeros=false
4191                         break
4192                 fi
4193         done
4194
4195         if $all_zeros; then
4196                 for ostnum in $(seq $OSTCOUNT); do
4197                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4198                         echo "Check write_bytes is in obdfilter.*.stats:"
4199                         do_facet ost$ostnum lctl get_param -n \
4200                                 obdfilter.$ostname.stats
4201                 done
4202                 error "OST not keeping write_bytes stats (b=22312)"
4203         fi
4204 }
4205 run_test 33c "test write_bytes stats"
4206
4207 test_33d() {
4208         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4210
4211         local MDTIDX=1
4212         local remote_dir=$DIR/$tdir/remote_dir
4213
4214         test_mkdir $DIR/$tdir
4215         $LFS mkdir -i $MDTIDX $remote_dir ||
4216                 error "create remote directory failed"
4217
4218         touch $remote_dir/$tfile
4219         chmod 444 $remote_dir/$tfile
4220         chown $RUNAS_ID $remote_dir/$tfile
4221
4222         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4223
4224         chown $RUNAS_ID $remote_dir
4225         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4226                                         error "create" || true
4227         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4228                                     error "open RDWR" || true
4229         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4230 }
4231 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4232
4233 test_33e() {
4234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4235
4236         mkdir $DIR/$tdir
4237
4238         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4239         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4240         mkdir $DIR/$tdir/local_dir
4241
4242         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4243         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4244         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4245
4246         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4247                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4248
4249         rmdir $DIR/$tdir/* || error "rmdir failed"
4250
4251         umask 777
4252         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4253         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4254         mkdir $DIR/$tdir/local_dir
4255
4256         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4257         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4258         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4259
4260         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4261                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4262
4263         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4264
4265         umask 000
4266         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4267         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4268         mkdir $DIR/$tdir/local_dir
4269
4270         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4271         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4272         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4273
4274         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4275                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4276 }
4277 run_test 33e "mkdir and striped directory should have same mode"
4278
4279 cleanup_33f() {
4280         trap 0
4281         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4282 }
4283
4284 test_33f() {
4285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4286         remote_mds_nodsh && skip "remote MDS with nodsh"
4287
4288         mkdir $DIR/$tdir
4289         chmod go+rwx $DIR/$tdir
4290         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4291         trap cleanup_33f EXIT
4292
4293         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4294                 error "cannot create striped directory"
4295
4296         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4297                 error "cannot create files in striped directory"
4298
4299         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4300                 error "cannot remove files in striped directory"
4301
4302         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4303                 error "cannot remove striped directory"
4304
4305         cleanup_33f
4306 }
4307 run_test 33f "nonroot user can create, access, and remove a striped directory"
4308
4309 test_33g() {
4310         mkdir -p $DIR/$tdir/dir2
4311
4312         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4313         echo $err
4314         [[ $err =~ "exists" ]] || error "Not exists error"
4315 }
4316 run_test 33g "nonroot user create already existing root created file"
4317
4318 sub_33h() {
4319         local hash_type=$1
4320         local count=250
4321
4322         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4323                 error "lfs mkdir -H $hash_type $tdir failed"
4324         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4325
4326         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4327         local index2
4328         local fname
4329
4330         for fname in $DIR/$tdir/$tfile.bak \
4331                      $DIR/$tdir/$tfile.SAV \
4332                      $DIR/$tdir/$tfile.orig \
4333                      $DIR/$tdir/$tfile~; do
4334                 touch $fname || error "touch $fname failed"
4335                 index2=$($LFS getstripe -m $fname)
4336                 (( $index == $index2 )) ||
4337                         error "$fname MDT index mismatch $index != $index2"
4338         done
4339
4340         local failed=0
4341         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4342         local pattern
4343
4344         for pattern in ${patterns[*]}; do
4345                 echo "pattern $pattern"
4346                 fname=$DIR/$tdir/$pattern
4347                 for (( i = 0; i < $count; i++ )); do
4348                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4349                                 error "mktemp $DIR/$tdir/$pattern failed"
4350                         index2=$($LFS getstripe -m $fname)
4351                         (( $index == $index2 )) && continue
4352
4353                         failed=$((failed + 1))
4354                         echo "$fname MDT index mismatch $index != $index2"
4355                 done
4356         done
4357
4358         echo "$failed/$count MDT index mismatches, expect ~2-4"
4359         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4360
4361         local same=0
4362         local expect
4363
4364         # verify that "crush" is still broken with all files on same MDT,
4365         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4366         [[ "$hash_type" == "crush" ]] && expect=$count ||
4367                 expect=$((count / MDSCOUNT))
4368
4369         # crush2 doesn't put all-numeric suffixes on the same MDT,
4370         # filename like $tfile.12345678 should *not* be considered temp
4371         for pattern in ${patterns[*]}; do
4372                 local base=${pattern%%X*}
4373                 local suff=${pattern#$base}
4374
4375                 echo "pattern $pattern"
4376                 for (( i = 0; i < $count; i++ )); do
4377                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4378                         touch $fname || error "touch $fname failed"
4379                         index2=$($LFS getstripe -m $fname)
4380                         (( $index != $index2 )) && continue
4381
4382                         same=$((same + 1))
4383                 done
4384         done
4385
4386         # the number of "bad" hashes is random, as it depends on the random
4387         # filenames generated by "mktemp".  Allow some margin in the results.
4388         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4389         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4390            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4391                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4392         same=0
4393
4394         # crush2 doesn't put suffixes with special characters on the same MDT
4395         # filename like $tfile.txt.1234 should *not* be considered temp
4396         for pattern in ${patterns[*]}; do
4397                 local base=${pattern%%X*}
4398                 local suff=${pattern#$base}
4399
4400                 pattern=$base...${suff/XXX}
4401                 echo "pattern=$pattern"
4402                 for (( i = 0; i < $count; i++ )); do
4403                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4404                                 error "touch $fname failed"
4405                         index2=$($LFS getstripe -m $fname)
4406                         (( $index != $index2 )) && continue
4407
4408                         same=$((same + 1))
4409                 done
4410         done
4411
4412         # the number of "bad" hashes is random, as it depends on the random
4413         # filenames generated by "mktemp".  Allow some margin in the results.
4414         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4415         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4416            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4417                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4418 }
4419
4420 test_33h() {
4421         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4422         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4423                 skip "Need MDS version at least 2.13.50"
4424
4425         sub_33h crush
4426 }
4427 run_test 33h "temp file is located on the same MDT as target (crush)"
4428
4429 test_33hh() {
4430         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4431         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4432         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4433                 skip "Need MDS version at least 2.15.0 for crush2"
4434
4435         sub_33h crush2
4436 }
4437 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4438
4439 test_33i()
4440 {
4441         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4442
4443         local FNAME=$(str_repeat 'f' 250)
4444
4445         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4446         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4447
4448         local count
4449         local total
4450
4451         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4452
4453         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4454
4455         lctl --device %$MDC deactivate
4456         stack_trap "lctl --device %$MDC activate"
4457         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4458         total=$(\ls -l $DIR/$tdir | wc -l)
4459         # "ls -l" will list total in the first line
4460         total=$((total - 1))
4461         (( total + count == 1000 )) ||
4462                 error "ls list $total files, $count files on MDT1"
4463 }
4464 run_test 33i "striped directory can be accessed when one MDT is down"
4465
4466 test_33j() {
4467         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4468
4469         mkdir -p $DIR/$tdir/
4470
4471         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4472                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4473
4474         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4475                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4476
4477         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4478                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4479
4480         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4481                 error "-D was not specified, but still failed"
4482 }
4483 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4484
4485 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4486 test_34a() {
4487         rm -f $DIR/f34
4488         $MCREATE $DIR/f34 || error "mcreate failed"
4489         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4490                 error "getstripe failed"
4491         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4492         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4493                 error "getstripe failed"
4494         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4495                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4496 }
4497 run_test 34a "truncate file that has not been opened ==========="
4498
4499 test_34b() {
4500         [ ! -f $DIR/f34 ] && test_34a
4501         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4502                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4503         $OPENFILE -f O_RDONLY $DIR/f34
4504         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4505                 error "getstripe failed"
4506         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4507                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4508 }
4509 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4510
4511 test_34c() {
4512         [ ! -f $DIR/f34 ] && test_34a
4513         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4514                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4515         $OPENFILE -f O_RDWR $DIR/f34
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4517                 error "$LFS getstripe failed"
4518         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4519                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4520 }
4521 run_test 34c "O_RDWR opening file-with-size works =============="
4522
4523 test_34d() {
4524         [ ! -f $DIR/f34 ] && test_34a
4525         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4526                 error "dd failed"
4527         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4528                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4529         rm $DIR/f34
4530 }
4531 run_test 34d "write to sparse file ============================="
4532
4533 test_34e() {
4534         rm -f $DIR/f34e
4535         $MCREATE $DIR/f34e || error "mcreate failed"
4536         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4537         $CHECKSTAT -s 1000 $DIR/f34e ||
4538                 error "Size of $DIR/f34e not equal to 1000 bytes"
4539         $OPENFILE -f O_RDWR $DIR/f34e
4540         $CHECKSTAT -s 1000 $DIR/f34e ||
4541                 error "Size of $DIR/f34e not equal to 1000 bytes"
4542 }
4543 run_test 34e "create objects, some with size and some without =="
4544
4545 test_34f() { # bug 6242, 6243
4546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4547
4548         SIZE34F=48000
4549         rm -f $DIR/f34f
4550         $MCREATE $DIR/f34f || error "mcreate failed"
4551         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4552         dd if=$DIR/f34f of=$TMP/f34f
4553         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4554         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4555         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4556         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4557         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4558 }
4559 run_test 34f "read from a file with no objects until EOF ======="
4560
4561 test_34g() {
4562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4563
4564         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4565                 error "dd failed"
4566         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4567         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4568                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4569         cancel_lru_locks osc
4570         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4571                 error "wrong size after lock cancel"
4572
4573         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4574         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4575                 error "expanding truncate failed"
4576         cancel_lru_locks osc
4577         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4578                 error "wrong expanded size after lock cancel"
4579 }
4580 run_test 34g "truncate long file ==============================="
4581
4582 test_34h() {
4583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4584
4585         local gid=10
4586         local sz=1000
4587
4588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4589         sync # Flush the cache so that multiop below does not block on cache
4590              # flush when getting the group lock
4591         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4592         MULTIPID=$!
4593
4594         # Since just timed wait is not good enough, let's do a sync write
4595         # that way we are sure enough time for a roundtrip + processing
4596         # passed + 2 seconds of extra margin.
4597         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4598         rm $DIR/${tfile}-1
4599         sleep 2
4600
4601         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4602                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4603                 kill -9 $MULTIPID
4604         fi
4605         wait $MULTIPID
4606         local nsz=`stat -c %s $DIR/$tfile`
4607         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4608 }
4609 run_test 34h "ftruncate file under grouplock should not block"
4610
4611 test_35a() {
4612         cp /bin/sh $DIR/f35a
4613         chmod 444 $DIR/f35a
4614         chown $RUNAS_ID $DIR/f35a
4615         $RUNAS $DIR/f35a && error || true
4616         rm $DIR/f35a
4617 }
4618 run_test 35a "exec file with mode 444 (should return and not leak)"
4619
4620 test_36a() {
4621         rm -f $DIR/f36
4622         utime $DIR/f36 || error "utime failed for MDS"
4623 }
4624 run_test 36a "MDS utime check (mknod, utime)"
4625
4626 test_36b() {
4627         echo "" > $DIR/f36
4628         utime $DIR/f36 || error "utime failed for OST"
4629 }
4630 run_test 36b "OST utime check (open, utime)"
4631
4632 test_36c() {
4633         rm -f $DIR/d36/f36
4634         test_mkdir $DIR/d36
4635         chown $RUNAS_ID $DIR/d36
4636         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4637 }
4638 run_test 36c "non-root MDS utime check (mknod, utime)"
4639
4640 test_36d() {
4641         [ ! -d $DIR/d36 ] && test_36c
4642         echo "" > $DIR/d36/f36
4643         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4644 }
4645 run_test 36d "non-root OST utime check (open, utime)"
4646
4647 test_36e() {
4648         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4649
4650         test_mkdir $DIR/$tdir
4651         touch $DIR/$tdir/$tfile
4652         $RUNAS utime $DIR/$tdir/$tfile &&
4653                 error "utime worked, expected failure" || true
4654 }
4655 run_test 36e "utime on non-owned file (should return error)"
4656
4657 subr_36fh() {
4658         local fl="$1"
4659         local LANG_SAVE=$LANG
4660         local LC_LANG_SAVE=$LC_LANG
4661         export LANG=C LC_LANG=C # for date language
4662
4663         DATESTR="Dec 20  2000"
4664         test_mkdir $DIR/$tdir
4665         lctl set_param fail_loc=$fl
4666         date; date +%s
4667         cp /etc/hosts $DIR/$tdir/$tfile
4668         sync & # write RPC generated with "current" inode timestamp, but delayed
4669         sleep 1
4670         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4671         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4672         cancel_lru_locks $OSC
4673         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4674         date; date +%s
4675         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4676                 echo "BEFORE: $LS_BEFORE" && \
4677                 echo "AFTER : $LS_AFTER" && \
4678                 echo "WANT  : $DATESTR" && \
4679                 error "$DIR/$tdir/$tfile timestamps changed" || true
4680
4681         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4682 }
4683
4684 test_36f() {
4685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4686
4687         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4688         subr_36fh "0x80000214"
4689 }
4690 run_test 36f "utime on file racing with OST BRW write =========="
4691
4692 test_36g() {
4693         remote_ost_nodsh && skip "remote OST with nodsh"
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4696                 skip "Need MDS version at least 2.12.51"
4697
4698         local fmd_max_age
4699         local fmd
4700         local facet="ost1"
4701         local tgt="obdfilter"
4702
4703         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4704
4705         test_mkdir $DIR/$tdir
4706         fmd_max_age=$(do_facet $facet \
4707                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4708                 head -n 1")
4709
4710         echo "FMD max age: ${fmd_max_age}s"
4711         touch $DIR/$tdir/$tfile
4712         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4713                 gawk '{cnt=cnt+$1}  END{print cnt}')
4714         echo "FMD before: $fmd"
4715         [[ $fmd == 0 ]] &&
4716                 error "FMD wasn't create by touch"
4717         sleep $((fmd_max_age + 12))
4718         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4719                 gawk '{cnt=cnt+$1}  END{print cnt}')
4720         echo "FMD after: $fmd"
4721         [[ $fmd == 0 ]] ||
4722                 error "FMD wasn't expired by ping"
4723 }
4724 run_test 36g "FMD cache expiry ====================="
4725
4726 test_36h() {
4727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4728
4729         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4730         subr_36fh "0x80000227"
4731 }
4732 run_test 36h "utime on file racing with OST BRW write =========="
4733
4734 test_36i() {
4735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4736
4737         test_mkdir $DIR/$tdir
4738         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4739
4740         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4741         local new_mtime=$((mtime + 200))
4742
4743         #change Modify time of striped dir
4744         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4745                         error "change mtime failed"
4746
4747         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4748
4749         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4750 }
4751 run_test 36i "change mtime on striped directory"
4752
4753 # test_37 - duplicate with tests 32q 32r
4754
4755 test_38() {
4756         local file=$DIR/$tfile
4757         touch $file
4758         openfile -f O_DIRECTORY $file
4759         local RC=$?
4760         local ENOTDIR=20
4761         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4762         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4763 }
4764 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4765
4766 test_39a() { # was test_39
4767         touch $DIR/$tfile
4768         touch $DIR/${tfile}2
4769 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4770 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4771 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4772         sleep 2
4773         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4774         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4775                 echo "mtime"
4776                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4777                 echo "atime"
4778                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4779                 echo "ctime"
4780                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4781                 error "O_TRUNC didn't change timestamps"
4782         fi
4783 }
4784 run_test 39a "mtime changed on create"
4785
4786 test_39b() {
4787         test_mkdir -c1 $DIR/$tdir
4788         cp -p /etc/passwd $DIR/$tdir/fopen
4789         cp -p /etc/passwd $DIR/$tdir/flink
4790         cp -p /etc/passwd $DIR/$tdir/funlink
4791         cp -p /etc/passwd $DIR/$tdir/frename
4792         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4793
4794         sleep 1
4795         echo "aaaaaa" >> $DIR/$tdir/fopen
4796         echo "aaaaaa" >> $DIR/$tdir/flink
4797         echo "aaaaaa" >> $DIR/$tdir/funlink
4798         echo "aaaaaa" >> $DIR/$tdir/frename
4799
4800         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4801         local link_new=`stat -c %Y $DIR/$tdir/flink`
4802         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4803         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4804
4805         cat $DIR/$tdir/fopen > /dev/null
4806         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4807         rm -f $DIR/$tdir/funlink2
4808         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4809
4810         for (( i=0; i < 2; i++ )) ; do
4811                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4812                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4813                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4814                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4815
4816                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4817                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4818                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4819                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4820
4821                 cancel_lru_locks $OSC
4822                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4823         done
4824 }
4825 run_test 39b "mtime change on open, link, unlink, rename  ======"
4826
4827 # this should be set to past
4828 TEST_39_MTIME=`date -d "1 year ago" +%s`
4829
4830 # bug 11063
4831 test_39c() {
4832         touch $DIR1/$tfile
4833         sleep 2
4834         local mtime0=`stat -c %Y $DIR1/$tfile`
4835
4836         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4837         local mtime1=`stat -c %Y $DIR1/$tfile`
4838         [ "$mtime1" = $TEST_39_MTIME ] || \
4839                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4840
4841         local d1=`date +%s`
4842         echo hello >> $DIR1/$tfile
4843         local d2=`date +%s`
4844         local mtime2=`stat -c %Y $DIR1/$tfile`
4845         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4846                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4847
4848         mv $DIR1/$tfile $DIR1/$tfile-1
4849
4850         for (( i=0; i < 2; i++ )) ; do
4851                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4852                 [ "$mtime2" = "$mtime3" ] || \
4853                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4854
4855                 cancel_lru_locks $OSC
4856                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4857         done
4858 }
4859 run_test 39c "mtime change on rename ==========================="
4860
4861 # bug 21114
4862 test_39d() {
4863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4864
4865         touch $DIR1/$tfile
4866         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4867
4868         for (( i=0; i < 2; i++ )) ; do
4869                 local mtime=`stat -c %Y $DIR1/$tfile`
4870                 [ $mtime = $TEST_39_MTIME ] || \
4871                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4872
4873                 cancel_lru_locks $OSC
4874                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4875         done
4876 }
4877 run_test 39d "create, utime, stat =============================="
4878
4879 # bug 21114
4880 test_39e() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         touch $DIR1/$tfile
4884         local mtime1=`stat -c %Y $DIR1/$tfile`
4885
4886         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4887
4888         for (( i=0; i < 2; i++ )) ; do
4889                 local mtime2=`stat -c %Y $DIR1/$tfile`
4890                 [ $mtime2 = $TEST_39_MTIME ] || \
4891                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4892
4893                 cancel_lru_locks $OSC
4894                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4895         done
4896 }
4897 run_test 39e "create, stat, utime, stat ========================"
4898
4899 # bug 21114
4900 test_39f() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         touch $DIR1/$tfile
4904         mtime1=`stat -c %Y $DIR1/$tfile`
4905
4906         sleep 2
4907         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4908
4909         for (( i=0; i < 2; i++ )) ; do
4910                 local mtime2=`stat -c %Y $DIR1/$tfile`
4911                 [ $mtime2 = $TEST_39_MTIME ] || \
4912                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4913
4914                 cancel_lru_locks $OSC
4915                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4916         done
4917 }
4918 run_test 39f "create, stat, sleep, utime, stat ================="
4919
4920 # bug 11063
4921 test_39g() {
4922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4923
4924         echo hello >> $DIR1/$tfile
4925         local mtime1=`stat -c %Y $DIR1/$tfile`
4926
4927         sleep 2
4928         chmod o+r $DIR1/$tfile
4929
4930         for (( i=0; i < 2; i++ )) ; do
4931                 local mtime2=`stat -c %Y $DIR1/$tfile`
4932                 [ "$mtime1" = "$mtime2" ] || \
4933                         error "lost mtime: $mtime2, should be $mtime1"
4934
4935                 cancel_lru_locks $OSC
4936                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4937         done
4938 }
4939 run_test 39g "write, chmod, stat ==============================="
4940
4941 # bug 11063
4942 test_39h() {
4943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4944
4945         touch $DIR1/$tfile
4946         sleep 1
4947
4948         local d1=`date`
4949         echo hello >> $DIR1/$tfile
4950         local mtime1=`stat -c %Y $DIR1/$tfile`
4951
4952         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4953         local d2=`date`
4954         if [ "$d1" != "$d2" ]; then
4955                 echo "write and touch not within one second"
4956         else
4957                 for (( i=0; i < 2; i++ )) ; do
4958                         local mtime2=`stat -c %Y $DIR1/$tfile`
4959                         [ "$mtime2" = $TEST_39_MTIME ] || \
4960                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4961
4962                         cancel_lru_locks $OSC
4963                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4964                 done
4965         fi
4966 }
4967 run_test 39h "write, utime within one second, stat ============="
4968
4969 test_39i() {
4970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4971
4972         touch $DIR1/$tfile
4973         sleep 1
4974
4975         echo hello >> $DIR1/$tfile
4976         local mtime1=`stat -c %Y $DIR1/$tfile`
4977
4978         mv $DIR1/$tfile $DIR1/$tfile-1
4979
4980         for (( i=0; i < 2; i++ )) ; do
4981                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4982
4983                 [ "$mtime1" = "$mtime2" ] || \
4984                         error "lost mtime: $mtime2, should be $mtime1"
4985
4986                 cancel_lru_locks $OSC
4987                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4988         done
4989 }
4990 run_test 39i "write, rename, stat =============================="
4991
4992 test_39j() {
4993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4994
4995         start_full_debug_logging
4996         touch $DIR1/$tfile
4997         sleep 1
4998
4999         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5000         lctl set_param fail_loc=0x80000412
5001         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5002                 error "multiop failed"
5003         local multipid=$!
5004         local mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         mv $DIR1/$tfile $DIR1/$tfile-1
5007
5008         kill -USR1 $multipid
5009         wait $multipid || error "multiop close failed"
5010
5011         for (( i=0; i < 2; i++ )) ; do
5012                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5013                 [ "$mtime1" = "$mtime2" ] ||
5014                         error "mtime is lost on close: $mtime2, " \
5015                               "should be $mtime1"
5016
5017                 cancel_lru_locks
5018                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5019         done
5020         lctl set_param fail_loc=0
5021         stop_full_debug_logging
5022 }
5023 run_test 39j "write, rename, close, stat ======================="
5024
5025 test_39k() {
5026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5027
5028         touch $DIR1/$tfile
5029         sleep 1
5030
5031         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5032         local multipid=$!
5033         local mtime1=`stat -c %Y $DIR1/$tfile`
5034
5035         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5036
5037         kill -USR1 $multipid
5038         wait $multipid || error "multiop close failed"
5039
5040         for (( i=0; i < 2; i++ )) ; do
5041                 local mtime2=`stat -c %Y $DIR1/$tfile`
5042
5043                 [ "$mtime2" = $TEST_39_MTIME ] || \
5044                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5045
5046                 cancel_lru_locks
5047                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048         done
5049 }
5050 run_test 39k "write, utime, close, stat ========================"
5051
5052 # this should be set to future
5053 TEST_39_ATIME=`date -d "1 year" +%s`
5054
5055 test_39l() {
5056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5057         remote_mds_nodsh && skip "remote MDS with nodsh"
5058
5059         local atime_diff=$(do_facet $SINGLEMDS \
5060                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5061         rm -rf $DIR/$tdir
5062         mkdir_on_mdt0 $DIR/$tdir
5063
5064         # test setting directory atime to future
5065         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5066         local atime=$(stat -c %X $DIR/$tdir)
5067         [ "$atime" = $TEST_39_ATIME ] ||
5068                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5069
5070         # test setting directory atime from future to now
5071         local now=$(date +%s)
5072         touch -a -d @$now $DIR/$tdir
5073
5074         atime=$(stat -c %X $DIR/$tdir)
5075         [ "$atime" -eq "$now"  ] ||
5076                 error "atime is not updated from future: $atime, $now"
5077
5078         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5079         sleep 3
5080
5081         # test setting directory atime when now > dir atime + atime_diff
5082         local d1=$(date +%s)
5083         ls $DIR/$tdir
5084         local d2=$(date +%s)
5085         cancel_lru_locks mdc
5086         atime=$(stat -c %X $DIR/$tdir)
5087         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5088                 error "atime is not updated  : $atime, should be $d2"
5089
5090         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5091         sleep 3
5092
5093         # test not setting directory atime when now < dir atime + atime_diff
5094         ls $DIR/$tdir
5095         cancel_lru_locks mdc
5096         atime=$(stat -c %X $DIR/$tdir)
5097         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5098                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5099
5100         do_facet $SINGLEMDS \
5101                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5102 }
5103 run_test 39l "directory atime update ==========================="
5104
5105 test_39m() {
5106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5107
5108         touch $DIR1/$tfile
5109         sleep 2
5110         local far_past_mtime=$(date -d "May 29 1953" +%s)
5111         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5112
5113         touch -m -d @$far_past_mtime $DIR1/$tfile
5114         touch -a -d @$far_past_atime $DIR1/$tfile
5115
5116         for (( i=0; i < 2; i++ )) ; do
5117                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5118                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5119                         error "atime or mtime set incorrectly"
5120
5121                 cancel_lru_locks $OSC
5122                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5123         done
5124 }
5125 run_test 39m "test atime and mtime before 1970"
5126
5127 test_39n() { # LU-3832
5128         remote_mds_nodsh && skip "remote MDS with nodsh"
5129
5130         local atime_diff=$(do_facet $SINGLEMDS \
5131                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5132         local atime0
5133         local atime1
5134         local atime2
5135
5136         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5137
5138         rm -rf $DIR/$tfile
5139         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5140         atime0=$(stat -c %X $DIR/$tfile)
5141
5142         sleep 5
5143         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5144         atime1=$(stat -c %X $DIR/$tfile)
5145
5146         sleep 5
5147         cancel_lru_locks mdc
5148         cancel_lru_locks osc
5149         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5150         atime2=$(stat -c %X $DIR/$tfile)
5151
5152         do_facet $SINGLEMDS \
5153                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5154
5155         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5156         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5157 }
5158 run_test 39n "check that O_NOATIME is honored"
5159
5160 test_39o() {
5161         TESTDIR=$DIR/$tdir/$tfile
5162         [ -e $TESTDIR ] && rm -rf $TESTDIR
5163         mkdir -p $TESTDIR
5164         cd $TESTDIR
5165         links1=2
5166         ls
5167         mkdir a b
5168         ls
5169         links2=$(stat -c %h .)
5170         [ $(($links1 + 2)) != $links2 ] &&
5171                 error "wrong links count $(($links1 + 2)) != $links2"
5172         rmdir b
5173         links3=$(stat -c %h .)
5174         [ $(($links1 + 1)) != $links3 ] &&
5175                 error "wrong links count $links1 != $links3"
5176         return 0
5177 }
5178 run_test 39o "directory cached attributes updated after create"
5179
5180 test_39p() {
5181         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5182
5183         local MDTIDX=1
5184         TESTDIR=$DIR/$tdir/$tdir
5185         [ -e $TESTDIR ] && rm -rf $TESTDIR
5186         test_mkdir -p $TESTDIR
5187         cd $TESTDIR
5188         links1=2
5189         ls
5190         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5191         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5192         ls
5193         links2=$(stat -c %h .)
5194         [ $(($links1 + 2)) != $links2 ] &&
5195                 error "wrong links count $(($links1 + 2)) != $links2"
5196         rmdir remote_dir2
5197         links3=$(stat -c %h .)
5198         [ $(($links1 + 1)) != $links3 ] &&
5199                 error "wrong links count $links1 != $links3"
5200         return 0
5201 }
5202 run_test 39p "remote directory cached attributes updated after create ========"
5203
5204 test_39r() {
5205         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5206                 skip "no atime update on old OST"
5207         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5208                 skip_env "ldiskfs only test"
5209         fi
5210
5211         local saved_adiff
5212         saved_adiff=$(do_facet ost1 \
5213                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5214         stack_trap "do_facet ost1 \
5215                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5216
5217         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5218
5219         $LFS setstripe -i 0 $DIR/$tfile
5220         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5221                 error "can't write initial file"
5222         cancel_lru_locks osc
5223
5224         # exceed atime_diff and access file
5225         sleep 10
5226         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5227                 error "can't udpate atime"
5228
5229         local atime_cli=$(stat -c %X $DIR/$tfile)
5230         echo "client atime: $atime_cli"
5231         # allow atime update to be written to device
5232         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5233         sleep 5
5234
5235         local ostdev=$(ostdevname 1)
5236         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5237         local seq=${fid[3]#0x}
5238         local oid=${fid[1]}
5239         local oid_hex
5240
5241         if [ $seq == 0 ]; then
5242                 oid_hex=${fid[1]}
5243         else
5244                 oid_hex=${fid[2]#0x}
5245         fi
5246         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5247         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5248
5249         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5250         local atime_ost=$(do_facet ost1 "$cmd" |&
5251                           awk -F'[: ]' '/atime:/ { print $4 }')
5252         (( atime_cli == atime_ost )) ||
5253                 error "atime on client $atime_cli != ost $atime_ost"
5254 }
5255 run_test 39r "lazy atime update on OST"
5256
5257 test_39q() { # LU-8041
5258         local testdir=$DIR/$tdir
5259         mkdir -p $testdir
5260         multiop_bg_pause $testdir D_c || error "multiop failed"
5261         local multipid=$!
5262         cancel_lru_locks mdc
5263         kill -USR1 $multipid
5264         local atime=$(stat -c %X $testdir)
5265         [ "$atime" -ne 0 ] || error "atime is zero"
5266 }
5267 run_test 39q "close won't zero out atime"
5268
5269 test_39s() {
5270         local atime0
5271         local atime1
5272         local atime2
5273         local atime3
5274         local atime4
5275
5276         umount_client $MOUNT
5277         mount_client $MOUNT relatime
5278
5279         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5280         atime0=$(stat -c %X $DIR/$tfile)
5281
5282         # First read updates atime
5283         sleep 1
5284         cat $DIR/$tfile >/dev/null
5285         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5286
5287         # Next reads do not update atime
5288         sleep 1
5289         cat $DIR/$tfile >/dev/null
5290         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5291
5292         # If mtime is greater than atime, atime is updated
5293         sleep 1
5294         touch -m $DIR/$tfile # (mtime = now)
5295         sleep 1
5296         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5297         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5298
5299         # Next reads do not update atime
5300         sleep 1
5301         cat $DIR/$tfile >/dev/null
5302         atime4=$(stat -c %X $DIR/$tfile)
5303
5304         # Remount the client to clear 'relatime' option
5305         remount_client $MOUNT
5306
5307         (( atime0 < atime1 )) ||
5308                 error "atime $atime0 should be smaller than $atime1"
5309         (( atime1 == atime2 )) ||
5310                 error "atime $atime1 was updated to $atime2"
5311         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5312         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5313 }
5314 run_test 39s "relatime is supported"
5315
5316 test_40() {
5317         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5318         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5319                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5320         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5321                 error "$tfile is not 4096 bytes in size"
5322 }
5323 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5324
5325 test_41() {
5326         # bug 1553
5327         small_write $DIR/f41 18
5328 }
5329 run_test 41 "test small file write + fstat ====================="
5330
5331 count_ost_writes() {
5332         lctl get_param -n ${OSC}.*.stats |
5333                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5334                         END { printf("%0.0f", writes) }'
5335 }
5336
5337 # decent default
5338 WRITEBACK_SAVE=500
5339 DIRTY_RATIO_SAVE=40
5340 MAX_DIRTY_RATIO=50
5341 BG_DIRTY_RATIO_SAVE=10
5342 MAX_BG_DIRTY_RATIO=25
5343
5344 start_writeback() {
5345         trap 0
5346         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5347         # dirty_ratio, dirty_background_ratio
5348         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5349                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5350                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5351                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5352         else
5353                 # if file not here, we are a 2.4 kernel
5354                 kill -CONT `pidof kupdated`
5355         fi
5356 }
5357
5358 stop_writeback() {
5359         # setup the trap first, so someone cannot exit the test at the
5360         # exact wrong time and mess up a machine
5361         trap start_writeback EXIT
5362         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5363         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5364                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5365                 sysctl -w vm.dirty_writeback_centisecs=0
5366                 sysctl -w vm.dirty_writeback_centisecs=0
5367                 # save and increase /proc/sys/vm/dirty_ratio
5368                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5369                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5370                 # save and increase /proc/sys/vm/dirty_background_ratio
5371                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5372                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5373         else
5374                 # if file not here, we are a 2.4 kernel
5375                 kill -STOP `pidof kupdated`
5376         fi
5377 }
5378
5379 # ensure that all stripes have some grant before we test client-side cache
5380 setup_test42() {
5381         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5382                 dd if=/dev/zero of=$i bs=4k count=1
5383                 rm $i
5384         done
5385 }
5386
5387 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5388 # file truncation, and file removal.
5389 test_42a() {
5390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5391
5392         setup_test42
5393         cancel_lru_locks $OSC
5394         stop_writeback
5395         sync; sleep 1; sync # just to be safe
5396         BEFOREWRITES=`count_ost_writes`
5397         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5398         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5399         AFTERWRITES=`count_ost_writes`
5400         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5401                 error "$BEFOREWRITES < $AFTERWRITES"
5402         start_writeback
5403 }
5404 run_test 42a "ensure that we don't flush on close"
5405
5406 test_42b() {
5407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5408
5409         setup_test42
5410         cancel_lru_locks $OSC
5411         stop_writeback
5412         sync
5413         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5414         BEFOREWRITES=$(count_ost_writes)
5415         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5416         AFTERWRITES=$(count_ost_writes)
5417         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5418                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5419         fi
5420         BEFOREWRITES=$(count_ost_writes)
5421         sync || error "sync: $?"
5422         AFTERWRITES=$(count_ost_writes)
5423         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5424                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5425         fi
5426         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5427         start_writeback
5428         return 0
5429 }
5430 run_test 42b "test destroy of file with cached dirty data ======"
5431
5432 # if these tests just want to test the effect of truncation,
5433 # they have to be very careful.  consider:
5434 # - the first open gets a {0,EOF}PR lock
5435 # - the first write conflicts and gets a {0, count-1}PW
5436 # - the rest of the writes are under {count,EOF}PW
5437 # - the open for truncate tries to match a {0,EOF}PR
5438 #   for the filesize and cancels the PWs.
5439 # any number of fixes (don't get {0,EOF} on open, match
5440 # composite locks, do smarter file size management) fix
5441 # this, but for now we want these tests to verify that
5442 # the cancellation with truncate intent works, so we
5443 # start the file with a full-file pw lock to match against
5444 # until the truncate.
5445 trunc_test() {
5446         test=$1
5447         file=$DIR/$test
5448         offset=$2
5449         cancel_lru_locks $OSC
5450         stop_writeback
5451         # prime the file with 0,EOF PW to match
5452         touch $file
5453         $TRUNCATE $file 0
5454         sync; sync
5455         # now the real test..
5456         dd if=/dev/zero of=$file bs=1024 count=100
5457         BEFOREWRITES=`count_ost_writes`
5458         $TRUNCATE $file $offset
5459         cancel_lru_locks $OSC
5460         AFTERWRITES=`count_ost_writes`
5461         start_writeback
5462 }
5463
5464 test_42c() {
5465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5466
5467         trunc_test 42c 1024
5468         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5469                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5470         rm $file
5471 }
5472 run_test 42c "test partial truncate of file with cached dirty data"
5473
5474 test_42d() {
5475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5476
5477         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5478         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5479         $LCTL set_param debug=+cache
5480
5481         trunc_test 42d 0
5482         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5483                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5484         rm $file
5485 }
5486 run_test 42d "test complete truncate of file with cached dirty data"
5487
5488 test_42e() { # bug22074
5489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5490
5491         local TDIR=$DIR/${tdir}e
5492         local pages=16 # hardcoded 16 pages, don't change it.
5493         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5494         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5495         local max_dirty_mb
5496         local warmup_files
5497
5498         test_mkdir $DIR/${tdir}e
5499         $LFS setstripe -c 1 $TDIR
5500         createmany -o $TDIR/f $files
5501
5502         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5503
5504         # we assume that with $OSTCOUNT files, at least one of them will
5505         # be allocated on OST0.
5506         warmup_files=$((OSTCOUNT * max_dirty_mb))
5507         createmany -o $TDIR/w $warmup_files
5508
5509         # write a large amount of data into one file and sync, to get good
5510         # avail_grant number from OST.
5511         for ((i=0; i<$warmup_files; i++)); do
5512                 idx=$($LFS getstripe -i $TDIR/w$i)
5513                 [ $idx -ne 0 ] && continue
5514                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5515                 break
5516         done
5517         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5518         sync
5519         $LCTL get_param $proc_osc0/cur_dirty_bytes
5520         $LCTL get_param $proc_osc0/cur_grant_bytes
5521
5522         # create as much dirty pages as we can while not to trigger the actual
5523         # RPCs directly. but depends on the env, VFS may trigger flush during this
5524         # period, hopefully we are good.
5525         for ((i=0; i<$warmup_files; i++)); do
5526                 idx=$($LFS getstripe -i $TDIR/w$i)
5527                 [ $idx -ne 0 ] && continue
5528                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5529         done
5530         $LCTL get_param $proc_osc0/cur_dirty_bytes
5531         $LCTL get_param $proc_osc0/cur_grant_bytes
5532
5533         # perform the real test
5534         $LCTL set_param $proc_osc0/rpc_stats 0
5535         for ((;i<$files; i++)); do
5536                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5537                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5538         done
5539         sync
5540         $LCTL get_param $proc_osc0/rpc_stats
5541
5542         local percent=0
5543         local have_ppr=false
5544         $LCTL get_param $proc_osc0/rpc_stats |
5545                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5546                         # skip lines until we are at the RPC histogram data
5547                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5548                         $have_ppr || continue
5549
5550                         # we only want the percent stat for < 16 pages
5551                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5552
5553                         percent=$((percent + WPCT))
5554                         if [[ $percent -gt 15 ]]; then
5555                                 error "less than 16-pages write RPCs" \
5556                                       "$percent% > 15%"
5557                                 break
5558                         fi
5559                 done
5560         rm -rf $TDIR
5561 }
5562 run_test 42e "verify sub-RPC writes are not done synchronously"
5563
5564 test_43A() { # was test_43
5565         test_mkdir $DIR/$tdir
5566         cp -p /bin/ls $DIR/$tdir/$tfile
5567         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5568         pid=$!
5569         # give multiop a chance to open
5570         sleep 1
5571
5572         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5573         kill -USR1 $pid
5574         # Wait for multiop to exit
5575         wait $pid
5576 }
5577 run_test 43A "execution of file opened for write should return -ETXTBSY"
5578
5579 test_43a() {
5580         test_mkdir $DIR/$tdir
5581         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5582         $DIR/$tdir/sleep 60 &
5583         SLEEP_PID=$!
5584         # Make sure exec of $tdir/sleep wins race with truncate
5585         sleep 1
5586         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5587         kill $SLEEP_PID
5588 }
5589 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5590
5591 test_43b() {
5592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5593
5594         test_mkdir $DIR/$tdir
5595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5596         $DIR/$tdir/sleep 60 &
5597         SLEEP_PID=$!
5598         # Make sure exec of $tdir/sleep wins race with truncate
5599         sleep 1
5600         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5601         kill $SLEEP_PID
5602 }
5603 run_test 43b "truncate of file being executed should return -ETXTBSY"
5604
5605 test_43c() {
5606         local testdir="$DIR/$tdir"
5607         test_mkdir $testdir
5608         cp $SHELL $testdir/
5609         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5610                 ( cd $testdir && md5sum -c )
5611 }
5612 run_test 43c "md5sum of copy into lustre"
5613
5614 test_44A() { # was test_44
5615         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5616
5617         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5618         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5619 }
5620 run_test 44A "zero length read from a sparse stripe"
5621
5622 test_44a() {
5623         local nstripe=$($LFS getstripe -c -d $DIR)
5624         [ -z "$nstripe" ] && skip "can't get stripe info"
5625         [[ $nstripe -gt $OSTCOUNT ]] &&
5626                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5627
5628         local stride=$($LFS getstripe -S -d $DIR)
5629         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5630                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5631         fi
5632
5633         OFFSETS="0 $((stride/2)) $((stride-1))"
5634         for offset in $OFFSETS; do
5635                 for i in $(seq 0 $((nstripe-1))); do
5636                         local GLOBALOFFSETS=""
5637                         # size in Bytes
5638                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5639                         local myfn=$DIR/d44a-$size
5640                         echo "--------writing $myfn at $size"
5641                         ll_sparseness_write $myfn $size ||
5642                                 error "ll_sparseness_write"
5643                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5644                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5645                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5646
5647                         for j in $(seq 0 $((nstripe-1))); do
5648                                 # size in Bytes
5649                                 size=$((((j + $nstripe )*$stride + $offset)))
5650                                 ll_sparseness_write $myfn $size ||
5651                                         error "ll_sparseness_write"
5652                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5653                         done
5654                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5655                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5656                         rm -f $myfn
5657                 done
5658         done
5659 }
5660 run_test 44a "test sparse pwrite ==============================="
5661
5662 dirty_osc_total() {
5663         tot=0
5664         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5665                 tot=$(($tot + $d))
5666         done
5667         echo $tot
5668 }
5669 do_dirty_record() {
5670         before=`dirty_osc_total`
5671         echo executing "\"$*\""
5672         eval $*
5673         after=`dirty_osc_total`
5674         echo before $before, after $after
5675 }
5676 test_45() {
5677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5678
5679         f="$DIR/f45"
5680         # Obtain grants from OST if it supports it
5681         echo blah > ${f}_grant
5682         stop_writeback
5683         sync
5684         do_dirty_record "echo blah > $f"
5685         [[ $before -eq $after ]] && error "write wasn't cached"
5686         do_dirty_record "> $f"
5687         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5688         do_dirty_record "echo blah > $f"
5689         [[ $before -eq $after ]] && error "write wasn't cached"
5690         do_dirty_record "sync"
5691         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5692         do_dirty_record "echo blah > $f"
5693         [[ $before -eq $after ]] && error "write wasn't cached"
5694         do_dirty_record "cancel_lru_locks osc"
5695         [[ $before -gt $after ]] ||
5696                 error "lock cancellation didn't lower dirty count"
5697         start_writeback
5698 }
5699 run_test 45 "osc io page accounting ============================"
5700
5701 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5702 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5703 # objects offset and an assert hit when an rpc was built with 1023's mapped
5704 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5705 test_46() {
5706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5707
5708         f="$DIR/f46"
5709         stop_writeback
5710         sync
5711         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5712         sync
5713         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5714         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5715         sync
5716         start_writeback
5717 }
5718 run_test 46 "dirtying a previously written page ================"
5719
5720 # test_47 is removed "Device nodes check" is moved to test_28
5721
5722 test_48a() { # bug 2399
5723         [ "$mds1_FSTYPE" = "zfs" ] &&
5724         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5725                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5726
5727         test_mkdir $DIR/$tdir
5728         cd $DIR/$tdir
5729         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5730         test_mkdir $DIR/$tdir
5731         touch foo || error "'touch foo' failed after recreating cwd"
5732         test_mkdir bar
5733         touch .foo || error "'touch .foo' failed after recreating cwd"
5734         test_mkdir .bar
5735         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5736         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5737         cd . || error "'cd .' failed after recreating cwd"
5738         mkdir . && error "'mkdir .' worked after recreating cwd"
5739         rmdir . && error "'rmdir .' worked after recreating cwd"
5740         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5741         cd .. || error "'cd ..' failed after recreating cwd"
5742 }
5743 run_test 48a "Access renamed working dir (should return errors)="
5744
5745 test_48b() { # bug 2399
5746         rm -rf $DIR/$tdir
5747         test_mkdir $DIR/$tdir
5748         cd $DIR/$tdir
5749         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5750         touch foo && error "'touch foo' worked after removing cwd"
5751         mkdir foo && error "'mkdir foo' worked after removing cwd"
5752         touch .foo && error "'touch .foo' worked after removing cwd"
5753         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5754         ls . > /dev/null && error "'ls .' worked after removing cwd"
5755         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5756         mkdir . && error "'mkdir .' worked after removing cwd"
5757         rmdir . && error "'rmdir .' worked after removing cwd"
5758         ln -s . foo && error "'ln -s .' worked after removing cwd"
5759         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5760 }
5761 run_test 48b "Access removed working dir (should return errors)="
5762
5763 test_48c() { # bug 2350
5764         #lctl set_param debug=-1
5765         #set -vx
5766         rm -rf $DIR/$tdir
5767         test_mkdir -p $DIR/$tdir/dir
5768         cd $DIR/$tdir/dir
5769         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5770         $TRACE touch foo && error "touch foo worked after removing cwd"
5771         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5772         touch .foo && error "touch .foo worked after removing cwd"
5773         mkdir .foo && error "mkdir .foo worked after removing cwd"
5774         $TRACE ls . && error "'ls .' worked after removing cwd"
5775         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5776         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5777         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5778         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5779         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5780 }
5781 run_test 48c "Access removed working subdir (should return errors)"
5782
5783 test_48d() { # bug 2350
5784         #lctl set_param debug=-1
5785         #set -vx
5786         rm -rf $DIR/$tdir
5787         test_mkdir -p $DIR/$tdir/dir
5788         cd $DIR/$tdir/dir
5789         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5790         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5791         $TRACE touch foo && error "'touch foo' worked after removing parent"
5792         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5793         touch .foo && error "'touch .foo' worked after removing parent"
5794         mkdir .foo && error "mkdir .foo worked after removing parent"
5795         $TRACE ls . && error "'ls .' worked after removing parent"
5796         $TRACE ls .. && error "'ls ..' worked after removing parent"
5797         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5798         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5799         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5800         true
5801 }
5802 run_test 48d "Access removed parent subdir (should return errors)"
5803
5804 test_48e() { # bug 4134
5805         #lctl set_param debug=-1
5806         #set -vx
5807         rm -rf $DIR/$tdir
5808         test_mkdir -p $DIR/$tdir/dir
5809         cd $DIR/$tdir/dir
5810         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5811         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5812         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5813         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5814         # On a buggy kernel addition of "touch foo" after cd .. will
5815         # produce kernel oops in lookup_hash_it
5816         touch ../foo && error "'cd ..' worked after recreate parent"
5817         cd $DIR
5818         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5819 }
5820 run_test 48e "Access to recreated parent subdir (should return errors)"
5821
5822 test_48f() {
5823         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5824                 skip "need MDS >= 2.13.55"
5825         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5826         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5827                 skip "needs different host for mdt1 mdt2"
5828         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5829
5830         $LFS mkdir -i0 $DIR/$tdir
5831         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5832
5833         for d in sub1 sub2 sub3; do
5834                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5835                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5836                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5837         done
5838
5839         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5840 }
5841 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5842
5843 test_49() { # LU-1030
5844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5845         remote_ost_nodsh && skip "remote OST with nodsh"
5846
5847         # get ost1 size - $FSNAME-OST0000
5848         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5849                 awk '{ print $4 }')
5850         # write 800M at maximum
5851         [[ $ost1_size -lt 2 ]] && ost1_size=2
5852         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5853
5854         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5855         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5856         local dd_pid=$!
5857
5858         # change max_pages_per_rpc while writing the file
5859         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5860         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5861         # loop until dd process exits
5862         while ps ax -opid | grep -wq $dd_pid; do
5863                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5864                 sleep $((RANDOM % 5 + 1))
5865         done
5866         # restore original max_pages_per_rpc
5867         $LCTL set_param $osc1_mppc=$orig_mppc
5868         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5869 }
5870 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5871
5872 test_50() {
5873         # bug 1485
5874         test_mkdir $DIR/$tdir
5875         cd $DIR/$tdir
5876         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5877 }
5878 run_test 50 "special situations: /proc symlinks  ==============="
5879
5880 test_51a() {    # was test_51
5881         # bug 1516 - create an empty entry right after ".." then split dir
5882         test_mkdir -c1 $DIR/$tdir
5883         touch $DIR/$tdir/foo
5884         $MCREATE $DIR/$tdir/bar
5885         rm $DIR/$tdir/foo
5886         createmany -m $DIR/$tdir/longfile 201
5887         FNUM=202
5888         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5889                 $MCREATE $DIR/$tdir/longfile$FNUM
5890                 FNUM=$(($FNUM + 1))
5891                 echo -n "+"
5892         done
5893         echo
5894         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5895 }
5896 run_test 51a "special situations: split htree with empty entry =="
5897
5898 cleanup_print_lfs_df () {
5899         trap 0
5900         $LFS df
5901         $LFS df -i
5902 }
5903
5904 test_51b() {
5905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5906
5907         local dir=$DIR/$tdir
5908         local nrdirs=$((65536 + 100))
5909
5910         # cleanup the directory
5911         rm -fr $dir
5912
5913         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5914
5915         $LFS df
5916         $LFS df -i
5917         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5918         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5919         [[ $numfree -lt $nrdirs ]] &&
5920                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5921
5922         # need to check free space for the directories as well
5923         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5924         numfree=$(( blkfree / $(fs_inode_ksize) ))
5925         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5926
5927         trap cleanup_print_lfs_df EXIT
5928
5929         # create files
5930         createmany -d $dir/d $nrdirs || {
5931                 unlinkmany $dir/d $nrdirs
5932                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5933         }
5934
5935         # really created :
5936         nrdirs=$(ls -U $dir | wc -l)
5937
5938         # unlink all but 100 subdirectories, then check it still works
5939         local left=100
5940         local delete=$((nrdirs - left))
5941
5942         $LFS df
5943         $LFS df -i
5944
5945         # for ldiskfs the nlink count should be 1, but this is OSD specific
5946         # and so this is listed for informational purposes only
5947         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5948         unlinkmany -d $dir/d $delete ||
5949                 error "unlink of first $delete subdirs failed"
5950
5951         echo "nlink between: $(stat -c %h $dir)"
5952         local found=$(ls -U $dir | wc -l)
5953         [ $found -ne $left ] &&
5954                 error "can't find subdirs: found only $found, expected $left"
5955
5956         unlinkmany -d $dir/d $delete $left ||
5957                 error "unlink of second $left subdirs failed"
5958         # regardless of whether the backing filesystem tracks nlink accurately
5959         # or not, the nlink count shouldn't be more than "." and ".." here
5960         local after=$(stat -c %h $dir)
5961         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5962                 echo "nlink after: $after"
5963
5964         cleanup_print_lfs_df
5965 }
5966 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5967
5968 test_51d_sub() {
5969         local stripecount=$1
5970         local nfiles=$2
5971
5972         log "create files with stripecount=$stripecount"
5973         $LFS setstripe -C $stripecount $DIR/$tdir
5974         createmany -o $DIR/$tdir/t- $nfiles
5975         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5976         for ((n = 0; n < $OSTCOUNT; n++)); do
5977                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5978                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5979                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5980                             '($1 == '$n') { objs += 1 } \
5981                             END { printf("%0.0f", objs) }')
5982                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5983         done
5984         unlinkmany $DIR/$tdir/t- $nfiles
5985         rm  -f $TMP/$tfile
5986
5987         local nlast
5988         local min=4
5989         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5990
5991         # For some combinations of stripecount and OSTCOUNT current code
5992         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5993         # than others. Rather than skipping this test entirely, check that
5994         # and keep testing to ensure imbalance does not get worse. LU-15282
5995         (( (OSTCOUNT == 6 && stripecount == 4) ||
5996            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5997            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5998         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5999                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6000                         { $LFS df && $LFS df -i &&
6001                         error "stripecount=$stripecount: " \
6002                               "OST $n has fewer objects vs. OST $nlast " \
6003                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6004                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6005                         { $LFS df && $LFS df -i &&
6006                         error "stripecount=$stripecount: " \
6007                               "OST $n has more objects vs. OST $nlast " \
6008                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6009
6010                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6011                         { $LFS df && $LFS df -i &&
6012                         error "stripecount=$stripecount: " \
6013                               "OST $n has fewer #0 objects vs. OST $nlast " \
6014                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6015                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6016                         { $LFS df && $LFS df -i &&
6017                         error "stripecount=$stripecount: " \
6018                               "OST $n has more #0 objects vs. OST $nlast " \
6019                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6020         done
6021 }
6022
6023 test_51d() {
6024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6025         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6026
6027         local stripecount
6028         local per_ost=100
6029         local nfiles=$((per_ost * OSTCOUNT))
6030         local mdts=$(comma_list $(mdts_nodes))
6031         local param="osp.*.create_count"
6032         local qos_old=$(do_facet mds1 \
6033                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6034
6035         do_nodes $mdts \
6036                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6037         stack_trap "do_nodes $mdts \
6038                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6039
6040         test_mkdir $DIR/$tdir
6041         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6042         (( dirstripes > 0 )) || dirstripes=1
6043
6044         # Ensure enough OST objects precreated for tests to pass without
6045         # running out of objects.  This is an LOV r-r OST algorithm test,
6046         # not an OST object precreation test.
6047         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6048         (( old >= nfiles )) ||
6049         {
6050                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6051
6052                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6053                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6054
6055                 # trigger precreation from all MDTs for all OSTs
6056                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6057                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6058                 done
6059         }
6060
6061         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6062                 sleep 8  # allow object precreation to catch up
6063                 test_51d_sub $stripecount $nfiles
6064         done
6065 }
6066 run_test 51d "check LOV round-robin OST object distribution"
6067
6068 test_51e() {
6069         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6070                 skip_env "ldiskfs only test"
6071         fi
6072
6073         test_mkdir -c1 $DIR/$tdir
6074         test_mkdir -c1 $DIR/$tdir/d0
6075
6076         touch $DIR/$tdir/d0/foo
6077         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6078                 error "file exceed 65000 nlink limit!"
6079         unlinkmany $DIR/$tdir/d0/f- 65001
6080         return 0
6081 }
6082 run_test 51e "check file nlink limit"
6083
6084 test_51f() {
6085         test_mkdir $DIR/$tdir
6086
6087         local max=100000
6088         local ulimit_old=$(ulimit -n)
6089         local spare=20 # number of spare fd's for scripts/libraries, etc.
6090         local mdt=$($LFS getstripe -m $DIR/$tdir)
6091         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6092
6093         echo "MDT$mdt numfree=$numfree, max=$max"
6094         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6095         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6096                 while ! ulimit -n $((numfree + spare)); do
6097                         numfree=$((numfree * 3 / 4))
6098                 done
6099                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6100         else
6101                 echo "left ulimit at $ulimit_old"
6102         fi
6103
6104         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6105                 unlinkmany $DIR/$tdir/f $numfree
6106                 error "create+open $numfree files in $DIR/$tdir failed"
6107         }
6108         ulimit -n $ulimit_old
6109
6110         # if createmany exits at 120s there will be fewer than $numfree files
6111         unlinkmany $DIR/$tdir/f $numfree || true
6112 }
6113 run_test 51f "check many open files limit"
6114
6115 test_52a() {
6116         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6117         test_mkdir $DIR/$tdir
6118         touch $DIR/$tdir/foo
6119         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6120         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6121         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6122         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6123         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6124                                         error "link worked"
6125         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6126         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6127         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6128                                                      error "lsattr"
6129         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6130         cp -r $DIR/$tdir $TMP/
6131         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6132 }
6133 run_test 52a "append-only flag test (should return errors)"
6134
6135 test_52b() {
6136         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6137         test_mkdir $DIR/$tdir
6138         touch $DIR/$tdir/foo
6139         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6140         cat test > $DIR/$tdir/foo && error "cat test worked"
6141         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6142         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6143         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6144                                         error "link worked"
6145         echo foo >> $DIR/$tdir/foo && error "echo worked"
6146         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6147         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6148         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6149         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6150                                                         error "lsattr"
6151         chattr -i $DIR/$tdir/foo || error "chattr failed"
6152
6153         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6154 }
6155 run_test 52b "immutable flag test (should return errors) ======="
6156
6157 test_53() {
6158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6159         remote_mds_nodsh && skip "remote MDS with nodsh"
6160         remote_ost_nodsh && skip "remote OST with nodsh"
6161
6162         local param
6163         local param_seq
6164         local ostname
6165         local mds_last
6166         local mds_last_seq
6167         local ost_last
6168         local ost_last_seq
6169         local ost_last_id
6170         local ostnum
6171         local node
6172         local found=false
6173         local support_last_seq=true
6174
6175         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6176                 support_last_seq=false
6177
6178         # only test MDT0000
6179         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6180         local value
6181         for value in $(do_facet $SINGLEMDS \
6182                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6183                 param=$(echo ${value[0]} | cut -d "=" -f1)
6184                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6185
6186                 if $support_last_seq; then
6187                         param_seq=$(echo $param |
6188                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6189                         mds_last_seq=$(do_facet $SINGLEMDS \
6190                                        $LCTL get_param -n $param_seq)
6191                 fi
6192                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6193
6194                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6195                 node=$(facet_active_host ost$((ostnum+1)))
6196                 param="obdfilter.$ostname.last_id"
6197                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6198                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6199                         ost_last_id=$ost_last
6200
6201                         if $support_last_seq; then
6202                                 ost_last_id=$(echo $ost_last |
6203                                               awk -F':' '{print $2}' |
6204                                               sed -e "s/^0x//g")
6205                                 ost_last_seq=$(echo $ost_last |
6206                                                awk -F':' '{print $1}')
6207                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6208                         fi
6209
6210                         if [[ $ost_last_id != $mds_last ]]; then
6211                                 error "$ost_last_id != $mds_last"
6212                         else
6213                                 found=true
6214                                 break
6215                         fi
6216                 done
6217         done
6218         $found || error "can not match last_seq/last_id for $mdtosc"
6219         return 0
6220 }
6221 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6222
6223 test_54a() {
6224         perl -MSocket -e ';' || skip "no Socket perl module installed"
6225
6226         $SOCKETSERVER $DIR/socket ||
6227                 error "$SOCKETSERVER $DIR/socket failed: $?"
6228         $SOCKETCLIENT $DIR/socket ||
6229                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6230         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6231 }
6232 run_test 54a "unix domain socket test =========================="
6233
6234 test_54b() {
6235         f="$DIR/f54b"
6236         mknod $f c 1 3
6237         chmod 0666 $f
6238         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6239 }
6240 run_test 54b "char device works in lustre ======================"
6241
6242 find_loop_dev() {
6243         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6244         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6245         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6246
6247         for i in $(seq 3 7); do
6248                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6249                 LOOPDEV=$LOOPBASE$i
6250                 LOOPNUM=$i
6251                 break
6252         done
6253 }
6254
6255 cleanup_54c() {
6256         local rc=0
6257         loopdev="$DIR/loop54c"
6258
6259         trap 0
6260         $UMOUNT $DIR/$tdir || rc=$?
6261         losetup -d $loopdev || true
6262         losetup -d $LOOPDEV || true
6263         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6264         return $rc
6265 }
6266
6267 test_54c() {
6268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6269
6270         loopdev="$DIR/loop54c"
6271
6272         find_loop_dev
6273         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6274         trap cleanup_54c EXIT
6275         mknod $loopdev b 7 $LOOPNUM
6276         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6277         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6278         losetup $loopdev $DIR/$tfile ||
6279                 error "can't set up $loopdev for $DIR/$tfile"
6280         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6281         test_mkdir $DIR/$tdir
6282         mount -t ext2 $loopdev $DIR/$tdir ||
6283                 error "error mounting $loopdev on $DIR/$tdir"
6284         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6285                 error "dd write"
6286         df $DIR/$tdir
6287         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6288                 error "dd read"
6289         cleanup_54c
6290 }
6291 run_test 54c "block device works in lustre ====================="
6292
6293 test_54d() {
6294         local pipe="$DIR/$tfile.pipe"
6295         local string="aaaaaa"
6296
6297         mknod $pipe p
6298         echo -n "$string" > $pipe &
6299         local result=$(cat $pipe)
6300         [[ "$result" == "$string" ]] || error "$result != $string"
6301 }
6302 run_test 54d "fifo device works in lustre ======================"
6303
6304 test_54e() {
6305         f="$DIR/f54e"
6306         string="aaaaaa"
6307         cp -aL /dev/console $f
6308         echo $string > $f || error "echo $string to $f failed"
6309 }
6310 run_test 54e "console/tty device works in lustre ======================"
6311
6312 test_56a() {
6313         local numfiles=3
6314         local numdirs=2
6315         local dir=$DIR/$tdir
6316
6317         rm -rf $dir
6318         test_mkdir -p $dir/dir
6319         for i in $(seq $numfiles); do
6320                 touch $dir/file$i
6321                 touch $dir/dir/file$i
6322         done
6323
6324         local numcomp=$($LFS getstripe --component-count $dir)
6325
6326         [[ $numcomp == 0 ]] && numcomp=1
6327
6328         # test lfs getstripe with --recursive
6329         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6330
6331         [[ $filenum -eq $((numfiles * 2)) ]] ||
6332                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6333         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6334         [[ $filenum -eq $numfiles ]] ||
6335                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6336         echo "$LFS getstripe showed obdidx or l_ost_idx"
6337
6338         # test lfs getstripe with file instead of dir
6339         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6340         [[ $filenum -eq 1 ]] ||
6341                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6342         echo "$LFS getstripe file1 passed"
6343
6344         #test lfs getstripe with --verbose
6345         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6346         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6347                 error "$LFS getstripe --verbose $dir: "\
6348                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6349         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6350                 error "$LFS getstripe $dir: showed lmm_magic"
6351
6352         #test lfs getstripe with -v prints lmm_fid
6353         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6354         local countfids=$((numdirs + numfiles * numcomp))
6355         [[ $filenum -eq $countfids ]] ||
6356                 error "$LFS getstripe -v $dir: "\
6357                       "got $filenum want $countfids lmm_fid"
6358         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6359                 error "$LFS getstripe $dir: showed lmm_fid by default"
6360         echo "$LFS getstripe --verbose passed"
6361
6362         #check for FID information
6363         local fid1=$($LFS getstripe --fid $dir/file1)
6364         local fid2=$($LFS getstripe --verbose $dir/file1 |
6365                      awk '/lmm_fid: / { print $2; exit; }')
6366         local fid3=$($LFS path2fid $dir/file1)
6367
6368         [ "$fid1" != "$fid2" ] &&
6369                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6370         [ "$fid1" != "$fid3" ] &&
6371                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6372         echo "$LFS getstripe --fid passed"
6373
6374         #test lfs getstripe with --obd
6375         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6376                 error "$LFS getstripe --obd wrong_uuid: should return error"
6377
6378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6379
6380         local ostidx=1
6381         local obduuid=$(ostuuid_from_index $ostidx)
6382         local found=$($LFS getstripe -r --obd $obduuid $dir |
6383                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6384
6385         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6386         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6387                 ((filenum--))
6388         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6389                 ((filenum--))
6390
6391         [[ $found -eq $filenum ]] ||
6392                 error "$LFS getstripe --obd: found $found expect $filenum"
6393         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6394                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6395                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6396                 error "$LFS getstripe --obd: should not show file on other obd"
6397         echo "$LFS getstripe --obd passed"
6398 }
6399 run_test 56a "check $LFS getstripe"
6400
6401 test_56b() {
6402         local dir=$DIR/$tdir
6403         local numdirs=3
6404
6405         test_mkdir $dir
6406         for i in $(seq $numdirs); do
6407                 test_mkdir $dir/dir$i
6408         done
6409
6410         # test lfs getdirstripe default mode is non-recursion, which is
6411         # different from lfs getstripe
6412         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6413
6414         [[ $dircnt -eq 1 ]] ||
6415                 error "$LFS getdirstripe: found $dircnt, not 1"
6416         dircnt=$($LFS getdirstripe --recursive $dir |
6417                 grep -c lmv_stripe_count)
6418         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6419                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6420 }
6421 run_test 56b "check $LFS getdirstripe"
6422
6423 test_56bb() {
6424         verify_yaml_available || skip_env "YAML verification not installed"
6425         local output_file=$DIR/$tfile.out
6426
6427         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6428
6429         cat $output_file
6430         cat $output_file | verify_yaml || error "layout is not valid YAML"
6431 }
6432 run_test 56bb "check $LFS getdirstripe layout is YAML"
6433
6434 test_56c() {
6435         remote_ost_nodsh && skip "remote OST with nodsh"
6436
6437         local ost_idx=0
6438         local ost_name=$(ostname_from_index $ost_idx)
6439         local old_status=$(ost_dev_status $ost_idx)
6440         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6441
6442         [[ -z "$old_status" ]] ||
6443                 skip_env "OST $ost_name is in $old_status status"
6444
6445         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6446         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6447                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6448         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6449                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6450                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6451         fi
6452
6453         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6454                 error "$LFS df -v showing inactive devices"
6455         sleep_maxage
6456
6457         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6458
6459         [[ "$new_status" =~ "D" ]] ||
6460                 error "$ost_name status is '$new_status', missing 'D'"
6461         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6462                 [[ "$new_status" =~ "N" ]] ||
6463                         error "$ost_name status is '$new_status', missing 'N'"
6464         fi
6465         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6466                 [[ "$new_status" =~ "f" ]] ||
6467                         error "$ost_name status is '$new_status', missing 'f'"
6468         fi
6469
6470         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6471         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6472                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6473         [[ -z "$p" ]] && restore_lustre_params < $p || true
6474         sleep_maxage
6475
6476         new_status=$(ost_dev_status $ost_idx)
6477         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6478                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6479         # can't check 'f' as devices may actually be on flash
6480 }
6481 run_test 56c "check 'lfs df' showing device status"
6482
6483 test_56d() {
6484         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6485         local osts=$($LFS df -v $MOUNT | grep -c OST)
6486
6487         $LFS df $MOUNT
6488
6489         (( mdts == MDSCOUNT )) ||
6490                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6491         (( osts == OSTCOUNT )) ||
6492                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6493 }
6494 run_test 56d "'lfs df -v' prints only configured devices"
6495
6496 test_56e() {
6497         err_enoent=2 # No such file or directory
6498         err_eopnotsupp=95 # Operation not supported
6499
6500         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6501         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6502
6503         # Check for handling of path not exists
6504         output=$($LFS df $enoent_mnt 2>&1)
6505         ret=$?
6506
6507         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6508         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6509                 error "expect failure $err_enoent, not $ret"
6510
6511         # Check for handling of non-Lustre FS
6512         output=$($LFS df $notsup_mnt)
6513         ret=$?
6514
6515         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6516         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6517                 error "expect success $err_eopnotsupp, not $ret"
6518
6519         # Check for multiple LustreFS argument
6520         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6521         ret=$?
6522
6523         [[ $output -eq 3 && $ret -eq 0 ]] ||
6524                 error "expect success 3, not $output, rc = $ret"
6525
6526         # Check for correct non-Lustre FS handling among multiple
6527         # LustreFS argument
6528         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6529                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6530         ret=$?
6531
6532         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6533                 error "expect success 2, not $output, rc = $ret"
6534 }
6535 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6536
6537 NUMFILES=3
6538 NUMDIRS=3
6539 setup_56() {
6540         local local_tdir="$1"
6541         local local_numfiles="$2"
6542         local local_numdirs="$3"
6543         local dir_params="$4"
6544         local dir_stripe_params="$5"
6545
6546         if [ ! -d "$local_tdir" ] ; then
6547                 test_mkdir -p $dir_stripe_params $local_tdir
6548                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6549                 for i in $(seq $local_numfiles) ; do
6550                         touch $local_tdir/file$i
6551                 done
6552                 for i in $(seq $local_numdirs) ; do
6553                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6554                         for j in $(seq $local_numfiles) ; do
6555                                 touch $local_tdir/dir$i/file$j
6556                         done
6557                 done
6558         fi
6559 }
6560
6561 setup_56_special() {
6562         local local_tdir=$1
6563         local local_numfiles=$2
6564         local local_numdirs=$3
6565
6566         setup_56 $local_tdir $local_numfiles $local_numdirs
6567
6568         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6569                 for i in $(seq $local_numfiles) ; do
6570                         mknod $local_tdir/loop${i}b b 7 $i
6571                         mknod $local_tdir/null${i}c c 1 3
6572                         ln -s $local_tdir/file1 $local_tdir/link${i}
6573                 done
6574                 for i in $(seq $local_numdirs) ; do
6575                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6576                         mknod $local_tdir/dir$i/null${i}c c 1 3
6577                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6578                 done
6579         fi
6580 }
6581
6582 test_56g() {
6583         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6584         local expected=$(($NUMDIRS + 2))
6585
6586         setup_56 $dir $NUMFILES $NUMDIRS
6587
6588         # test lfs find with -name
6589         for i in $(seq $NUMFILES) ; do
6590                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6591
6592                 [ $nums -eq $expected ] ||
6593                         error "lfs find -name '*$i' $dir wrong: "\
6594                               "found $nums, expected $expected"
6595         done
6596 }
6597 run_test 56g "check lfs find -name"
6598
6599 test_56h() {
6600         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6601         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6602
6603         setup_56 $dir $NUMFILES $NUMDIRS
6604
6605         # test lfs find with ! -name
6606         for i in $(seq $NUMFILES) ; do
6607                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6608
6609                 [ $nums -eq $expected ] ||
6610                         error "lfs find ! -name '*$i' $dir wrong: "\
6611                               "found $nums, expected $expected"
6612         done
6613 }
6614 run_test 56h "check lfs find ! -name"
6615
6616 test_56i() {
6617         local dir=$DIR/$tdir
6618
6619         test_mkdir $dir
6620
6621         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6622         local out=$($cmd)
6623
6624         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6625 }
6626 run_test 56i "check 'lfs find -ost UUID' skips directories"
6627
6628 test_56j() {
6629         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6630
6631         setup_56_special $dir $NUMFILES $NUMDIRS
6632
6633         local expected=$((NUMDIRS + 1))
6634         local cmd="$LFS find -type d $dir"
6635         local nums=$($cmd | wc -l)
6636
6637         [ $nums -eq $expected ] ||
6638                 error "'$cmd' wrong: found $nums, expected $expected"
6639 }
6640 run_test 56j "check lfs find -type d"
6641
6642 test_56k() {
6643         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6644
6645         setup_56_special $dir $NUMFILES $NUMDIRS
6646
6647         local expected=$(((NUMDIRS + 1) * NUMFILES))
6648         local cmd="$LFS find -type f $dir"
6649         local nums=$($cmd | wc -l)
6650
6651         [ $nums -eq $expected ] ||
6652                 error "'$cmd' wrong: found $nums, expected $expected"
6653 }
6654 run_test 56k "check lfs find -type f"
6655
6656 test_56l() {
6657         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6658
6659         setup_56_special $dir $NUMFILES $NUMDIRS
6660
6661         local expected=$((NUMDIRS + NUMFILES))
6662         local cmd="$LFS find -type b $dir"
6663         local nums=$($cmd | wc -l)
6664
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56l "check lfs find -type b"
6669
6670 test_56m() {
6671         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6672
6673         setup_56_special $dir $NUMFILES $NUMDIRS
6674
6675         local expected=$((NUMDIRS + NUMFILES))
6676         local cmd="$LFS find -type c $dir"
6677         local nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56m "check lfs find -type c"
6682
6683 test_56n() {
6684         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6685         setup_56_special $dir $NUMFILES $NUMDIRS
6686
6687         local expected=$((NUMDIRS + NUMFILES))
6688         local cmd="$LFS find -type l $dir"
6689         local nums=$($cmd | wc -l)
6690
6691         [ $nums -eq $expected ] ||
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693 }
6694 run_test 56n "check lfs find -type l"
6695
6696 test_56o() {
6697         local dir=$DIR/$tdir
6698
6699         setup_56 $dir $NUMFILES $NUMDIRS
6700         utime $dir/file1 > /dev/null || error "utime (1)"
6701         utime $dir/file2 > /dev/null || error "utime (2)"
6702         utime $dir/dir1 > /dev/null || error "utime (3)"
6703         utime $dir/dir2 > /dev/null || error "utime (4)"
6704         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6705         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6706
6707         local expected=4
6708         local nums=$($LFS find -mtime +0 $dir | wc -l)
6709
6710         [ $nums -eq $expected ] ||
6711                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6712
6713         expected=12
6714         cmd="$LFS find -mtime 0 $dir"
6715         nums=$($cmd | wc -l)
6716         [ $nums -eq $expected ] ||
6717                 error "'$cmd' wrong: found $nums, expected $expected"
6718 }
6719 run_test 56o "check lfs find -mtime for old files"
6720
6721 test_56ob() {
6722         local dir=$DIR/$tdir
6723         local expected=1
6724         local count=0
6725
6726         # just to make sure there is something that won't be found
6727         test_mkdir $dir
6728         touch $dir/$tfile.now
6729
6730         for age in year week day hour min; do
6731                 count=$((count + 1))
6732
6733                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6734                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6735                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6736
6737                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6738                 local nums=$($cmd | wc -l)
6739                 [ $nums -eq $expected ] ||
6740                         error "'$cmd' wrong: found $nums, expected $expected"
6741
6742                 cmd="$LFS find $dir -atime $count${age:0:1}"
6743                 nums=$($cmd | wc -l)
6744                 [ $nums -eq $expected ] ||
6745                         error "'$cmd' wrong: found $nums, expected $expected"
6746         done
6747
6748         sleep 2
6749         cmd="$LFS find $dir -ctime +1s -type f"
6750         nums=$($cmd | wc -l)
6751         (( $nums == $count * 2 + 1)) ||
6752                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6753 }
6754 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6755
6756 test_newerXY_base() {
6757         local x=$1
6758         local y=$2
6759         local dir=$DIR/$tdir
6760         local ref
6761         local negref
6762
6763         if [ $y == "t" ]; then
6764                 if [ $x == "b" ]; then
6765                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6766                 else
6767                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6768                 fi
6769         else
6770                 ref=$DIR/$tfile.newer.$x$y
6771                 touch $ref || error "touch $ref failed"
6772         fi
6773
6774         echo "before = $ref"
6775         sleep 2
6776         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6777         sleep 2
6778         if [ $y == "t" ]; then
6779                 if [ $x == "b" ]; then
6780                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6781                 else
6782                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6783                 fi
6784         else
6785                 negref=$DIR/$tfile.negnewer.$x$y
6786                 touch $negref || error "touch $negref failed"
6787         fi
6788
6789         echo "after = $negref"
6790         local cmd="$LFS find $dir -newer$x$y $ref"
6791         local nums=$(eval $cmd | wc -l)
6792         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6793
6794         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6795                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6796
6797         cmd="$LFS find $dir ! -newer$x$y $negref"
6798         nums=$(eval $cmd | wc -l)
6799         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6800                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6801
6802         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6803         nums=$(eval $cmd | wc -l)
6804         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6805                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6806
6807         rm -rf $DIR/*
6808 }
6809
6810 test_56oc() {
6811         test_newerXY_base "a" "a"
6812         test_newerXY_base "a" "m"
6813         test_newerXY_base "a" "c"
6814         test_newerXY_base "m" "a"
6815         test_newerXY_base "m" "m"
6816         test_newerXY_base "m" "c"
6817         test_newerXY_base "c" "a"
6818         test_newerXY_base "c" "m"
6819         test_newerXY_base "c" "c"
6820
6821         test_newerXY_base "a" "t"
6822         test_newerXY_base "m" "t"
6823         test_newerXY_base "c" "t"
6824
6825         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6826            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6827                 ! btime_supported && echo "btime unsupported" && return 0
6828
6829         test_newerXY_base "b" "b"
6830         test_newerXY_base "b" "t"
6831 }
6832 run_test 56oc "check lfs find -newerXY work"
6833
6834 btime_supported() {
6835         local dir=$DIR/$tdir
6836         local rc
6837
6838         mkdir -p $dir
6839         touch $dir/$tfile
6840         $LFS find $dir -btime -1d -type f
6841         rc=$?
6842         rm -rf $dir
6843         return $rc
6844 }
6845
6846 test_56od() {
6847         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6848                 ! btime_supported && skip "btime unsupported on MDS"
6849
6850         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6851                 ! btime_supported && skip "btime unsupported on clients"
6852
6853         local dir=$DIR/$tdir
6854         local ref=$DIR/$tfile.ref
6855         local negref=$DIR/$tfile.negref
6856
6857         mkdir $dir || error "mkdir $dir failed"
6858         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6859         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6860         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6861         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6862         touch $ref || error "touch $ref failed"
6863         # sleep 3 seconds at least
6864         sleep 3
6865
6866         local before=$(do_facet mds1 date +%s)
6867         local skew=$(($(date +%s) - before + 1))
6868
6869         if (( skew < 0 && skew > -5 )); then
6870                 sleep $((0 - skew + 1))
6871                 skew=0
6872         fi
6873
6874         # Set the dir stripe params to limit files all on MDT0,
6875         # otherwise we need to calc the max clock skew between
6876         # the client and MDTs.
6877         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6878         sleep 2
6879         touch $negref || error "touch $negref failed"
6880
6881         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6882         local nums=$($cmd | wc -l)
6883         local expected=$(((NUMFILES + 1) * NUMDIRS))
6884
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6889         nums=$($cmd | wc -l)
6890         expected=$((NUMFILES + 1))
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         [ $skew -lt 0 ] && return
6895
6896         local after=$(do_facet mds1 date +%s)
6897         local age=$((after - before + 1 + skew))
6898
6899         cmd="$LFS find $dir -btime -${age}s -type f"
6900         nums=$($cmd | wc -l)
6901         expected=$(((NUMFILES + 1) * NUMDIRS))
6902
6903         echo "Clock skew between client and server: $skew, age:$age"
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906
6907         expected=$(($NUMDIRS + 1))
6908         cmd="$LFS find $dir -btime -${age}s -type d"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912         rm -f $ref $negref || error "Failed to remove $ref $negref"
6913 }
6914 run_test 56od "check lfs find -btime with units"
6915
6916 test_56p() {
6917         [ $RUNAS_ID -eq $UID ] &&
6918                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6919
6920         local dir=$DIR/$tdir
6921
6922         setup_56 $dir $NUMFILES $NUMDIRS
6923         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6924
6925         local expected=$NUMFILES
6926         local cmd="$LFS find -uid $RUNAS_ID $dir"
6927         local nums=$($cmd | wc -l)
6928
6929         [ $nums -eq $expected ] ||
6930                 error "'$cmd' wrong: found $nums, expected $expected"
6931
6932         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6933         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6934         nums=$($cmd | wc -l)
6935         [ $nums -eq $expected ] ||
6936                 error "'$cmd' wrong: found $nums, expected $expected"
6937 }
6938 run_test 56p "check lfs find -uid and ! -uid"
6939
6940 test_56q() {
6941         [ $RUNAS_ID -eq $UID ] &&
6942                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6943
6944         local dir=$DIR/$tdir
6945
6946         setup_56 $dir $NUMFILES $NUMDIRS
6947         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6948
6949         local expected=$NUMFILES
6950         local cmd="$LFS find -gid $RUNAS_GID $dir"
6951         local nums=$($cmd | wc -l)
6952
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6957         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6958         nums=$($cmd | wc -l)
6959         [ $nums -eq $expected ] ||
6960                 error "'$cmd' wrong: found $nums, expected $expected"
6961 }
6962 run_test 56q "check lfs find -gid and ! -gid"
6963
6964 test_56r() {
6965         local dir=$DIR/$tdir
6966
6967         setup_56 $dir $NUMFILES $NUMDIRS
6968
6969         local expected=12
6970         local cmd="$LFS find -size 0 -type f -lazy $dir"
6971         local nums=$($cmd | wc -l)
6972
6973         [ $nums -eq $expected ] ||
6974                 error "'$cmd' wrong: found $nums, expected $expected"
6975         cmd="$LFS find -size 0 -type f $dir"
6976         nums=$($cmd | wc -l)
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=0
6981         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985         cmd="$LFS find ! -size 0 -type f $dir"
6986         nums=$($cmd | wc -l)
6987         [ $nums -eq $expected ] ||
6988                 error "'$cmd' wrong: found $nums, expected $expected"
6989
6990         echo "test" > $dir/$tfile
6991         echo "test2" > $dir/$tfile.2 && sync
6992         expected=1
6993         cmd="$LFS find -size 5 -type f -lazy $dir"
6994         nums=$($cmd | wc -l)
6995         [ $nums -eq $expected ] ||
6996                 error "'$cmd' wrong: found $nums, expected $expected"
6997         cmd="$LFS find -size 5 -type f $dir"
6998         nums=$($cmd | wc -l)
6999         [ $nums -eq $expected ] ||
7000                 error "'$cmd' wrong: found $nums, expected $expected"
7001
7002         expected=1
7003         cmd="$LFS find -size +5 -type f -lazy $dir"
7004         nums=$($cmd | wc -l)
7005         [ $nums -eq $expected ] ||
7006                 error "'$cmd' wrong: found $nums, expected $expected"
7007         cmd="$LFS find -size +5 -type f $dir"
7008         nums=$($cmd | wc -l)
7009         [ $nums -eq $expected ] ||
7010                 error "'$cmd' wrong: found $nums, expected $expected"
7011
7012         expected=2
7013         cmd="$LFS find -size +0 -type f -lazy $dir"
7014         nums=$($cmd | wc -l)
7015         [ $nums -eq $expected ] ||
7016                 error "'$cmd' wrong: found $nums, expected $expected"
7017         cmd="$LFS find -size +0 -type f $dir"
7018         nums=$($cmd | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021
7022         expected=2
7023         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7024         nums=$($cmd | wc -l)
7025         [ $nums -eq $expected ] ||
7026                 error "'$cmd' wrong: found $nums, expected $expected"
7027         cmd="$LFS find ! -size -5 -type f $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031
7032         expected=12
7033         cmd="$LFS find -size -5 -type f -lazy $dir"
7034         nums=$($cmd | wc -l)
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037         cmd="$LFS find -size -5 -type f $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041 }
7042 run_test 56r "check lfs find -size works"
7043
7044 test_56ra_sub() {
7045         local expected=$1
7046         local glimpses=$2
7047         local cmd="$3"
7048
7049         cancel_lru_locks $OSC
7050
7051         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7052         local nums=$($cmd | wc -l)
7053
7054         [ $nums -eq $expected ] ||
7055                 error "'$cmd' wrong: found $nums, expected $expected"
7056
7057         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7058
7059         if (( rpcs_before + glimpses != rpcs_after )); then
7060                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7061                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7062
7063                 if [[ $glimpses == 0 ]]; then
7064                         error "'$cmd' should not send glimpse RPCs to OST"
7065                 else
7066                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7067                 fi
7068         fi
7069 }
7070
7071 test_56ra() {
7072         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7073                 skip "MDS < 2.12.58 doesn't return LSOM data"
7074         local dir=$DIR/$tdir
7075         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7076
7077         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7078
7079         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7080         $LCTL set_param -n llite.*.statahead_agl=0
7081         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7082
7083         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7084         # open and close all files to ensure LSOM is updated
7085         cancel_lru_locks $OSC
7086         find $dir -type f | xargs cat > /dev/null
7087
7088         #   expect_found  glimpse_rpcs  command_to_run
7089         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7090         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7091         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7092         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7093
7094         echo "test" > $dir/$tfile
7095         echo "test2" > $dir/$tfile.2 && sync
7096         cancel_lru_locks $OSC
7097         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7098
7099         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7100         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7101         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7102         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7103
7104         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7105         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7106         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7107         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7108         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7109         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7110 }
7111 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7112
7113 test_56rb() {
7114         local dir=$DIR/$tdir
7115         local tmp=$TMP/$tfile.log
7116         local mdt_idx;
7117
7118         test_mkdir -p $dir || error "failed to mkdir $dir"
7119         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7120                 error "failed to setstripe $dir/$tfile"
7121         mdt_idx=$($LFS getdirstripe -i $dir)
7122         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7123
7124         stack_trap "rm -f $tmp" EXIT
7125         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7126         ! grep -q obd_uuid $tmp ||
7127                 error "failed to find --size +100K --ost 0 $dir"
7128         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7129         ! grep -q obd_uuid $tmp ||
7130                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7131 }
7132 run_test 56rb "check lfs find --size --ost/--mdt works"
7133
7134 test_56rc() {
7135         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7136         local dir=$DIR/$tdir
7137         local found
7138
7139         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7140         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7141         (( $MDSCOUNT > 2 )) &&
7142                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7143         mkdir $dir/$tdir-{1..10}
7144         touch $dir/$tfile-{1..10}
7145
7146         found=$($LFS find $dir --mdt-count 2 | wc -l)
7147         expect=11
7148         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7149
7150         found=$($LFS find $dir -T +1 | wc -l)
7151         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7152         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7153
7154         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7155         expect=11
7156         (( $found == $expect )) || error "found $found all_char, expect $expect"
7157
7158         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7159         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7160         (( $found == $expect )) || error "found $found all_char, expect $expect"
7161 }
7162 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7163
7164 test_56s() { # LU-611 #LU-9369
7165         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7166
7167         local dir=$DIR/$tdir
7168         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7169
7170         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7171         for i in $(seq $NUMDIRS); do
7172                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7173         done
7174
7175         local expected=$NUMDIRS
7176         local cmd="$LFS find -c $OSTCOUNT $dir"
7177         local nums=$($cmd | wc -l)
7178
7179         [ $nums -eq $expected ] || {
7180                 $LFS getstripe -R $dir
7181                 error "'$cmd' wrong: found $nums, expected $expected"
7182         }
7183
7184         expected=$((NUMDIRS + onestripe))
7185         cmd="$LFS find -stripe-count +0 -type f $dir"
7186         nums=$($cmd | wc -l)
7187         [ $nums -eq $expected ] || {
7188                 $LFS getstripe -R $dir
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190         }
7191
7192         expected=$onestripe
7193         cmd="$LFS find -stripe-count 1 -type f $dir"
7194         nums=$($cmd | wc -l)
7195         [ $nums -eq $expected ] || {
7196                 $LFS getstripe -R $dir
7197                 error "'$cmd' wrong: found $nums, expected $expected"
7198         }
7199
7200         cmd="$LFS find -stripe-count -2 -type f $dir"
7201         nums=$($cmd | wc -l)
7202         [ $nums -eq $expected ] || {
7203                 $LFS getstripe -R $dir
7204                 error "'$cmd' wrong: found $nums, expected $expected"
7205         }
7206
7207         expected=0
7208         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7209         nums=$($cmd | wc -l)
7210         [ $nums -eq $expected ] || {
7211                 $LFS getstripe -R $dir
7212                 error "'$cmd' wrong: found $nums, expected $expected"
7213         }
7214 }
7215 run_test 56s "check lfs find -stripe-count works"
7216
7217 test_56t() { # LU-611 #LU-9369
7218         local dir=$DIR/$tdir
7219
7220         setup_56 $dir 0 $NUMDIRS
7221         for i in $(seq $NUMDIRS); do
7222                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7223         done
7224
7225         local expected=$NUMDIRS
7226         local cmd="$LFS find -S 8M $dir"
7227         local nums=$($cmd | wc -l)
7228
7229         [ $nums -eq $expected ] || {
7230                 $LFS getstripe -R $dir
7231                 error "'$cmd' wrong: found $nums, expected $expected"
7232         }
7233         rm -rf $dir
7234
7235         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7236
7237         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7238
7239         expected=$(((NUMDIRS + 1) * NUMFILES))
7240         cmd="$LFS find -stripe-size 512k -type f $dir"
7241         nums=$($cmd | wc -l)
7242         [ $nums -eq $expected ] ||
7243                 error "'$cmd' wrong: found $nums, expected $expected"
7244
7245         cmd="$LFS find -stripe-size +320k -type f $dir"
7246         nums=$($cmd | wc -l)
7247         [ $nums -eq $expected ] ||
7248                 error "'$cmd' wrong: found $nums, expected $expected"
7249
7250         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7251         cmd="$LFS find -stripe-size +200k -type f $dir"
7252         nums=$($cmd | wc -l)
7253         [ $nums -eq $expected ] ||
7254                 error "'$cmd' wrong: found $nums, expected $expected"
7255
7256         cmd="$LFS find -stripe-size -640k -type f $dir"
7257         nums=$($cmd | wc -l)
7258         [ $nums -eq $expected ] ||
7259                 error "'$cmd' wrong: found $nums, expected $expected"
7260
7261         expected=4
7262         cmd="$LFS find -stripe-size 256k -type f $dir"
7263         nums=$($cmd | wc -l)
7264         [ $nums -eq $expected ] ||
7265                 error "'$cmd' wrong: found $nums, expected $expected"
7266
7267         cmd="$LFS find -stripe-size -320k -type f $dir"
7268         nums=$($cmd | wc -l)
7269         [ $nums -eq $expected ] ||
7270                 error "'$cmd' wrong: found $nums, expected $expected"
7271
7272         expected=0
7273         cmd="$LFS find -stripe-size 1024k -type f $dir"
7274         nums=$($cmd | wc -l)
7275         [ $nums -eq $expected ] ||
7276                 error "'$cmd' wrong: found $nums, expected $expected"
7277 }
7278 run_test 56t "check lfs find -stripe-size works"
7279
7280 test_56u() { # LU-611
7281         local dir=$DIR/$tdir
7282
7283         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7284
7285         if [[ $OSTCOUNT -gt 1 ]]; then
7286                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7287                 onestripe=4
7288         else
7289                 onestripe=0
7290         fi
7291
7292         local expected=$(((NUMDIRS + 1) * NUMFILES))
7293         local cmd="$LFS find -stripe-index 0 -type f $dir"
7294         local nums=$($cmd | wc -l)
7295
7296         [ $nums -eq $expected ] ||
7297                 error "'$cmd' wrong: found $nums, expected $expected"
7298
7299         expected=$onestripe
7300         cmd="$LFS find -stripe-index 1 -type f $dir"
7301         nums=$($cmd | wc -l)
7302         [ $nums -eq $expected ] ||
7303                 error "'$cmd' wrong: found $nums, expected $expected"
7304
7305         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7306         nums=$($cmd | wc -l)
7307         [ $nums -eq $expected ] ||
7308                 error "'$cmd' wrong: found $nums, expected $expected"
7309
7310         expected=0
7311         # This should produce an error and not return any files
7312         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7313         nums=$($cmd 2>/dev/null | wc -l)
7314         [ $nums -eq $expected ] ||
7315                 error "'$cmd' wrong: found $nums, expected $expected"
7316
7317         if [[ $OSTCOUNT -gt 1 ]]; then
7318                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7319                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7320                 nums=$($cmd | wc -l)
7321                 [ $nums -eq $expected ] ||
7322                         error "'$cmd' wrong: found $nums, expected $expected"
7323         fi
7324 }
7325 run_test 56u "check lfs find -stripe-index works"
7326
7327 test_56v() {
7328         local mdt_idx=0
7329         local dir=$DIR/$tdir
7330
7331         setup_56 $dir $NUMFILES $NUMDIRS
7332
7333         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7334         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7335
7336         for file in $($LFS find -m $UUID $dir); do
7337                 file_midx=$($LFS getstripe -m $file)
7338                 [ $file_midx -eq $mdt_idx ] ||
7339                         error "lfs find -m $UUID != getstripe -m $file_midx"
7340         done
7341 }
7342 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7343
7344 test_56wa() {
7345         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7347
7348         local dir=$DIR/$tdir
7349
7350         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7351
7352         local stripe_size=$($LFS getstripe -S -d $dir) ||
7353                 error "$LFS getstripe -S -d $dir failed"
7354         stripe_size=${stripe_size%% *}
7355
7356         local file_size=$((stripe_size * OSTCOUNT))
7357         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7358         local required_space=$((file_num * file_size))
7359         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7360                            head -n1)
7361         (( free_space >= required_space / 1024 )) ||
7362                 skip_env "need $required_space, have $free_space kbytes"
7363
7364         local dd_bs=65536
7365         local dd_count=$((file_size / dd_bs))
7366
7367         # write data into the files
7368         local i
7369         local j
7370         local file
7371
7372         for ((i = 1; i <= NUMFILES; i++ )); do
7373                 file=$dir/file$i
7374                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7375                         error "write data into $file failed"
7376         done
7377         for ((i = 1; i <= NUMDIRS; i++ )); do
7378                 for ((j = 1; j <= NUMFILES; j++ )); do
7379                         file=$dir/dir$i/file$j
7380                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7381                                 error "write data into $file failed"
7382                 done
7383         done
7384
7385         # $LFS_MIGRATE will fail if hard link migration is unsupported
7386         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7387                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7388                         error "creating links to $dir/dir1/file1 failed"
7389         fi
7390
7391         local expected=-1
7392
7393         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7394
7395         # lfs_migrate file
7396         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7397
7398         echo "$cmd"
7399         eval $cmd || error "$cmd failed"
7400
7401         check_stripe_count $dir/file1 $expected
7402
7403         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7404                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7405                 # OST 1 if it is on OST 0. This file is small enough to
7406                 # be on only one stripe.
7407                 file=$dir/migr_1_ost
7408                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7409                         error "write data into $file failed"
7410                 local obdidx=$($LFS getstripe -i $file)
7411                 local oldmd5=$(md5sum $file)
7412                 local newobdidx=0
7413
7414                 (( obdidx != 0 )) || newobdidx=1
7415                 cmd="$LFS migrate -i $newobdidx $file"
7416                 echo $cmd
7417                 eval $cmd || error "$cmd failed"
7418
7419                 local realobdix=$($LFS getstripe -i $file)
7420                 local newmd5=$(md5sum $file)
7421
7422                 (( $newobdidx == $realobdix )) ||
7423                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7424                 [[ "$oldmd5" == "$newmd5" ]] ||
7425                         error "md5sum differ: $oldmd5, $newmd5"
7426         fi
7427
7428         # lfs_migrate dir
7429         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7430         echo "$cmd"
7431         eval $cmd || error "$cmd failed"
7432
7433         for (( j = 1; j <= NUMFILES; j++ )); do
7434                 check_stripe_count $dir/dir1/file$j $expected
7435         done
7436
7437         # lfs_migrate works with lfs find
7438         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7439              $LFS_MIGRATE -y -c $expected"
7440         echo "$cmd"
7441         eval $cmd || error "$cmd failed"
7442
7443         for (( i = 2; i <= NUMFILES; i++ )); do
7444                 check_stripe_count $dir/file$i $expected
7445         done
7446         for (( i = 2; i <= NUMDIRS; i++ )); do
7447                 for (( j = 1; j <= NUMFILES; j++ )); do
7448                         check_stripe_count $dir/dir$i/file$j $expected
7449                 done
7450         done
7451 }
7452 run_test 56wa "check lfs_migrate -c stripe_count works"
7453
7454 test_56wb() {
7455         local file1=$DIR/$tdir/file1
7456         local create_pool=false
7457         local initial_pool=$($LFS getstripe -p $DIR)
7458         local pool_list=()
7459         local pool=""
7460
7461         echo -n "Creating test dir..."
7462         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7463         echo "done."
7464
7465         echo -n "Creating test file..."
7466         touch $file1 || error "cannot create file"
7467         echo "done."
7468
7469         echo -n "Detecting existing pools..."
7470         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7471
7472         if [ ${#pool_list[@]} -gt 0 ]; then
7473                 echo "${pool_list[@]}"
7474                 for thispool in "${pool_list[@]}"; do
7475                         if [[ -z "$initial_pool" ||
7476                               "$initial_pool" != "$thispool" ]]; then
7477                                 pool="$thispool"
7478                                 echo "Using existing pool '$pool'"
7479                                 break
7480                         fi
7481                 done
7482         else
7483                 echo "none detected."
7484         fi
7485         if [ -z "$pool" ]; then
7486                 pool=${POOL:-testpool}
7487                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7488                 echo -n "Creating pool '$pool'..."
7489                 create_pool=true
7490                 pool_add $pool &> /dev/null ||
7491                         error "pool_add failed"
7492                 echo "done."
7493
7494                 echo -n "Adding target to pool..."
7495                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7496                         error "pool_add_targets failed"
7497                 echo "done."
7498         fi
7499
7500         echo -n "Setting pool using -p option..."
7501         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7502                 error "migrate failed rc = $?"
7503         echo "done."
7504
7505         echo -n "Verifying test file is in pool after migrating..."
7506         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7507                 error "file was not migrated to pool $pool"
7508         echo "done."
7509
7510         echo -n "Removing test file from pool '$pool'..."
7511         # "lfs migrate $file" won't remove the file from the pool
7512         # until some striping information is changed.
7513         $LFS migrate -c 1 $file1 &> /dev/null ||
7514                 error "cannot remove from pool"
7515         [ "$($LFS getstripe -p $file1)" ] &&
7516                 error "pool still set"
7517         echo "done."
7518
7519         echo -n "Setting pool using --pool option..."
7520         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7521                 error "migrate failed rc = $?"
7522         echo "done."
7523
7524         # Clean up
7525         rm -f $file1
7526         if $create_pool; then
7527                 destroy_test_pools 2> /dev/null ||
7528                         error "destroy test pools failed"
7529         fi
7530 }
7531 run_test 56wb "check lfs_migrate pool support"
7532
7533 test_56wc() {
7534         local file1="$DIR/$tdir/$tfile"
7535         local md5
7536         local parent_ssize
7537         local parent_scount
7538         local cur_ssize
7539         local cur_scount
7540         local orig_ssize
7541         local new_scount
7542         local cur_comp
7543
7544         echo -n "Creating test dir..."
7545         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7546         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7547                 error "cannot set stripe by '-S 1M -c 1'"
7548         echo "done"
7549
7550         echo -n "Setting initial stripe for test file..."
7551         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7552                 error "cannot set stripe"
7553         cur_ssize=$($LFS getstripe -S "$file1")
7554         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7555         echo "done."
7556
7557         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7558         stack_trap "rm -f $file1"
7559         md5="$(md5sum $file1)"
7560
7561         # File currently set to -S 512K -c 1
7562
7563         # Ensure -c and -S options are rejected when -R is set
7564         echo -n "Verifying incompatible options are detected..."
7565         $LFS_MIGRATE -R -c 1 "$file1" &&
7566                 error "incompatible -R and -c options not detected"
7567         $LFS_MIGRATE -R -S 1M "$file1" &&
7568                 error "incompatible -R and -S options not detected"
7569         $LFS_MIGRATE -R -p pool "$file1" &&
7570                 error "incompatible -R and -p options not detected"
7571         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7572                 error "incompatible -R and -E options not detected"
7573         $LFS_MIGRATE -R -A "$file1" &&
7574                 error "incompatible -R and -A options not detected"
7575         $LFS_MIGRATE -A -c 1 "$file1" &&
7576                 error "incompatible -A and -c options not detected"
7577         $LFS_MIGRATE -A -S 1M "$file1" &&
7578                 error "incompatible -A and -S options not detected"
7579         $LFS_MIGRATE -A -p pool "$file1" &&
7580                 error "incompatible -A and -p options not detected"
7581         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7582                 error "incompatible -A and -E options not detected"
7583         echo "done."
7584
7585         # Ensure unrecognized options are passed through to 'lfs migrate'
7586         echo -n "Verifying -S option is passed through to lfs migrate..."
7587         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7588         cur_ssize=$($LFS getstripe -S "$file1")
7589         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7590         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7591         echo "done."
7592
7593         # File currently set to -S 1M -c 1
7594
7595         # Ensure long options are supported
7596         echo -n "Verifying long options supported..."
7597         $LFS_MIGRATE --non-block "$file1" ||
7598                 error "long option without argument not supported"
7599         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7600                 error "long option with argument not supported"
7601         cur_ssize=$($LFS getstripe -S "$file1")
7602         (( cur_ssize == 524288 )) ||
7603                 error "migrate --stripe-size $cur_ssize != 524288"
7604         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7605         echo "done."
7606
7607         # File currently set to -S 512K -c 1
7608
7609         if (( OSTCOUNT > 1 )); then
7610                 echo -n "Verifying explicit stripe count can be set..."
7611                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7612                 cur_scount=$($LFS getstripe -c "$file1")
7613                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7614                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7615                         error "file data has changed (3)"
7616                 echo "done."
7617         fi
7618
7619         # File currently set to -S 512K -c 1 or -S 512K -c 2
7620
7621         # Ensure parent striping is used if -R is set, and no stripe
7622         # count or size is specified
7623         echo -n "Setting stripe for parent directory..."
7624         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7625                 error "cannot set stripe '-S 2M -c 1'"
7626         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7627         echo "done."
7628
7629         echo -n "Verifying restripe option uses parent stripe settings..."
7630         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7631         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7632         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7633         cur_ssize=$($LFS getstripe -S "$file1")
7634         (( cur_ssize == parent_ssize )) ||
7635                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7636         cur_scount=$($LFS getstripe -c "$file1")
7637         (( cur_scount == parent_scount )) ||
7638                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7639         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7640         echo "done."
7641
7642         # File currently set to -S 1M -c 1
7643
7644         # Ensure striping is preserved if -R is not set, and no stripe
7645         # count or size is specified
7646         echo -n "Verifying striping size preserved when not specified..."
7647         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7648         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7649                 error "cannot set stripe on parent directory"
7650         $LFS_MIGRATE "$file1" || error "migrate failed"
7651         cur_ssize=$($LFS getstripe -S "$file1")
7652         (( cur_ssize == orig_ssize )) ||
7653                 error "migrate by default $cur_ssize != $orig_ssize"
7654         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7655         echo "done."
7656
7657         # Ensure file name properly detected when final option has no argument
7658         echo -n "Verifying file name properly detected..."
7659         $LFS_MIGRATE "$file1" ||
7660                 error "file name interpreted as option argument"
7661         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7662         echo "done."
7663
7664         # Ensure PFL arguments are passed through properly
7665         echo -n "Verifying PFL options passed through..."
7666         new_scount=$(((OSTCOUNT + 1) / 2))
7667         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7668                 error "migrate PFL arguments failed"
7669         cur_comp=$($LFS getstripe --comp-count $file1)
7670         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7671         cur_scount=$($LFS getstripe --stripe-count $file1)
7672         (( cur_scount == new_scount)) ||
7673                 error "PFL stripe count $cur_scount != $new_scount"
7674         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7675         echo "done."
7676 }
7677 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7678
7679 test_56wd() {
7680         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7681
7682         local file1=$DIR/$tdir/$tfile
7683
7684         echo -n "Creating test dir..."
7685         test_mkdir $DIR/$tdir || error "cannot create dir"
7686         echo "done."
7687
7688         echo -n "Creating test file..."
7689         echo "$tfile" > $file1
7690         echo "done."
7691
7692         # Ensure 'lfs migrate' will fail by using a non-existent option,
7693         # and make sure rsync is not called to recover
7694         echo -n "Make sure --no-rsync option works..."
7695         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7696                 grep -q 'refusing to fall back to rsync' ||
7697                 error "rsync was called with --no-rsync set"
7698         echo "done."
7699
7700         # Ensure rsync is called without trying 'lfs migrate' first
7701         echo -n "Make sure --rsync option works..."
7702         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7703                 grep -q 'falling back to rsync' &&
7704                 error "lfs migrate was called with --rsync set"
7705         echo "done."
7706 }
7707 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7708
7709 test_56we() {
7710         local td=$DIR/$tdir
7711         local tf=$td/$tfile
7712
7713         test_mkdir $td || error "cannot create $td"
7714         touch $tf || error "cannot touch $tf"
7715
7716         echo -n "Make sure --non-direct|-D works..."
7717         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7718                 grep -q "lfs migrate --non-direct" ||
7719                 error "--non-direct option cannot work correctly"
7720         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7721                 grep -q "lfs migrate -D" ||
7722                 error "-D option cannot work correctly"
7723         echo "done."
7724 }
7725 run_test 56we "check lfs_migrate --non-direct|-D support"
7726
7727 test_56x() {
7728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7729         check_swap_layouts_support
7730
7731         local dir=$DIR/$tdir
7732         local ref1=/etc/passwd
7733         local file1=$dir/file1
7734
7735         test_mkdir $dir || error "creating dir $dir"
7736         $LFS setstripe -c 2 $file1
7737         cp $ref1 $file1
7738         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7739         stripe=$($LFS getstripe -c $file1)
7740         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7741         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7742
7743         # clean up
7744         rm -f $file1
7745 }
7746 run_test 56x "lfs migration support"
7747
7748 test_56xa() {
7749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7750         check_swap_layouts_support
7751
7752         local dir=$DIR/$tdir/$testnum
7753
7754         test_mkdir -p $dir
7755
7756         local ref1=/etc/passwd
7757         local file1=$dir/file1
7758
7759         $LFS setstripe -c 2 $file1
7760         cp $ref1 $file1
7761         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7762
7763         local stripe=$($LFS getstripe -c $file1)
7764
7765         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7766         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7767
7768         # clean up
7769         rm -f $file1
7770 }
7771 run_test 56xa "lfs migration --block support"
7772
7773 check_migrate_links() {
7774         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7775         local dir="$1"
7776         local file1="$dir/file1"
7777         local begin="$2"
7778         local count="$3"
7779         local runas="$4"
7780         local total_count=$(($begin + $count - 1))
7781         local symlink_count=10
7782         local uniq_count=10
7783
7784         if [ ! -f "$file1" ]; then
7785                 echo -n "creating initial file..."
7786                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7787                         error "cannot setstripe initial file"
7788                 echo "done"
7789
7790                 echo -n "creating symlinks..."
7791                 for s in $(seq 1 $symlink_count); do
7792                         ln -s "$file1" "$dir/slink$s" ||
7793                                 error "cannot create symlinks"
7794                 done
7795                 echo "done"
7796
7797                 echo -n "creating nonlinked files..."
7798                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7799                         error "cannot create nonlinked files"
7800                 echo "done"
7801         fi
7802
7803         # create hard links
7804         if [ ! -f "$dir/file$total_count" ]; then
7805                 echo -n "creating hard links $begin:$total_count..."
7806                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7807                         /dev/null || error "cannot create hard links"
7808                 echo "done"
7809         fi
7810
7811         echo -n "checking number of hard links listed in xattrs..."
7812         local fid=$($LFS getstripe -F "$file1")
7813         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7814
7815         echo "${#paths[*]}"
7816         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7817                         skip "hard link list has unexpected size, skipping test"
7818         fi
7819         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7820                         error "link names should exceed xattrs size"
7821         fi
7822
7823         echo -n "migrating files..."
7824         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7825         local rc=$?
7826         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7827         echo "done"
7828
7829         # make sure all links have been properly migrated
7830         echo -n "verifying files..."
7831         fid=$($LFS getstripe -F "$file1") ||
7832                 error "cannot get fid for file $file1"
7833         for i in $(seq 2 $total_count); do
7834                 local fid2=$($LFS getstripe -F $dir/file$i)
7835
7836                 [ "$fid2" == "$fid" ] ||
7837                         error "migrated hard link has mismatched FID"
7838         done
7839
7840         # make sure hard links were properly detected, and migration was
7841         # performed only once for the entire link set; nonlinked files should
7842         # also be migrated
7843         local actual=$(grep -c 'done' <<< "$migrate_out")
7844         local expected=$(($uniq_count + 1))
7845
7846         [ "$actual" -eq  "$expected" ] ||
7847                 error "hard links individually migrated ($actual != $expected)"
7848
7849         # make sure the correct number of hard links are present
7850         local hardlinks=$(stat -c '%h' "$file1")
7851
7852         [ $hardlinks -eq $total_count ] ||
7853                 error "num hard links $hardlinks != $total_count"
7854         echo "done"
7855
7856         return 0
7857 }
7858
7859 test_56xb() {
7860         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7861                 skip "Need MDS version at least 2.10.55"
7862
7863         local dir="$DIR/$tdir"
7864
7865         test_mkdir "$dir" || error "cannot create dir $dir"
7866
7867         echo "testing lfs migrate mode when all links fit within xattrs"
7868         check_migrate_links "$dir" 2 99
7869
7870         echo "testing rsync mode when all links fit within xattrs"
7871         check_migrate_links --rsync "$dir" 2 99
7872
7873         echo "testing lfs migrate mode when all links do not fit within xattrs"
7874         check_migrate_links "$dir" 101 100
7875
7876         echo "testing rsync mode when all links do not fit within xattrs"
7877         check_migrate_links --rsync "$dir" 101 100
7878
7879         chown -R $RUNAS_ID $dir
7880         echo "testing non-root lfs migrate mode when not all links are in xattr"
7881         check_migrate_links "$dir" 101 100 "$RUNAS"
7882
7883         # clean up
7884         rm -rf $dir
7885 }
7886 run_test 56xb "lfs migration hard link support"
7887
7888 test_56xc() {
7889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7890
7891         local dir="$DIR/$tdir"
7892
7893         test_mkdir "$dir" || error "cannot create dir $dir"
7894
7895         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7896         echo -n "Setting initial stripe for 20MB test file..."
7897         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7898                 error "cannot setstripe 20MB file"
7899         echo "done"
7900         echo -n "Sizing 20MB test file..."
7901         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7902         echo "done"
7903         echo -n "Verifying small file autostripe count is 1..."
7904         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7905                 error "cannot migrate 20MB file"
7906         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7907                 error "cannot get stripe for $dir/20mb"
7908         [ $stripe_count -eq 1 ] ||
7909                 error "unexpected stripe count $stripe_count for 20MB file"
7910         rm -f "$dir/20mb"
7911         echo "done"
7912
7913         # Test 2: File is small enough to fit within the available space on
7914         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7915         # have at least an additional 1KB for each desired stripe for test 3
7916         echo -n "Setting stripe for 1GB test file..."
7917         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7918         echo "done"
7919         echo -n "Sizing 1GB test file..."
7920         # File size is 1GB + 3KB
7921         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7922         echo "done"
7923
7924         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7925         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7926         if (( avail > 524288 * OSTCOUNT )); then
7927                 echo -n "Migrating 1GB file..."
7928                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7929                         error "cannot migrate 1GB file"
7930                 echo "done"
7931                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7932                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7933                         error "cannot getstripe for 1GB file"
7934                 [ $stripe_count -eq 2 ] ||
7935                         error "unexpected stripe count $stripe_count != 2"
7936                 echo "done"
7937         fi
7938
7939         # Test 3: File is too large to fit within the available space on
7940         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7941         if [ $OSTCOUNT -ge 3 ]; then
7942                 # The required available space is calculated as
7943                 # file size (1GB + 3KB) / OST count (3).
7944                 local kb_per_ost=349526
7945
7946                 echo -n "Migrating 1GB file with limit..."
7947                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7948                         error "cannot migrate 1GB file with limit"
7949                 echo "done"
7950
7951                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7952                 echo -n "Verifying 1GB autostripe count with limited space..."
7953                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7954                         error "unexpected stripe count $stripe_count (min 3)"
7955                 echo "done"
7956         fi
7957
7958         # clean up
7959         rm -rf $dir
7960 }
7961 run_test 56xc "lfs migration autostripe"
7962
7963 test_56xd() {
7964         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7965
7966         local dir=$DIR/$tdir
7967         local f_mgrt=$dir/$tfile.mgrt
7968         local f_yaml=$dir/$tfile.yaml
7969         local f_copy=$dir/$tfile.copy
7970         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7971         local layout_copy="-c 2 -S 2M -i 1"
7972         local yamlfile=$dir/yamlfile
7973         local layout_before;
7974         local layout_after;
7975
7976         test_mkdir "$dir" || error "cannot create dir $dir"
7977         $LFS setstripe $layout_yaml $f_yaml ||
7978                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7979         $LFS getstripe --yaml $f_yaml > $yamlfile
7980         $LFS setstripe $layout_copy $f_copy ||
7981                 error "cannot setstripe $f_copy with layout $layout_copy"
7982         touch $f_mgrt
7983         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7984
7985         # 1. test option --yaml
7986         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7987                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7988         layout_before=$(get_layout_param $f_yaml)
7989         layout_after=$(get_layout_param $f_mgrt)
7990         [ "$layout_after" == "$layout_before" ] ||
7991                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7992
7993         # 2. test option --copy
7994         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7995                 error "cannot migrate $f_mgrt with --copy $f_copy"
7996         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
7997         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
7998         [ "$layout_after" == "$layout_before" ] ||
7999                 error "lfs_migrate --copy: $layout_after != $layout_before"
8000 }
8001 run_test 56xd "check lfs_migrate --yaml and --copy support"
8002
8003 test_56xe() {
8004         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8005
8006         local dir=$DIR/$tdir
8007         local f_comp=$dir/$tfile
8008         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8009         local layout_before=""
8010         local layout_after=""
8011
8012         test_mkdir "$dir" || error "cannot create dir $dir"
8013         $LFS setstripe $layout $f_comp ||
8014                 error "cannot setstripe $f_comp with layout $layout"
8015         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8016         dd if=/dev/zero of=$f_comp bs=1M count=4
8017
8018         # 1. migrate a comp layout file by lfs_migrate
8019         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8020         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8021         [ "$layout_before" == "$layout_after" ] ||
8022                 error "lfs_migrate: $layout_before != $layout_after"
8023
8024         # 2. migrate a comp layout file by lfs migrate
8025         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8026         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8027         [ "$layout_before" == "$layout_after" ] ||
8028                 error "lfs migrate: $layout_before != $layout_after"
8029 }
8030 run_test 56xe "migrate a composite layout file"
8031
8032 test_56xf() {
8033         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8034
8035         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8036                 skip "Need server version at least 2.13.53"
8037
8038         local dir=$DIR/$tdir
8039         local f_comp=$dir/$tfile
8040         local layout="-E 1M -c1 -E -1 -c2"
8041         local fid_before=""
8042         local fid_after=""
8043
8044         test_mkdir "$dir" || error "cannot create dir $dir"
8045         $LFS setstripe $layout $f_comp ||
8046                 error "cannot setstripe $f_comp with layout $layout"
8047         fid_before=$($LFS getstripe --fid $f_comp)
8048         dd if=/dev/zero of=$f_comp bs=1M count=4
8049
8050         # 1. migrate a comp layout file to a comp layout
8051         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8052         fid_after=$($LFS getstripe --fid $f_comp)
8053         [ "$fid_before" == "$fid_after" ] ||
8054                 error "comp-to-comp migrate: $fid_before != $fid_after"
8055
8056         # 2. migrate a comp layout file to a plain layout
8057         $LFS migrate -c2 $f_comp ||
8058                 error "cannot migrate $f_comp by lfs migrate"
8059         fid_after=$($LFS getstripe --fid $f_comp)
8060         [ "$fid_before" == "$fid_after" ] ||
8061                 error "comp-to-plain migrate: $fid_before != $fid_after"
8062
8063         # 3. migrate a plain layout file to a comp layout
8064         $LFS migrate $layout $f_comp ||
8065                 error "cannot migrate $f_comp by lfs migrate"
8066         fid_after=$($LFS getstripe --fid $f_comp)
8067         [ "$fid_before" == "$fid_after" ] ||
8068                 error "plain-to-comp migrate: $fid_before != $fid_after"
8069 }
8070 run_test 56xf "FID is not lost during migration of a composite layout file"
8071
8072 check_file_ost_range() {
8073         local file="$1"
8074         shift
8075         local range="$*"
8076         local -a file_range
8077         local idx
8078
8079         file_range=($($LFS getstripe -y "$file" |
8080                 awk '/l_ost_idx:/ { print $NF }'))
8081
8082         if [[ "${#file_range[@]}" = 0 ]]; then
8083                 echo "No osts found for $file"
8084                 return 1
8085         fi
8086
8087         for idx in "${file_range[@]}"; do
8088                 [[ " $range " =~ " $idx " ]] ||
8089                         return 1
8090         done
8091
8092         return 0
8093 }
8094
8095 sub_test_56xg() {
8096         local stripe_opt="$1"
8097         local pool="$2"
8098         shift 2
8099         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8100
8101         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8102                 error "Fail to migrate $tfile on $pool"
8103         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8104                 error "$tfile is not in pool $pool"
8105         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8106                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8107 }
8108
8109 test_56xg() {
8110         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8111         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8112         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8113                 skip "Need MDS version newer than 2.14.52"
8114
8115         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8116         local -a pool_ranges=("0 0" "1 1" "0 1")
8117
8118         # init pools
8119         for i in "${!pool_names[@]}"; do
8120                 pool_add ${pool_names[$i]} ||
8121                         error "pool_add failed (pool: ${pool_names[$i]})"
8122                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8123                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8124         done
8125
8126         # init the file to migrate
8127         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8128                 error "Unable to create $tfile on OST1"
8129         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8130                 error "Unable to write on $tfile"
8131
8132         echo "1. migrate $tfile on pool ${pool_names[0]}"
8133         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8134
8135         echo "2. migrate $tfile on pool ${pool_names[2]}"
8136         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8137
8138         echo "3. migrate $tfile on pool ${pool_names[1]}"
8139         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8140
8141         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8142         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8143         echo
8144
8145         # Clean pools
8146         destroy_test_pools ||
8147                 error "pool_destroy failed"
8148 }
8149 run_test 56xg "lfs migrate pool support"
8150
8151 test_56xh() {
8152         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8153
8154         local size_mb=25
8155         local file1=$DIR/$tfile
8156         local tmp1=$TMP/$tfile.tmp
8157
8158         $LFS setstripe -c 2 $file1
8159
8160         stack_trap "rm -f $file1 $tmp1"
8161         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8162                         error "error creating $tmp1"
8163         ls -lsh $tmp1
8164         cp $tmp1 $file1
8165
8166         local start=$SECONDS
8167
8168         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8169                 error "migrate failed rc = $?"
8170
8171         local elapsed=$((SECONDS - start))
8172
8173         # with 1MB/s, elapsed should equal size_mb
8174         (( elapsed >= size_mb * 95 / 100 )) ||
8175                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8176
8177         (( elapsed <= size_mb * 120 / 100 )) ||
8178                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8179
8180         (( elapsed <= size_mb * 150 / 100 )) ||
8181                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8182
8183         stripe=$($LFS getstripe -c $file1)
8184         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8185         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8186
8187         # Clean up file (since it is multiple MB)
8188         rm -f $file1 $tmp1
8189 }
8190 run_test 56xh "lfs migrate bandwidth limitation support"
8191
8192 test_56xi() {
8193         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8194         verify_yaml_available || skip_env "YAML verification not installed"
8195
8196         local size_mb=5
8197         local file1=$DIR/$tfile.1
8198         local file2=$DIR/$tfile.2
8199         local file3=$DIR/$tfile.3
8200         local output_file=$DIR/$tfile.out
8201         local tmp1=$TMP/$tfile.tmp
8202
8203         $LFS setstripe -c 2 $file1
8204         $LFS setstripe -c 2 $file2
8205         $LFS setstripe -c 2 $file3
8206
8207         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8208         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8209                         error "error creating $tmp1"
8210         ls -lsh $tmp1
8211         cp $tmp1 $file1
8212         cp $tmp1 $file2
8213         cp $tmp1 $file3
8214
8215         $LFS migrate --stats --stats-interval=1 \
8216                 -c 1 $file1 $file2 $file3 1> $output_file ||
8217                 error "migrate failed rc = $?"
8218
8219         cat $output_file
8220         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8221
8222         # Clean up file (since it is multiple MB)
8223         rm -f $file1 $file2 $file3 $tmp1 $output_file
8224 }
8225 run_test 56xi "lfs migrate stats support"
8226
8227 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8228         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8229
8230         local file=$DIR/$tfile
8231         local linkdir=$DIR/$tdir
8232
8233         test_mkdir $linkdir || error "fail to create $linkdir"
8234         $LFS setstripe -i 0 -c 1 -S1M $file
8235         dd if=/dev/urandom of=$file bs=1M count=10 ||
8236                 error "fail to create $file"
8237
8238         # Create file links
8239         local cpts
8240         local threads_max
8241         local nlinks
8242
8243         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8244         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8245         (( nlinks = thread_max * 3 / 2 / cpts))
8246
8247         echo "create $nlinks hard links of $file"
8248         createmany -l $file $linkdir/link $nlinks
8249
8250         # Parallel migrates (should not block)
8251         local i
8252         for ((i = 0; i < nlinks; i++)); do
8253                 echo $linkdir/link$i
8254         done | xargs -n1 -P $nlinks $LFS migrate -c2
8255
8256         local stripe_count
8257         stripe_count=$($LFS getstripe -c $file) ||
8258                 error "fail to get stripe count on $file"
8259
8260         ((stripe_count == 2)) ||
8261                 error "fail to migrate $file (stripe_count = $stripe_count)"
8262 }
8263 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8264
8265 test_56y() {
8266         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8267                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8268
8269         local res=""
8270         local dir=$DIR/$tdir
8271         local f1=$dir/file1
8272         local f2=$dir/file2
8273
8274         test_mkdir -p $dir || error "creating dir $dir"
8275         touch $f1 || error "creating std file $f1"
8276         $MULTIOP $f2 H2c || error "creating released file $f2"
8277
8278         # a directory can be raid0, so ask only for files
8279         res=$($LFS find $dir -L raid0 -type f | wc -l)
8280         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8281
8282         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8283         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8284
8285         # only files can be released, so no need to force file search
8286         res=$($LFS find $dir -L released)
8287         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8288
8289         res=$($LFS find $dir -type f \! -L released)
8290         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8291 }
8292 run_test 56y "lfs find -L raid0|released"
8293
8294 test_56z() { # LU-4824
8295         # This checks to make sure 'lfs find' continues after errors
8296         # There are two classes of errors that should be caught:
8297         # - If multiple paths are provided, all should be searched even if one
8298         #   errors out
8299         # - If errors are encountered during the search, it should not terminate
8300         #   early
8301         local dir=$DIR/$tdir
8302         local i
8303
8304         test_mkdir $dir
8305         for i in d{0..9}; do
8306                 test_mkdir $dir/$i
8307                 touch $dir/$i/$tfile
8308         done
8309         $LFS find $DIR/non_existent_dir $dir &&
8310                 error "$LFS find did not return an error"
8311         # Make a directory unsearchable. This should NOT be the last entry in
8312         # directory order.  Arbitrarily pick the 6th entry
8313         chmod 700 $($LFS find $dir -type d | sed '6!d')
8314
8315         $RUNAS $LFS find $DIR/non_existent $dir
8316         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8317
8318         # The user should be able to see 10 directories and 9 files
8319         (( count == 19 )) ||
8320                 error "$LFS find found $count != 19 entries after error"
8321 }
8322 run_test 56z "lfs find should continue after an error"
8323
8324 test_56aa() { # LU-5937
8325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8326
8327         local dir=$DIR/$tdir
8328
8329         mkdir $dir
8330         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8331
8332         createmany -o $dir/striped_dir/${tfile}- 1024
8333         local dirs=$($LFS find --size +8k $dir/)
8334
8335         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8336 }
8337 run_test 56aa "lfs find --size under striped dir"
8338
8339 test_56ab() { # LU-10705
8340         test_mkdir $DIR/$tdir
8341         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8342         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8343         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8344         # Flush writes to ensure valid blocks.  Need to be more thorough for
8345         # ZFS, since blocks are not allocated/returned to client immediately.
8346         sync_all_data
8347         wait_zfs_commit ost1 2
8348         cancel_lru_locks osc
8349         ls -ls $DIR/$tdir
8350
8351         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8352
8353         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8354
8355         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8356         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8357
8358         rm -f $DIR/$tdir/$tfile.[123]
8359 }
8360 run_test 56ab "lfs find --blocks"
8361
8362 # LU-11188
8363 test_56aca() {
8364         local dir="$DIR/$tdir"
8365         local perms=(001 002 003 004 005 006 007
8366                      010 020 030 040 050 060 070
8367                      100 200 300 400 500 600 700
8368                      111 222 333 444 555 666 777)
8369         local perm_minus=(8 8 4 8 4 4 2
8370                           8 8 4 8 4 4 2
8371                           8 8 4 8 4 4 2
8372                           4 4 2 4 2 2 1)
8373         local perm_slash=(8  8 12  8 12 12 14
8374                           8  8 12  8 12 12 14
8375                           8  8 12  8 12 12 14
8376                          16 16 24 16 24 24 28)
8377
8378         test_mkdir "$dir"
8379         for perm in ${perms[*]}; do
8380                 touch "$dir/$tfile.$perm"
8381                 chmod $perm "$dir/$tfile.$perm"
8382         done
8383
8384         for ((i = 0; i < ${#perms[*]}; i++)); do
8385                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8386                 (( $num == 1 )) ||
8387                         error "lfs find -perm ${perms[i]}:"\
8388                               "$num != 1"
8389
8390                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8391                 (( $num == ${perm_minus[i]} )) ||
8392                         error "lfs find -perm -${perms[i]}:"\
8393                               "$num != ${perm_minus[i]}"
8394
8395                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8396                 (( $num == ${perm_slash[i]} )) ||
8397                         error "lfs find -perm /${perms[i]}:"\
8398                               "$num != ${perm_slash[i]}"
8399         done
8400 }
8401 run_test 56aca "check lfs find -perm with octal representation"
8402
8403 test_56acb() {
8404         local dir=$DIR/$tdir
8405         # p is the permission of write and execute for user, group and other
8406         # without the umask. It is used to test +wx.
8407         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8408         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8409         local symbolic=(+t  a+t u+t g+t o+t
8410                         g+s u+s o+s +s o+sr
8411                         o=r,ug+o,u+w
8412                         u+ g+ o+ a+ ugo+
8413                         u- g- o- a- ugo-
8414                         u= g= o= a= ugo=
8415                         o=r,ug+o,u+w u=r,a+u,u+w
8416                         g=r,ugo=g,u+w u+x,+X +X
8417                         u+x,u+X u+X u+x,g+X o+r,+X
8418                         u+x,go+X +wx +rwx)
8419
8420         test_mkdir $dir
8421         for perm in ${perms[*]}; do
8422                 touch "$dir/$tfile.$perm"
8423                 chmod $perm "$dir/$tfile.$perm"
8424         done
8425
8426         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8427                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8428
8429                 (( $num == 1 )) ||
8430                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8431         done
8432 }
8433 run_test 56acb "check lfs find -perm with symbolic representation"
8434
8435 test_56acc() {
8436         local dir=$DIR/$tdir
8437         local tests="17777 787 789 abcd
8438                 ug=uu ug=a ug=gu uo=ou urw
8439                 u+xg+x a=r,u+x,"
8440
8441         test_mkdir $dir
8442         for err in $tests; do
8443                 if $LFS find $dir -perm $err 2>/dev/null; then
8444                         error "lfs find -perm $err: parsing should have failed"
8445                 fi
8446         done
8447 }
8448 run_test 56acc "check parsing error for lfs find -perm"
8449
8450 test_56ba() {
8451         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8452                 skip "Need MDS version at least 2.10.50"
8453
8454         # Create composite files with one component
8455         local dir=$DIR/$tdir
8456
8457         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8458         # Create composite files with three components
8459         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8460         # Create non-composite files
8461         createmany -o $dir/${tfile}- 10
8462
8463         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8464
8465         [[ $nfiles == 10 ]] ||
8466                 error "lfs find -E 1M found $nfiles != 10 files"
8467
8468         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8469         [[ $nfiles == 25 ]] ||
8470                 error "lfs find ! -E 1M found $nfiles != 25 files"
8471
8472         # All files have a component that starts at 0
8473         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8474         [[ $nfiles == 35 ]] ||
8475                 error "lfs find --component-start 0 - $nfiles != 35 files"
8476
8477         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8478         [[ $nfiles == 15 ]] ||
8479                 error "lfs find --component-start 2M - $nfiles != 15 files"
8480
8481         # All files created here have a componenet that does not starts at 2M
8482         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8483         [[ $nfiles == 35 ]] ||
8484                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8485
8486         # Find files with a specified number of components
8487         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8488         [[ $nfiles == 15 ]] ||
8489                 error "lfs find --component-count 3 - $nfiles != 15 files"
8490
8491         # Remember non-composite files have a component count of zero
8492         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8493         [[ $nfiles == 10 ]] ||
8494                 error "lfs find --component-count 0 - $nfiles != 10 files"
8495
8496         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8497         [[ $nfiles == 20 ]] ||
8498                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8499
8500         # All files have a flag called "init"
8501         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8502         [[ $nfiles == 35 ]] ||
8503                 error "lfs find --component-flags init - $nfiles != 35 files"
8504
8505         # Multi-component files will have a component not initialized
8506         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8507         [[ $nfiles == 15 ]] ||
8508                 error "lfs find !--component-flags init - $nfiles != 15 files"
8509
8510         rm -rf $dir
8511
8512 }
8513 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8514
8515 test_56ca() {
8516         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8517                 skip "Need MDS version at least 2.10.57"
8518
8519         local td=$DIR/$tdir
8520         local tf=$td/$tfile
8521         local dir
8522         local nfiles
8523         local cmd
8524         local i
8525         local j
8526
8527         # create mirrored directories and mirrored files
8528         mkdir $td || error "mkdir $td failed"
8529         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8530         createmany -o $tf- 10 || error "create $tf- failed"
8531
8532         for i in $(seq 2); do
8533                 dir=$td/dir$i
8534                 mkdir $dir || error "mkdir $dir failed"
8535                 $LFS mirror create -N$((3 + i)) $dir ||
8536                         error "create mirrored dir $dir failed"
8537                 createmany -o $dir/$tfile- 10 ||
8538                         error "create $dir/$tfile- failed"
8539         done
8540
8541         # change the states of some mirrored files
8542         echo foo > $tf-6
8543         for i in $(seq 2); do
8544                 dir=$td/dir$i
8545                 for j in $(seq 4 9); do
8546                         echo foo > $dir/$tfile-$j
8547                 done
8548         done
8549
8550         # find mirrored files with specific mirror count
8551         cmd="$LFS find --mirror-count 3 --type f $td"
8552         nfiles=$($cmd | wc -l)
8553         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8554
8555         cmd="$LFS find ! --mirror-count 3 --type f $td"
8556         nfiles=$($cmd | wc -l)
8557         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8558
8559         cmd="$LFS find --mirror-count +2 --type f $td"
8560         nfiles=$($cmd | wc -l)
8561         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8562
8563         cmd="$LFS find --mirror-count -6 --type f $td"
8564         nfiles=$($cmd | wc -l)
8565         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8566
8567         # find mirrored files with specific file state
8568         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8569         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8570
8571         cmd="$LFS find --mirror-state=ro --type f $td"
8572         nfiles=$($cmd | wc -l)
8573         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8574
8575         cmd="$LFS find ! --mirror-state=ro --type f $td"
8576         nfiles=$($cmd | wc -l)
8577         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8578
8579         cmd="$LFS find --mirror-state=wp --type f $td"
8580         nfiles=$($cmd | wc -l)
8581         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8582
8583         cmd="$LFS find ! --mirror-state=sp --type f $td"
8584         nfiles=$($cmd | wc -l)
8585         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8586 }
8587 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8588
8589 test_56da() { # LU-14179
8590         local path=$DIR/$tdir
8591
8592         test_mkdir $path
8593         cd $path
8594
8595         local longdir=$(str_repeat 'a' 255)
8596
8597         for i in {1..15}; do
8598                 path=$path/$longdir
8599                 test_mkdir $longdir
8600                 cd $longdir
8601         done
8602
8603         local len=${#path}
8604         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8605
8606         test_mkdir $lastdir
8607         cd $lastdir
8608         # PATH_MAX-1
8609         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8610
8611         # NAME_MAX
8612         touch $(str_repeat 'f' 255)
8613
8614         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8615                 error "lfs find reported an error"
8616
8617         rm -rf $DIR/$tdir
8618 }
8619 run_test 56da "test lfs find with long paths"
8620
8621 test_56ea() { #LU-10378
8622         local path=$DIR/$tdir
8623         local pool=$TESTNAME
8624
8625         # Create ost pool
8626         pool_add $pool || error "pool_add $pool failed"
8627         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8628                 error "adding targets to $pool failed"
8629
8630         # Set default pool on directory before creating file
8631         mkdir $path || error "mkdir $path failed"
8632         $LFS setstripe -p $pool $path ||
8633                 error "set OST pool on $pool failed"
8634         touch $path/$tfile || error "touch $path/$tfile failed"
8635
8636         # Compare basic file attributes from -printf and stat
8637         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8638         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8639
8640         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8641                 error "Attrs from lfs find and stat don't match"
8642
8643         # Compare Lustre attributes from lfs find and lfs getstripe
8644         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8645         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8646         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8647         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8648         local fpool=$($LFS getstripe --pool $path/$tfile)
8649         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8650
8651         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8652                 error "Attrs from lfs find and lfs getstripe don't match"
8653
8654         # Verify behavior for unknown escape/format sequences
8655         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8656
8657         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8658                 error "Escape/format codes don't match"
8659 }
8660 run_test 56ea "test lfs find -printf option"
8661
8662 test_56eb() {
8663         local dir=$DIR/$tdir
8664         local subdir_1=$dir/subdir_1
8665
8666         test_mkdir -p $subdir_1
8667         ln -s subdir_1 $dir/link_1
8668
8669         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8670                 error "symlink is not followed"
8671
8672         $LFS getstripe --no-follow $dir |
8673                 grep "^$dir/link_1 has no stripe info$" ||
8674                 error "symlink should not have stripe info"
8675
8676         touch $dir/testfile
8677         ln -s testfile $dir/file_link_2
8678
8679         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8680                 error "symlink is not followed"
8681
8682         $LFS getstripe --no-follow $dir |
8683                 grep "^$dir/file_link_2 has no stripe info$" ||
8684                 error "symlink should not have stripe info"
8685 }
8686 run_test 56eb "check lfs getstripe on symlink"
8687
8688 test_57a() {
8689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8690         # note test will not do anything if MDS is not local
8691         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8692                 skip_env "ldiskfs only test"
8693         fi
8694         remote_mds_nodsh && skip "remote MDS with nodsh"
8695
8696         local MNTDEV="osd*.*MDT*.mntdev"
8697         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8698         [ -z "$DEV" ] && error "can't access $MNTDEV"
8699         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8700                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8701                         error "can't access $DEV"
8702                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8703                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8704                 rm $TMP/t57a.dump
8705         done
8706 }
8707 run_test 57a "verify MDS filesystem created with large inodes =="
8708
8709 test_57b() {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8712                 skip_env "ldiskfs only test"
8713         fi
8714         remote_mds_nodsh && skip "remote MDS with nodsh"
8715
8716         local dir=$DIR/$tdir
8717         local filecount=100
8718         local file1=$dir/f1
8719         local fileN=$dir/f$filecount
8720
8721         rm -rf $dir || error "removing $dir"
8722         test_mkdir -c1 $dir
8723         local mdtidx=$($LFS getstripe -m $dir)
8724         local mdtname=MDT$(printf %04x $mdtidx)
8725         local facet=mds$((mdtidx + 1))
8726
8727         echo "mcreating $filecount files"
8728         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8729
8730         # verify that files do not have EAs yet
8731         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8732                 error "$file1 has an EA"
8733         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8734                 error "$fileN has an EA"
8735
8736         sync
8737         sleep 1
8738         df $dir  #make sure we get new statfs data
8739         local mdsfree=$(do_facet $facet \
8740                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8741         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8742         local file
8743
8744         echo "opening files to create objects/EAs"
8745         for file in $(seq -f $dir/f%g 1 $filecount); do
8746                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8747                         error "opening $file"
8748         done
8749
8750         # verify that files have EAs now
8751         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8752         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8753
8754         sleep 1  #make sure we get new statfs data
8755         df $dir
8756         local mdsfree2=$(do_facet $facet \
8757                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8758         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8759
8760         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8761                 if [ "$mdsfree" != "$mdsfree2" ]; then
8762                         error "MDC before $mdcfree != after $mdcfree2"
8763                 else
8764                         echo "MDC before $mdcfree != after $mdcfree2"
8765                         echo "unable to confirm if MDS has large inodes"
8766                 fi
8767         fi
8768         rm -rf $dir
8769 }
8770 run_test 57b "default LOV EAs are stored inside large inodes ==="
8771
8772 test_58() {
8773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8774         [ -z "$(which wiretest 2>/dev/null)" ] &&
8775                         skip_env "could not find wiretest"
8776
8777         wiretest
8778 }
8779 run_test 58 "verify cross-platform wire constants =============="
8780
8781 test_59() {
8782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8783
8784         echo "touch 130 files"
8785         createmany -o $DIR/f59- 130
8786         echo "rm 130 files"
8787         unlinkmany $DIR/f59- 130
8788         sync
8789         # wait for commitment of removal
8790         wait_delete_completed
8791 }
8792 run_test 59 "verify cancellation of llog records async ========="
8793
8794 TEST60_HEAD="test_60 run $RANDOM"
8795 test_60a() {
8796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8797         remote_mgs_nodsh && skip "remote MGS with nodsh"
8798         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8799                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8800                         skip_env "missing subtest run-llog.sh"
8801
8802         log "$TEST60_HEAD - from kernel mode"
8803         do_facet mgs "$LCTL dk > /dev/null"
8804         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8805         do_facet mgs $LCTL dk > $TMP/$tfile
8806
8807         # LU-6388: test llog_reader
8808         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8809         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8810         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8811                         skip_env "missing llog_reader"
8812         local fstype=$(facet_fstype mgs)
8813         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8814                 skip_env "Only for ldiskfs or zfs type mgs"
8815
8816         local mntpt=$(facet_mntpt mgs)
8817         local mgsdev=$(mgsdevname 1)
8818         local fid_list
8819         local fid
8820         local rec_list
8821         local rec
8822         local rec_type
8823         local obj_file
8824         local path
8825         local seq
8826         local oid
8827         local pass=true
8828
8829         #get fid and record list
8830         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8831                 tail -n 4))
8832         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8833                 tail -n 4))
8834         #remount mgs as ldiskfs or zfs type
8835         stop mgs || error "stop mgs failed"
8836         mount_fstype mgs || error "remount mgs failed"
8837         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8838                 fid=${fid_list[i]}
8839                 rec=${rec_list[i]}
8840                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8841                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8842                 oid=$((16#$oid))
8843
8844                 case $fstype in
8845                         ldiskfs )
8846                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8847                         zfs )
8848                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8849                 esac
8850                 echo "obj_file is $obj_file"
8851                 do_facet mgs $llog_reader $obj_file
8852
8853                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8854                         awk '{ print $3 }' | sed -e "s/^type=//g")
8855                 if [ $rec_type != $rec ]; then
8856                         echo "FAILED test_60a wrong record type $rec_type," \
8857                               "should be $rec"
8858                         pass=false
8859                         break
8860                 fi
8861
8862                 #check obj path if record type is LLOG_LOGID_MAGIC
8863                 if [ "$rec" == "1064553b" ]; then
8864                         path=$(do_facet mgs $llog_reader $obj_file |
8865                                 grep "path=" | awk '{ print $NF }' |
8866                                 sed -e "s/^path=//g")
8867                         if [ $obj_file != $mntpt/$path ]; then
8868                                 echo "FAILED test_60a wrong obj path" \
8869                                       "$montpt/$path, should be $obj_file"
8870                                 pass=false
8871                                 break
8872                         fi
8873                 fi
8874         done
8875         rm -f $TMP/$tfile
8876         #restart mgs before "error", otherwise it will block the next test
8877         stop mgs || error "stop mgs failed"
8878         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8879         $pass || error "test failed, see FAILED test_60a messages for specifics"
8880 }
8881 run_test 60a "llog_test run from kernel module and test llog_reader"
8882
8883 test_60b() { # bug 6411
8884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8885
8886         dmesg > $DIR/$tfile
8887         LLOG_COUNT=$(do_facet mgs dmesg |
8888                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8889                           /llog_[a-z]*.c:[0-9]/ {
8890                                 if (marker)
8891                                         from_marker++
8892                                 from_begin++
8893                           }
8894                           END {
8895                                 if (marker)
8896                                         print from_marker
8897                                 else
8898                                         print from_begin
8899                           }")
8900
8901         [[ $LLOG_COUNT -gt 120 ]] &&
8902                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8903 }
8904 run_test 60b "limit repeated messages from CERROR/CWARN"
8905
8906 test_60c() {
8907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8908
8909         echo "create 5000 files"
8910         createmany -o $DIR/f60c- 5000
8911 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8912         lctl set_param fail_loc=0x80000137
8913         unlinkmany $DIR/f60c- 5000
8914         lctl set_param fail_loc=0
8915 }
8916 run_test 60c "unlink file when mds full"
8917
8918 test_60d() {
8919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8920
8921         SAVEPRINTK=$(lctl get_param -n printk)
8922         # verify "lctl mark" is even working"
8923         MESSAGE="test message ID $RANDOM $$"
8924         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8925         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8926
8927         lctl set_param printk=0 || error "set lnet.printk failed"
8928         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8929         MESSAGE="new test message ID $RANDOM $$"
8930         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8931         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8932         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8933
8934         lctl set_param -n printk="$SAVEPRINTK"
8935 }
8936 run_test 60d "test printk console message masking"
8937
8938 test_60e() {
8939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8940         remote_mds_nodsh && skip "remote MDS with nodsh"
8941
8942         touch $DIR/$tfile
8943 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8944         do_facet mds1 lctl set_param fail_loc=0x15b
8945         rm $DIR/$tfile
8946 }
8947 run_test 60e "no space while new llog is being created"
8948
8949 test_60f() {
8950         local old_path=$($LCTL get_param -n debug_path)
8951
8952         stack_trap "$LCTL set_param debug_path=$old_path"
8953         stack_trap "rm -f $TMP/$tfile*"
8954         rm -f $TMP/$tfile* 2> /dev/null
8955         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8956         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8957         test_mkdir $DIR/$tdir
8958         # retry in case the open is cached and not released
8959         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8960                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8961                 sleep 0.1
8962         done
8963         ls $TMP/$tfile*
8964         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8965 }
8966 run_test 60f "change debug_path works"
8967
8968 test_60g() {
8969         local pid
8970         local i
8971
8972         test_mkdir -c $MDSCOUNT $DIR/$tdir
8973
8974         (
8975                 local index=0
8976                 while true; do
8977                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8978                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8979                                 2>/dev/null
8980                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8981                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8982                         index=$((index + 1))
8983                 done
8984         ) &
8985
8986         pid=$!
8987
8988         for i in {0..100}; do
8989                 # define OBD_FAIL_OSD_TXN_START    0x19a
8990                 local index=$((i % MDSCOUNT + 1))
8991
8992                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8993                         > /dev/null
8994                 sleep 0.01
8995         done
8996
8997         kill -9 $pid
8998
8999         for i in $(seq $MDSCOUNT); do
9000                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9001         done
9002
9003         mkdir $DIR/$tdir/new || error "mkdir failed"
9004         rmdir $DIR/$tdir/new || error "rmdir failed"
9005
9006         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9007                 -t namespace
9008         for i in $(seq $MDSCOUNT); do
9009                 wait_update_facet mds$i "$LCTL get_param -n \
9010                         mdd.$(facet_svc mds$i).lfsck_namespace |
9011                         awk '/^status/ { print \\\$2 }'" "completed"
9012         done
9013
9014         ls -R $DIR/$tdir
9015         rm -rf $DIR/$tdir || error "rmdir failed"
9016 }
9017 run_test 60g "transaction abort won't cause MDT hung"
9018
9019 test_60h() {
9020         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9021                 skip "Need MDS version at least 2.12.52"
9022         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9023
9024         local f
9025
9026         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9027         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9028         for fail_loc in 0x80000188 0x80000189; do
9029                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9030                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9031                         error "mkdir $dir-$fail_loc failed"
9032                 for i in {0..10}; do
9033                         # create may fail on missing stripe
9034                         echo $i > $DIR/$tdir-$fail_loc/$i
9035                 done
9036                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9037                         error "getdirstripe $tdir-$fail_loc failed"
9038                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9039                         error "migrate $tdir-$fail_loc failed"
9040                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9041                         error "getdirstripe $tdir-$fail_loc failed"
9042                 pushd $DIR/$tdir-$fail_loc
9043                 for f in *; do
9044                         echo $f | cmp $f - || error "$f data mismatch"
9045                 done
9046                 popd
9047                 rm -rf $DIR/$tdir-$fail_loc
9048         done
9049 }
9050 run_test 60h "striped directory with missing stripes can be accessed"
9051
9052 function t60i_load() {
9053         mkdir $DIR/$tdir
9054         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9055         $LCTL set_param fail_loc=0x131c fail_val=1
9056         for ((i=0; i<5000; i++)); do
9057                 touch $DIR/$tdir/f$i
9058         done
9059 }
9060
9061 test_60i() {
9062         changelog_register || error "changelog_register failed"
9063         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9064         changelog_users $SINGLEMDS | grep -q $cl_user ||
9065                 error "User $cl_user not found in changelog_users"
9066         changelog_chmask "ALL"
9067         t60i_load &
9068         local PID=$!
9069         for((i=0; i<100; i++)); do
9070                 changelog_dump >/dev/null ||
9071                         error "can't read changelog"
9072         done
9073         kill $PID
9074         wait $PID
9075         changelog_deregister || error "changelog_deregister failed"
9076         $LCTL set_param fail_loc=0
9077 }
9078 run_test 60i "llog: new record vs reader race"
9079
9080 test_60j() {
9081         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9082                 skip "need MDS version at least 2.15.50"
9083         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9084         remote_mds_nodsh && skip "remote MDS with nodsh"
9085         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9086
9087         changelog_users $SINGLEMDS | grep "^cl" &&
9088                 skip "active changelog user"
9089
9090         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9091
9092         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9093                 skip_env "missing llog_reader"
9094
9095         mkdir_on_mdt0 $DIR/$tdir
9096
9097         local f=$DIR/$tdir/$tfile
9098         local mdt_dev
9099         local tmpfile
9100         local plain
9101
9102         changelog_register || error "cannot register changelog user"
9103
9104         # set changelog_mask to ALL
9105         changelog_chmask "ALL"
9106         changelog_clear
9107
9108         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9109         unlinkmany ${f}- 100 || error "unlinkmany failed"
9110
9111         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9112         mdt_dev=$(facet_device $SINGLEMDS)
9113
9114         do_facet $SINGLEMDS sync
9115         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9116                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9117                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9118
9119         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9120
9121         # if $tmpfile is not on EXT3 filesystem for some reason
9122         [[ ${plain:0:1} == 'O' ]] ||
9123                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9124
9125         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9126                 $mdt_dev; stat -c %s $tmpfile")
9127         echo "Truncate llog from $size to $((size - size % 8192))"
9128         size=$((size - size % 8192))
9129         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9130         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9131                 grep -c 'in bitmap only')
9132         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9133
9134         size=$((size - 9000))
9135         echo "Corrupt llog in the middle at $size"
9136         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9137                 count=333 conv=notrunc
9138         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9139                 grep -c 'next chunk')
9140         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9141 }
9142 run_test 60j "llog_reader reports corruptions"
9143
9144 test_61a() {
9145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9146
9147         f="$DIR/f61"
9148         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9149         cancel_lru_locks osc
9150         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9151         sync
9152 }
9153 run_test 61a "mmap() writes don't make sync hang ================"
9154
9155 test_61b() {
9156         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9157 }
9158 run_test 61b "mmap() of unstriped file is successful"
9159
9160 # bug 2330 - insufficient obd_match error checking causes LBUG
9161 test_62() {
9162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9163
9164         f="$DIR/f62"
9165         echo foo > $f
9166         cancel_lru_locks osc
9167         lctl set_param fail_loc=0x405
9168         cat $f && error "cat succeeded, expect -EIO"
9169         lctl set_param fail_loc=0
9170 }
9171 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9172 # match every page all of the time.
9173 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9174
9175 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9176 # Though this test is irrelevant anymore, it helped to reveal some
9177 # other grant bugs (LU-4482), let's keep it.
9178 test_63a() {   # was test_63
9179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9180
9181         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9182
9183         for i in `seq 10` ; do
9184                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9185                 sleep 5
9186                 kill $!
9187                 sleep 1
9188         done
9189
9190         rm -f $DIR/f63 || true
9191 }
9192 run_test 63a "Verify oig_wait interruption does not crash ======="
9193
9194 # bug 2248 - async write errors didn't return to application on sync
9195 # bug 3677 - async write errors left page locked
9196 test_63b() {
9197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9198
9199         debugsave
9200         lctl set_param debug=-1
9201
9202         # ensure we have a grant to do async writes
9203         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9204         rm $DIR/$tfile
9205
9206         sync    # sync lest earlier test intercept the fail_loc
9207
9208         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9209         lctl set_param fail_loc=0x80000406
9210         $MULTIOP $DIR/$tfile Owy && \
9211                 error "sync didn't return ENOMEM"
9212         sync; sleep 2; sync     # do a real sync this time to flush page
9213         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9214                 error "locked page left in cache after async error" || true
9215         debugrestore
9216 }
9217 run_test 63b "async write errors should be returned to fsync ==="
9218
9219 test_64a () {
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221
9222         lfs df $DIR
9223         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9224 }
9225 run_test 64a "verify filter grant calculations (in kernel) ====="
9226
9227 test_64b () {
9228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9229
9230         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9231 }
9232 run_test 64b "check out-of-space detection on client"
9233
9234 test_64c() {
9235         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9236 }
9237 run_test 64c "verify grant shrink"
9238
9239 import_param() {
9240         local tgt=$1
9241         local param=$2
9242
9243         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9244 }
9245
9246 # this does exactly what osc_request.c:osc_announce_cached() does in
9247 # order to calculate max amount of grants to ask from server
9248 want_grant() {
9249         local tgt=$1
9250
9251         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9252         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9253
9254         ((rpc_in_flight++));
9255         nrpages=$((nrpages * rpc_in_flight))
9256
9257         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9258
9259         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9260
9261         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9262         local undirty=$((nrpages * PAGE_SIZE))
9263
9264         local max_extent_pages
9265         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9266         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9267         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9268         local grant_extent_tax
9269         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9270
9271         undirty=$((undirty + nrextents * grant_extent_tax))
9272
9273         echo $undirty
9274 }
9275
9276 # this is size of unit for grant allocation. It should be equal to
9277 # what tgt_grant.c:tgt_grant_chunk() calculates
9278 grant_chunk() {
9279         local tgt=$1
9280         local max_brw_size
9281         local grant_extent_tax
9282
9283         max_brw_size=$(import_param $tgt max_brw_size)
9284
9285         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9286
9287         echo $(((max_brw_size + grant_extent_tax) * 2))
9288 }
9289
9290 test_64d() {
9291         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9292                 skip "OST < 2.10.55 doesn't limit grants enough"
9293
9294         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9295
9296         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9297                 skip "no grant_param connect flag"
9298
9299         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9300
9301         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9302         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9303
9304
9305         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9306         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9307
9308         $LFS setstripe $DIR/$tfile -i 0 -c 1
9309         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9310         ddpid=$!
9311
9312         while kill -0 $ddpid; do
9313                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9314
9315                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9316                         kill $ddpid
9317                         error "cur_grant $cur_grant > $max_cur_granted"
9318                 fi
9319
9320                 sleep 1
9321         done
9322 }
9323 run_test 64d "check grant limit exceed"
9324
9325 check_grants() {
9326         local tgt=$1
9327         local expected=$2
9328         local msg=$3
9329         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9330
9331         ((cur_grants == expected)) ||
9332                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9333 }
9334
9335 round_up_p2() {
9336         echo $((($1 + $2 - 1) & ~($2 - 1)))
9337 }
9338
9339 test_64e() {
9340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9341         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9342                 skip "Need OSS version at least 2.11.56"
9343
9344         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9345         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9346         $LCTL set_param debug=+cache
9347
9348         # Remount client to reset grant
9349         remount_client $MOUNT || error "failed to remount client"
9350         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9351
9352         local init_grants=$(import_param $osc_tgt initial_grant)
9353
9354         check_grants $osc_tgt $init_grants "init grants"
9355
9356         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9357         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9358         local gbs=$(import_param $osc_tgt grant_block_size)
9359
9360         # write random number of bytes from max_brw_size / 4 to max_brw_size
9361         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9362         # align for direct io
9363         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9364         # round to grant consumption unit
9365         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9366
9367         local grants=$((wb_round_up + extent_tax))
9368
9369         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9370
9371         # define OBD_FAIL_TGT_NO_GRANT 0x725
9372         # make the server not grant more back
9373         do_facet ost1 $LCTL set_param fail_loc=0x725
9374         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9375
9376         do_facet ost1 $LCTL set_param fail_loc=0
9377
9378         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9379
9380         rm -f $DIR/$tfile || error "rm failed"
9381
9382         # Remount client to reset grant
9383         remount_client $MOUNT || error "failed to remount client"
9384         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9385
9386         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9387
9388         # define OBD_FAIL_TGT_NO_GRANT 0x725
9389         # make the server not grant more back
9390         do_facet ost1 $LCTL set_param fail_loc=0x725
9391         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9392         do_facet ost1 $LCTL set_param fail_loc=0
9393
9394         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9395 }
9396 run_test 64e "check grant consumption (no grant allocation)"
9397
9398 test_64f() {
9399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9400
9401         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9402         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9403         $LCTL set_param debug=+cache
9404
9405         # Remount client to reset grant
9406         remount_client $MOUNT || error "failed to remount client"
9407         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9408
9409         local init_grants=$(import_param $osc_tgt initial_grant)
9410         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9411         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9412         local gbs=$(import_param $osc_tgt grant_block_size)
9413         local chunk=$(grant_chunk $osc_tgt)
9414
9415         # write random number of bytes from max_brw_size / 4 to max_brw_size
9416         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9417         # align for direct io
9418         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9419         # round to grant consumption unit
9420         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9421
9422         local grants=$((wb_round_up + extent_tax))
9423
9424         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9425         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9426                 error "error writing to $DIR/$tfile"
9427
9428         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9429                 "direct io with grant allocation"
9430
9431         rm -f $DIR/$tfile || error "rm failed"
9432
9433         # Remount client to reset grant
9434         remount_client $MOUNT || error "failed to remount client"
9435         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9436
9437         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9438
9439         local cmd="oO_WRONLY:w${write_bytes}_yc"
9440
9441         $MULTIOP $DIR/$tfile $cmd &
9442         MULTIPID=$!
9443         sleep 1
9444
9445         check_grants $osc_tgt $((init_grants - grants)) \
9446                 "buffered io, not write rpc"
9447
9448         kill -USR1 $MULTIPID
9449         wait
9450
9451         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9452                 "buffered io, one RPC"
9453 }
9454 run_test 64f "check grant consumption (with grant allocation)"
9455
9456 test_64g() {
9457         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9458                 skip "Need MDS version at least 2.14.56"
9459
9460         local mdts=$(comma_list $(mdts_nodes))
9461
9462         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9463                         tr '\n' ' ')
9464         stack_trap "$LCTL set_param $old"
9465
9466         # generate dirty pages and increase dirty granted on MDT
9467         stack_trap "rm -f $DIR/$tfile-*"
9468         for (( i = 0; i < 10; i++)); do
9469                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9470                         error "can't set stripe"
9471                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9472                         error "can't dd"
9473                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9474                         $LFS getstripe $DIR/$tfile-$i
9475                         error "not DoM file"
9476                 }
9477         done
9478
9479         # flush dirty pages
9480         sync
9481
9482         # wait until grant shrink reset grant dirty on MDTs
9483         for ((i = 0; i < 120; i++)); do
9484                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9485                         awk '{sum=sum+$1} END {print sum}')
9486                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9487                 echo "$grant_dirty grants, $vm_dirty pages"
9488                 (( grant_dirty + vm_dirty == 0 )) && break
9489                 (( i == 3 )) && sync &&
9490                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9491                 sleep 1
9492         done
9493
9494         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9495                 awk '{sum=sum+$1} END {print sum}')
9496         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9497 }
9498 run_test 64g "grant shrink on MDT"
9499
9500 test_64h() {
9501         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9502                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9503
9504         local instance=$($LFS getname -i $DIR)
9505         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9506         local num_exps=$(do_facet ost1 \
9507             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9508         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9509         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9510         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9511
9512         # 10MiB is for file to be written, max_brw_size * 16 *
9513         # num_exps is space reserve so that tgt_grant_shrink() decided
9514         # to not shrink
9515         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9516         (( avail * 1024 < expect )) &&
9517                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9518
9519         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9520         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9521         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9522         $LCTL set_param osc.*OST0000*.grant_shrink=1
9523         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9524
9525         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9527
9528         # drop cache so that coming read would do rpc
9529         cancel_lru_locks osc
9530
9531         # shrink interval is set to 10, pause for 7 seconds so that
9532         # grant thread did not wake up yet but coming read entered
9533         # shrink mode for rpc (osc_should_shrink_grant())
9534         sleep 7
9535
9536         declare -a cur_grant_bytes
9537         declare -a tot_granted
9538         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9539         tot_granted[0]=$(do_facet ost1 \
9540             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9541
9542         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9543
9544         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9545         tot_granted[1]=$(do_facet ost1 \
9546             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9547
9548         # grant change should be equal on both sides
9549         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9550                 tot_granted[0] - tot_granted[1])) ||
9551                 error "grant change mismatch, "                                \
9552                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9553                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9554 }
9555 run_test 64h "grant shrink on read"
9556
9557 test_64i() {
9558         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9559                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9560
9561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9562         remote_ost_nodsh && skip "remote OSTs with nodsh"
9563
9564         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9565
9566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9567
9568         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9569         local instance=$($LFS getname -i $DIR)
9570
9571         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9572         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9573
9574         # shrink grants and simulate rpc loss
9575         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9576         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9577         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9578
9579         fail ost1
9580
9581         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9582
9583         local testid=$(echo $TESTNAME | tr '_' ' ')
9584
9585         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9586                 grep "GRANT, real grant" &&
9587                 error "client has more grants then it owns" || true
9588 }
9589 run_test 64i "shrink on reconnect"
9590
9591 # bug 1414 - set/get directories' stripe info
9592 test_65a() {
9593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9594
9595         test_mkdir $DIR/$tdir
9596         touch $DIR/$tdir/f1
9597         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9598 }
9599 run_test 65a "directory with no stripe info"
9600
9601 test_65b() {
9602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9603
9604         test_mkdir $DIR/$tdir
9605         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9606
9607         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9608                                                 error "setstripe"
9609         touch $DIR/$tdir/f2
9610         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9611 }
9612 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9613
9614 test_65c() {
9615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9616         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9617
9618         test_mkdir $DIR/$tdir
9619         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9620
9621         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9622                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9623         touch $DIR/$tdir/f3
9624         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9625 }
9626 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9627
9628 test_65d() {
9629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9630
9631         test_mkdir $DIR/$tdir
9632         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9633         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9634
9635         if [[ $STRIPECOUNT -le 0 ]]; then
9636                 sc=1
9637         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9638                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9639                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9640         else
9641                 sc=$(($STRIPECOUNT - 1))
9642         fi
9643         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9644         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9645         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9646                 error "lverify failed"
9647 }
9648 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9649
9650 test_65e() {
9651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9652
9653         test_mkdir $DIR/$tdir
9654
9655         $LFS setstripe $DIR/$tdir || error "setstripe"
9656         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9657                                         error "no stripe info failed"
9658         touch $DIR/$tdir/f6
9659         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9660 }
9661 run_test 65e "directory setstripe defaults"
9662
9663 test_65f() {
9664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9665
9666         test_mkdir $DIR/${tdir}f
9667         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9668                 error "setstripe succeeded" || true
9669 }
9670 run_test 65f "dir setstripe permission (should return error) ==="
9671
9672 test_65g() {
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674
9675         test_mkdir $DIR/$tdir
9676         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9677
9678         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9679                 error "setstripe -S failed"
9680         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9681         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9682                 error "delete default stripe failed"
9683 }
9684 run_test 65g "directory setstripe -d"
9685
9686 test_65h() {
9687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9688
9689         test_mkdir $DIR/$tdir
9690         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9691
9692         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9693                 error "setstripe -S failed"
9694         test_mkdir $DIR/$tdir/dd1
9695         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9696                 error "stripe info inherit failed"
9697 }
9698 run_test 65h "directory stripe info inherit ===================="
9699
9700 test_65i() {
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702
9703         save_layout_restore_at_exit $MOUNT
9704
9705         # bug6367: set non-default striping on root directory
9706         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9707
9708         # bug12836: getstripe on -1 default directory striping
9709         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9710
9711         # bug12836: getstripe -v on -1 default directory striping
9712         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9713
9714         # bug12836: new find on -1 default directory striping
9715         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9716 }
9717 run_test 65i "various tests to set root directory striping"
9718
9719 test_65j() { # bug6367
9720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9721
9722         sync; sleep 1
9723
9724         # if we aren't already remounting for each test, do so for this test
9725         if [ "$I_MOUNTED" = "yes" ]; then
9726                 cleanup || error "failed to unmount"
9727                 setup
9728         fi
9729
9730         save_layout_restore_at_exit $MOUNT
9731
9732         $LFS setstripe -d $MOUNT || error "setstripe failed"
9733 }
9734 run_test 65j "set default striping on root directory (bug 6367)="
9735
9736 cleanup_65k() {
9737         rm -rf $DIR/$tdir
9738         wait_delete_completed
9739         do_facet $SINGLEMDS "lctl set_param -n \
9740                 osp.$ost*MDT0000.max_create_count=$max_count"
9741         do_facet $SINGLEMDS "lctl set_param -n \
9742                 osp.$ost*MDT0000.create_count=$count"
9743         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9744         echo $INACTIVE_OSC "is Activate"
9745
9746         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9747 }
9748
9749 test_65k() { # bug11679
9750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9751         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9752         remote_mds_nodsh && skip "remote MDS with nodsh"
9753
9754         local disable_precreate=true
9755         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9756                 disable_precreate=false
9757
9758         echo "Check OST status: "
9759         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9760                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9761
9762         for OSC in $MDS_OSCS; do
9763                 echo $OSC "is active"
9764                 do_facet $SINGLEMDS lctl --device %$OSC activate
9765         done
9766
9767         for INACTIVE_OSC in $MDS_OSCS; do
9768                 local ost=$(osc_to_ost $INACTIVE_OSC)
9769                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9770                                lov.*md*.target_obd |
9771                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9772
9773                 mkdir -p $DIR/$tdir
9774                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9775                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9776
9777                 echo "Deactivate: " $INACTIVE_OSC
9778                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9779
9780                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9781                               osp.$ost*MDT0000.create_count")
9782                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9783                                   osp.$ost*MDT0000.max_create_count")
9784                 $disable_precreate &&
9785                         do_facet $SINGLEMDS "lctl set_param -n \
9786                                 osp.$ost*MDT0000.max_create_count=0"
9787
9788                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9789                         [ -f $DIR/$tdir/$idx ] && continue
9790                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9791                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9792                                 { cleanup_65k;
9793                                   error "setstripe $idx should succeed"; }
9794                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9795                 done
9796                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9797                 rmdir $DIR/$tdir
9798
9799                 do_facet $SINGLEMDS "lctl set_param -n \
9800                         osp.$ost*MDT0000.max_create_count=$max_count"
9801                 do_facet $SINGLEMDS "lctl set_param -n \
9802                         osp.$ost*MDT0000.create_count=$count"
9803                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9804                 echo $INACTIVE_OSC "is Activate"
9805
9806                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9807         done
9808 }
9809 run_test 65k "validate manual striping works properly with deactivated OSCs"
9810
9811 test_65l() { # bug 12836
9812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9813
9814         test_mkdir -p $DIR/$tdir/test_dir
9815         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9816         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9817 }
9818 run_test 65l "lfs find on -1 stripe dir ========================"
9819
9820 test_65m() {
9821         local layout=$(save_layout $MOUNT)
9822         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9823                 restore_layout $MOUNT $layout
9824                 error "setstripe should fail by non-root users"
9825         }
9826         true
9827 }
9828 run_test 65m "normal user can't set filesystem default stripe"
9829
9830 test_65n() {
9831         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9832         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9833                 skip "Need MDS version at least 2.12.50"
9834         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9835
9836         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9837         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9838         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9839
9840         save_layout_restore_at_exit $MOUNT
9841
9842         # new subdirectory under root directory should not inherit
9843         # the default layout from root
9844         local dir1=$MOUNT/$tdir-1
9845         mkdir $dir1 || error "mkdir $dir1 failed"
9846         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9847                 error "$dir1 shouldn't have LOV EA"
9848
9849         # delete the default layout on root directory
9850         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9851
9852         local dir2=$MOUNT/$tdir-2
9853         mkdir $dir2 || error "mkdir $dir2 failed"
9854         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9855                 error "$dir2 shouldn't have LOV EA"
9856
9857         # set a new striping pattern on root directory
9858         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9859         local new_def_stripe_size=$((def_stripe_size * 2))
9860         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9861                 error "set stripe size on $MOUNT failed"
9862
9863         # new file created in $dir2 should inherit the new stripe size from
9864         # the filesystem default
9865         local file2=$dir2/$tfile-2
9866         touch $file2 || error "touch $file2 failed"
9867
9868         local file2_stripe_size=$($LFS getstripe -S $file2)
9869         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9870         {
9871                 echo "file2_stripe_size: '$file2_stripe_size'"
9872                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9873                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9874         }
9875
9876         local dir3=$MOUNT/$tdir-3
9877         mkdir $dir3 || error "mkdir $dir3 failed"
9878         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9879         # the root layout, which is the actual default layout that will be used
9880         # when new files are created in $dir3.
9881         local dir3_layout=$(get_layout_param $dir3)
9882         local root_dir_layout=$(get_layout_param $MOUNT)
9883         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9884         {
9885                 echo "dir3_layout: '$dir3_layout'"
9886                 echo "root_dir_layout: '$root_dir_layout'"
9887                 error "$dir3 should show the default layout from $MOUNT"
9888         }
9889
9890         # set OST pool on root directory
9891         local pool=$TESTNAME
9892         pool_add $pool || error "add $pool failed"
9893         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9894                 error "add targets to $pool failed"
9895
9896         $LFS setstripe -p $pool $MOUNT ||
9897                 error "set OST pool on $MOUNT failed"
9898
9899         # new file created in $dir3 should inherit the pool from
9900         # the filesystem default
9901         local file3=$dir3/$tfile-3
9902         touch $file3 || error "touch $file3 failed"
9903
9904         local file3_pool=$($LFS getstripe -p $file3)
9905         [[ "$file3_pool" = "$pool" ]] ||
9906                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9907
9908         local dir4=$MOUNT/$tdir-4
9909         mkdir $dir4 || error "mkdir $dir4 failed"
9910         local dir4_layout=$(get_layout_param $dir4)
9911         root_dir_layout=$(get_layout_param $MOUNT)
9912         echo "$LFS getstripe -d $dir4"
9913         $LFS getstripe -d $dir4
9914         echo "$LFS getstripe -d $MOUNT"
9915         $LFS getstripe -d $MOUNT
9916         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9917         {
9918                 echo "dir4_layout: '$dir4_layout'"
9919                 echo "root_dir_layout: '$root_dir_layout'"
9920                 error "$dir4 should show the default layout from $MOUNT"
9921         }
9922
9923         # new file created in $dir4 should inherit the pool from
9924         # the filesystem default
9925         local file4=$dir4/$tfile-4
9926         touch $file4 || error "touch $file4 failed"
9927
9928         local file4_pool=$($LFS getstripe -p $file4)
9929         [[ "$file4_pool" = "$pool" ]] ||
9930                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9931
9932         # new subdirectory under non-root directory should inherit
9933         # the default layout from its parent directory
9934         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9935                 error "set directory layout on $dir4 failed"
9936
9937         local dir5=$dir4/$tdir-5
9938         mkdir $dir5 || error "mkdir $dir5 failed"
9939
9940         dir4_layout=$(get_layout_param $dir4)
9941         local dir5_layout=$(get_layout_param $dir5)
9942         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9943         {
9944                 echo "dir4_layout: '$dir4_layout'"
9945                 echo "dir5_layout: '$dir5_layout'"
9946                 error "$dir5 should inherit the default layout from $dir4"
9947         }
9948
9949         # though subdir under ROOT doesn't inherit default layout, but
9950         # its sub dir/file should be created with default layout.
9951         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9952         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9953                 skip "Need MDS version at least 2.12.59"
9954
9955         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9956         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9957         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9958
9959         if [ $default_lmv_hash == "none" ]; then
9960                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9961         else
9962                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9963                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9964         fi
9965
9966         $LFS setdirstripe -D -c 2 $MOUNT ||
9967                 error "setdirstripe -D -c 2 failed"
9968         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9969         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9970         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9971
9972         # $dir4 layout includes pool
9973         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9974         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9975                 error "pool lost on setstripe"
9976         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9977         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9978                 error "pool lost on compound layout setstripe"
9979 }
9980 run_test 65n "don't inherit default layout from root for new subdirectories"
9981
9982 test_65o() {
9983         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9984                 skip "need MDS version at least 2.14.57"
9985
9986         # set OST pool on root directory
9987         local pool=$TESTNAME
9988
9989         pool_add $pool || error "add $pool failed"
9990         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9991                 error "add targets to $pool failed"
9992
9993         local dir1=$MOUNT/$tdir
9994
9995         mkdir $dir1 || error "mkdir $dir1 failed"
9996
9997         # set a new striping pattern on root directory
9998         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9999
10000         $LFS setstripe -p $pool $dir1 ||
10001                 error "set directory layout on $dir1 failed"
10002
10003         # $dir1 layout includes pool
10004         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10005         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10006                 error "pool lost on setstripe"
10007         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10008         $LFS getstripe $dir1
10009         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10010                 error "pool lost on compound layout setstripe"
10011
10012         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10013                 error "setdirstripe failed on sub-dir with inherited pool"
10014         $LFS getstripe $dir1/dir2
10015         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10016                 error "pool lost on compound layout setdirstripe"
10017
10018         $LFS setstripe -E -1 -c 1 $dir1
10019         $LFS getstripe -d $dir1
10020         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10021                 error "pool lost on setstripe"
10022 }
10023 run_test 65o "pool inheritance for mdt component"
10024
10025 test_65p () { # LU-16152
10026         local src_dir=$DIR/$tdir/src_dir
10027         local dst_dir=$DIR/$tdir/dst_dir
10028         local yaml_file=$DIR/$tdir/layout.yaml
10029         local border
10030
10031         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10032                 skip "Need at least version 2.15.51"
10033
10034         test_mkdir -p $src_dir
10035         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10036                 error "failed to setstripe"
10037         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10038                 error "failed to getstripe"
10039
10040         test_mkdir -p $dst_dir
10041         $LFS setstripe --yaml $yaml_file $dst_dir ||
10042                 error "failed to setstripe with yaml file"
10043         border=$($LFS getstripe -d $dst_dir |
10044                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10045                 error "failed to getstripe"
10046
10047         # 2048M is 0x80000000, or 2147483648
10048         (( $border == 2147483648 )) ||
10049                 error "failed to handle huge number in yaml layout"
10050 }
10051 run_test 65p "setstripe with yaml file and huge number"
10052
10053 # bug 2543 - update blocks count on client
10054 test_66() {
10055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10056
10057         local COUNT=${COUNT:-8}
10058         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10059         sync; sync_all_data; sync; sync_all_data
10060         cancel_lru_locks osc
10061         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10062         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10063 }
10064 run_test 66 "update inode blocks count on client ==============="
10065
10066 meminfo() {
10067         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10068 }
10069
10070 swap_used() {
10071         swapon -s | awk '($1 == "'$1'") { print $4 }'
10072 }
10073
10074 # bug5265, obdfilter oa2dentry return -ENOENT
10075 # #define OBD_FAIL_SRV_ENOENT 0x217
10076 test_69() {
10077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10078         remote_ost_nodsh && skip "remote OST with nodsh"
10079
10080         f="$DIR/$tfile"
10081         $LFS setstripe -c 1 -i 0 $f
10082
10083         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10084
10085         do_facet ost1 lctl set_param fail_loc=0x217
10086         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10087         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10088
10089         do_facet ost1 lctl set_param fail_loc=0
10090         $DIRECTIO write $f 0 2 || error "write error"
10091
10092         cancel_lru_locks osc
10093         $DIRECTIO read $f 0 1 || error "read error"
10094
10095         do_facet ost1 lctl set_param fail_loc=0x217
10096         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10097
10098         do_facet ost1 lctl set_param fail_loc=0
10099         rm -f $f
10100 }
10101 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10102
10103 test_71() {
10104         test_mkdir $DIR/$tdir
10105         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10106         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10107 }
10108 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10109
10110 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10112         [ "$RUNAS_ID" = "$UID" ] &&
10113                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10114         # Check that testing environment is properly set up. Skip if not
10115         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10116                 skip_env "User $RUNAS_ID does not exist - skipping"
10117
10118         touch $DIR/$tfile
10119         chmod 777 $DIR/$tfile
10120         chmod ug+s $DIR/$tfile
10121         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10122                 error "$RUNAS dd $DIR/$tfile failed"
10123         # See if we are still setuid/sgid
10124         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10125                 error "S/gid is not dropped on write"
10126         # Now test that MDS is updated too
10127         cancel_lru_locks mdc
10128         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10129                 error "S/gid is not dropped on MDS"
10130         rm -f $DIR/$tfile
10131 }
10132 run_test 72a "Test that remove suid works properly (bug5695) ===="
10133
10134 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10135         local perm
10136
10137         [ "$RUNAS_ID" = "$UID" ] &&
10138                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10139         [ "$RUNAS_ID" -eq 0 ] &&
10140                 skip_env "RUNAS_ID = 0 -- skipping"
10141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10142         # Check that testing environment is properly set up. Skip if not
10143         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10144                 skip_env "User $RUNAS_ID does not exist - skipping"
10145
10146         touch $DIR/${tfile}-f{g,u}
10147         test_mkdir $DIR/${tfile}-dg
10148         test_mkdir $DIR/${tfile}-du
10149         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10150         chmod g+s $DIR/${tfile}-{f,d}g
10151         chmod u+s $DIR/${tfile}-{f,d}u
10152         for perm in 777 2777 4777; do
10153                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10154                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10155                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10156                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10157         done
10158         true
10159 }
10160 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10161
10162 # bug 3462 - multiple simultaneous MDC requests
10163 test_73() {
10164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10165
10166         test_mkdir $DIR/d73-1
10167         test_mkdir $DIR/d73-2
10168         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10169         pid1=$!
10170
10171         lctl set_param fail_loc=0x80000129
10172         $MULTIOP $DIR/d73-1/f73-2 Oc &
10173         sleep 1
10174         lctl set_param fail_loc=0
10175
10176         $MULTIOP $DIR/d73-2/f73-3 Oc &
10177         pid3=$!
10178
10179         kill -USR1 $pid1
10180         wait $pid1 || return 1
10181
10182         sleep 25
10183
10184         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10185         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10186         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10187
10188         rm -rf $DIR/d73-*
10189 }
10190 run_test 73 "multiple MDC requests (should not deadlock)"
10191
10192 test_74a() { # bug 6149, 6184
10193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10194
10195         touch $DIR/f74a
10196         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10197         #
10198         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10199         # will spin in a tight reconnection loop
10200         $LCTL set_param fail_loc=0x8000030e
10201         # get any lock that won't be difficult - lookup works.
10202         ls $DIR/f74a
10203         $LCTL set_param fail_loc=0
10204         rm -f $DIR/f74a
10205         true
10206 }
10207 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10208
10209 test_74b() { # bug 13310
10210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10211
10212         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10213         #
10214         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10215         # will spin in a tight reconnection loop
10216         $LCTL set_param fail_loc=0x8000030e
10217         # get a "difficult" lock
10218         touch $DIR/f74b
10219         $LCTL set_param fail_loc=0
10220         rm -f $DIR/f74b
10221         true
10222 }
10223 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10224
10225 test_74c() {
10226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10227
10228         #define OBD_FAIL_LDLM_NEW_LOCK
10229         $LCTL set_param fail_loc=0x319
10230         touch $DIR/$tfile && error "touch successful"
10231         $LCTL set_param fail_loc=0
10232         true
10233 }
10234 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10235
10236 slab_lic=/sys/kernel/slab/lustre_inode_cache
10237 num_objects() {
10238         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10239         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10240                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10241 }
10242
10243 test_76a() { # Now for b=20433, added originally in b=1443
10244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10245
10246         cancel_lru_locks osc
10247         # there may be some slab objects cached per core
10248         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10249         local before=$(num_objects)
10250         local count=$((512 * cpus))
10251         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10252         local margin=$((count / 10))
10253         if [[ -f $slab_lic/aliases ]]; then
10254                 local aliases=$(cat $slab_lic/aliases)
10255                 (( aliases > 0 )) && margin=$((margin * aliases))
10256         fi
10257
10258         echo "before slab objects: $before"
10259         for i in $(seq $count); do
10260                 touch $DIR/$tfile
10261                 rm -f $DIR/$tfile
10262         done
10263         cancel_lru_locks osc
10264         local after=$(num_objects)
10265         echo "created: $count, after slab objects: $after"
10266         # shared slab counts are not very accurate, allow significant margin
10267         # the main goal is that the cache growth is not permanently > $count
10268         while (( after > before + margin )); do
10269                 sleep 1
10270                 after=$(num_objects)
10271                 wait=$((wait + 1))
10272                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10273                 if (( wait > 60 )); then
10274                         error "inode slab grew from $before+$margin to $after"
10275                 fi
10276         done
10277 }
10278 run_test 76a "confirm clients recycle inodes properly ===="
10279
10280 test_76b() {
10281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10282         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10283
10284         local count=512
10285         local before=$(num_objects)
10286
10287         for i in $(seq $count); do
10288                 mkdir $DIR/$tdir
10289                 rmdir $DIR/$tdir
10290         done
10291
10292         local after=$(num_objects)
10293         local wait=0
10294
10295         while (( after > before )); do
10296                 sleep 1
10297                 after=$(num_objects)
10298                 wait=$((wait + 1))
10299                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10300                 if (( wait > 60 )); then
10301                         error "inode slab grew from $before to $after"
10302                 fi
10303         done
10304
10305         echo "slab objects before: $before, after: $after"
10306 }
10307 run_test 76b "confirm clients recycle directory inodes properly ===="
10308
10309 export ORIG_CSUM=""
10310 set_checksums()
10311 {
10312         # Note: in sptlrpc modes which enable its own bulk checksum, the
10313         # original crc32_le bulk checksum will be automatically disabled,
10314         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10315         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10316         # In this case set_checksums() will not be no-op, because sptlrpc
10317         # bulk checksum will be enabled all through the test.
10318
10319         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10320         lctl set_param -n osc.*.checksums $1
10321         return 0
10322 }
10323
10324 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10325                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10326 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10327                              tr -d [] | head -n1)}
10328 set_checksum_type()
10329 {
10330         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10331         rc=$?
10332         log "set checksum type to $1, rc = $rc"
10333         return $rc
10334 }
10335
10336 get_osc_checksum_type()
10337 {
10338         # arugment 1: OST name, like OST0000
10339         ost=$1
10340         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10341                         sed 's/.*\[\(.*\)\].*/\1/g')
10342         rc=$?
10343         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10344         echo $checksum_type
10345 }
10346
10347 F77_TMP=$TMP/f77-temp
10348 F77SZ=8
10349 setup_f77() {
10350         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10351                 error "error writing to $F77_TMP"
10352 }
10353
10354 test_77a() { # bug 10889
10355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10356         $GSS && skip_env "could not run with gss"
10357
10358         [ ! -f $F77_TMP ] && setup_f77
10359         set_checksums 1
10360         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10361         set_checksums 0
10362         rm -f $DIR/$tfile
10363 }
10364 run_test 77a "normal checksum read/write operation"
10365
10366 test_77b() { # bug 10889
10367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10368         $GSS && skip_env "could not run with gss"
10369
10370         [ ! -f $F77_TMP ] && setup_f77
10371         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10372         $LCTL set_param fail_loc=0x80000409
10373         set_checksums 1
10374
10375         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10376                 error "dd error: $?"
10377         $LCTL set_param fail_loc=0
10378
10379         for algo in $CKSUM_TYPES; do
10380                 cancel_lru_locks osc
10381                 set_checksum_type $algo
10382                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10383                 $LCTL set_param fail_loc=0x80000408
10384                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10385                 $LCTL set_param fail_loc=0
10386         done
10387         set_checksums 0
10388         set_checksum_type $ORIG_CSUM_TYPE
10389         rm -f $DIR/$tfile
10390 }
10391 run_test 77b "checksum error on client write, read"
10392
10393 cleanup_77c() {
10394         trap 0
10395         set_checksums 0
10396         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10397         $check_ost &&
10398                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10399         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10400         $check_ost && [ -n "$ost_file_prefix" ] &&
10401                 do_facet ost1 rm -f ${ost_file_prefix}\*
10402 }
10403
10404 test_77c() {
10405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10406         $GSS && skip_env "could not run with gss"
10407         remote_ost_nodsh && skip "remote OST with nodsh"
10408
10409         local bad1
10410         local osc_file_prefix
10411         local osc_file
10412         local check_ost=false
10413         local ost_file_prefix
10414         local ost_file
10415         local orig_cksum
10416         local dump_cksum
10417         local fid
10418
10419         # ensure corruption will occur on first OSS/OST
10420         $LFS setstripe -i 0 $DIR/$tfile
10421
10422         [ ! -f $F77_TMP ] && setup_f77
10423         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10424                 error "dd write error: $?"
10425         fid=$($LFS path2fid $DIR/$tfile)
10426
10427         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10428         then
10429                 check_ost=true
10430                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10431                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10432         else
10433                 echo "OSS do not support bulk pages dump upon error"
10434         fi
10435
10436         osc_file_prefix=$($LCTL get_param -n debug_path)
10437         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10438
10439         trap cleanup_77c EXIT
10440
10441         set_checksums 1
10442         # enable bulk pages dump upon error on Client
10443         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10444         # enable bulk pages dump upon error on OSS
10445         $check_ost &&
10446                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10447
10448         # flush Client cache to allow next read to reach OSS
10449         cancel_lru_locks osc
10450
10451         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10452         $LCTL set_param fail_loc=0x80000408
10453         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10454         $LCTL set_param fail_loc=0
10455
10456         rm -f $DIR/$tfile
10457
10458         # check cksum dump on Client
10459         osc_file=$(ls ${osc_file_prefix}*)
10460         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10461         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10462         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10463         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10464         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10465                      cksum)
10466         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10467         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10468                 error "dump content does not match on Client"
10469
10470         $check_ost || skip "No need to check cksum dump on OSS"
10471
10472         # check cksum dump on OSS
10473         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10474         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10475         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10476         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10477         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10478                 error "dump content does not match on OSS"
10479
10480         cleanup_77c
10481 }
10482 run_test 77c "checksum error on client read with debug"
10483
10484 test_77d() { # bug 10889
10485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10486         $GSS && skip_env "could not run with gss"
10487
10488         stack_trap "rm -f $DIR/$tfile"
10489         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10490         $LCTL set_param fail_loc=0x80000409
10491         set_checksums 1
10492         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10493                 error "direct write: rc=$?"
10494         $LCTL set_param fail_loc=0
10495         set_checksums 0
10496
10497         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10498         $LCTL set_param fail_loc=0x80000408
10499         set_checksums 1
10500         cancel_lru_locks osc
10501         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10502                 error "direct read: rc=$?"
10503         $LCTL set_param fail_loc=0
10504         set_checksums 0
10505 }
10506 run_test 77d "checksum error on OST direct write, read"
10507
10508 test_77f() { # bug 10889
10509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10510         $GSS && skip_env "could not run with gss"
10511
10512         set_checksums 1
10513         stack_trap "rm -f $DIR/$tfile"
10514         for algo in $CKSUM_TYPES; do
10515                 cancel_lru_locks osc
10516                 set_checksum_type $algo
10517                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10518                 $LCTL set_param fail_loc=0x409
10519                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10520                         error "direct write succeeded"
10521                 $LCTL set_param fail_loc=0
10522         done
10523         set_checksum_type $ORIG_CSUM_TYPE
10524         set_checksums 0
10525 }
10526 run_test 77f "repeat checksum error on write (expect error)"
10527
10528 test_77g() { # bug 10889
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530         $GSS && skip_env "could not run with gss"
10531         remote_ost_nodsh && skip "remote OST with nodsh"
10532
10533         [ ! -f $F77_TMP ] && setup_f77
10534
10535         local file=$DIR/$tfile
10536         stack_trap "rm -f $file" EXIT
10537
10538         $LFS setstripe -c 1 -i 0 $file
10539         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10540         do_facet ost1 lctl set_param fail_loc=0x8000021a
10541         set_checksums 1
10542         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10543                 error "write error: rc=$?"
10544         do_facet ost1 lctl set_param fail_loc=0
10545         set_checksums 0
10546
10547         cancel_lru_locks osc
10548         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10549         do_facet ost1 lctl set_param fail_loc=0x8000021b
10550         set_checksums 1
10551         cmp $F77_TMP $file || error "file compare failed"
10552         do_facet ost1 lctl set_param fail_loc=0
10553         set_checksums 0
10554 }
10555 run_test 77g "checksum error on OST write, read"
10556
10557 test_77k() { # LU-10906
10558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10559         $GSS && skip_env "could not run with gss"
10560
10561         local cksum_param="osc.$FSNAME*.checksums"
10562         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10563         local checksum
10564         local i
10565
10566         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10567         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10568         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10569
10570         for i in 0 1; do
10571                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10572                         error "failed to set checksum=$i on MGS"
10573                 wait_update $HOSTNAME "$get_checksum" $i
10574                 #remount
10575                 echo "remount client, checksum should be $i"
10576                 remount_client $MOUNT || error "failed to remount client"
10577                 checksum=$(eval $get_checksum)
10578                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10579         done
10580         # remove persistent param to avoid races with checksum mountopt below
10581         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10582                 error "failed to delete checksum on MGS"
10583
10584         for opt in "checksum" "nochecksum"; do
10585                 #remount with mount option
10586                 echo "remount client with option $opt, checksum should be $i"
10587                 umount_client $MOUNT || error "failed to umount client"
10588                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10589                         error "failed to mount client with option '$opt'"
10590                 checksum=$(eval $get_checksum)
10591                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10592                 i=$((i - 1))
10593         done
10594
10595         remount_client $MOUNT || error "failed to remount client"
10596 }
10597 run_test 77k "enable/disable checksum correctly"
10598
10599 test_77l() {
10600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10601         $GSS && skip_env "could not run with gss"
10602
10603         set_checksums 1
10604         stack_trap "set_checksums $ORIG_CSUM" EXIT
10605         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10606
10607         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10608
10609         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10610         for algo in $CKSUM_TYPES; do
10611                 set_checksum_type $algo || error "fail to set checksum type $algo"
10612                 osc_algo=$(get_osc_checksum_type OST0000)
10613                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10614
10615                 # no locks, no reqs to let the connection idle
10616                 cancel_lru_locks osc
10617                 lru_resize_disable osc
10618                 wait_osc_import_state client ost1 IDLE
10619
10620                 # ensure ost1 is connected
10621                 stat $DIR/$tfile >/dev/null || error "can't stat"
10622                 wait_osc_import_state client ost1 FULL
10623
10624                 osc_algo=$(get_osc_checksum_type OST0000)
10625                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10626         done
10627         return 0
10628 }
10629 run_test 77l "preferred checksum type is remembered after reconnected"
10630
10631 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10632 rm -f $F77_TMP
10633 unset F77_TMP
10634
10635 test_77m() {
10636         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10637                 skip "Need at least version 2.14.52"
10638         local param=checksum_speed
10639
10640         $LCTL get_param $param || error "reading $param failed"
10641
10642         csum_speeds=$($LCTL get_param -n $param)
10643
10644         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10645                 error "known checksum types are missing"
10646 }
10647 run_test 77m "Verify checksum_speed is correctly read"
10648
10649 check_filefrag_77n() {
10650         local nr_ext=0
10651         local starts=()
10652         local ends=()
10653
10654         while read extidx a b start end rest; do
10655                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10656                         nr_ext=$(( $nr_ext + 1 ))
10657                         starts+=( ${start%..} )
10658                         ends+=( ${end%:} )
10659                 fi
10660         done < <( filefrag -sv $1 )
10661
10662         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10663         return 1
10664 }
10665
10666 test_77n() {
10667         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10668
10669         touch $DIR/$tfile
10670         $TRUNCATE $DIR/$tfile 0
10671         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10672         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10673         check_filefrag_77n $DIR/$tfile ||
10674                 skip "$tfile blocks not contiguous around hole"
10675
10676         set_checksums 1
10677         stack_trap "set_checksums $ORIG_CSUM" EXIT
10678         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10679         stack_trap "rm -f $DIR/$tfile"
10680
10681         for algo in $CKSUM_TYPES; do
10682                 if [[ "$algo" =~ ^t10 ]]; then
10683                         set_checksum_type $algo ||
10684                                 error "fail to set checksum type $algo"
10685                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10686                                 error "fail to read $tfile with $algo"
10687                 fi
10688         done
10689         rm -f $DIR/$tfile
10690         return 0
10691 }
10692 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10693
10694 test_77o() {
10695         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10696                 skip "Need MDS version at least 2.14.55"
10697         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10698                 skip "Need OST version at least 2.14.55"
10699         local ofd=obdfilter
10700         local mdt=mdt
10701
10702         # print OST checksum_type
10703         echo "$ofd.$FSNAME-*.checksum_type:"
10704         do_nodes $(comma_list $(osts_nodes)) \
10705                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10706
10707         # print MDT checksum_type
10708         echo "$mdt.$FSNAME-*.checksum_type:"
10709         do_nodes $(comma_list $(mdts_nodes)) \
10710                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10711
10712         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10713                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10714
10715         (( $o_count == $OSTCOUNT )) ||
10716                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10717
10718         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10719                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10720
10721         (( $m_count == $MDSCOUNT )) ||
10722                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10723 }
10724 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10725
10726 cleanup_test_78() {
10727         trap 0
10728         rm -f $DIR/$tfile
10729 }
10730
10731 test_78() { # bug 10901
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733         remote_ost || skip_env "local OST"
10734
10735         NSEQ=5
10736         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10737         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10738         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10739         echo "MemTotal: $MEMTOTAL"
10740
10741         # reserve 256MB of memory for the kernel and other running processes,
10742         # and then take 1/2 of the remaining memory for the read/write buffers.
10743         if [ $MEMTOTAL -gt 512 ] ;then
10744                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10745         else
10746                 # for those poor memory-starved high-end clusters...
10747                 MEMTOTAL=$((MEMTOTAL / 2))
10748         fi
10749         echo "Mem to use for directio: $MEMTOTAL"
10750
10751         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10752         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10753         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10754         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10755                 head -n1)
10756         echo "Smallest OST: $SMALLESTOST"
10757         [[ $SMALLESTOST -lt 10240 ]] &&
10758                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10759
10760         trap cleanup_test_78 EXIT
10761
10762         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10763                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10764
10765         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10766         echo "File size: $F78SIZE"
10767         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10768         for i in $(seq 1 $NSEQ); do
10769                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10770                 echo directIO rdwr round $i of $NSEQ
10771                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10772         done
10773
10774         cleanup_test_78
10775 }
10776 run_test 78 "handle large O_DIRECT writes correctly ============"
10777
10778 test_79() { # bug 12743
10779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10780
10781         wait_delete_completed
10782
10783         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10784         BKFREE=$(calc_osc_kbytes kbytesfree)
10785         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10786
10787         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10788         DFTOTAL=`echo $STRING | cut -d, -f1`
10789         DFUSED=`echo $STRING  | cut -d, -f2`
10790         DFAVAIL=`echo $STRING | cut -d, -f3`
10791         DFFREE=$(($DFTOTAL - $DFUSED))
10792
10793         ALLOWANCE=$((64 * $OSTCOUNT))
10794
10795         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10796            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10797                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10798         fi
10799         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10800            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10801                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10802         fi
10803         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10804            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10805                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10806         fi
10807 }
10808 run_test 79 "df report consistency check ======================="
10809
10810 test_80() { # bug 10718
10811         remote_ost_nodsh && skip "remote OST with nodsh"
10812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10813
10814         # relax strong synchronous semantics for slow backends like ZFS
10815         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10816                 local soc="obdfilter.*.sync_lock_cancel"
10817                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10818
10819                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10820                 if [ -z "$save" ]; then
10821                         soc="obdfilter.*.sync_on_lock_cancel"
10822                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10823                 fi
10824
10825                 if [ "$save" != "never" ]; then
10826                         local hosts=$(comma_list $(osts_nodes))
10827
10828                         do_nodes $hosts $LCTL set_param $soc=never
10829                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10830                 fi
10831         fi
10832
10833         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10834         sync; sleep 1; sync
10835         local before=$(date +%s)
10836         cancel_lru_locks osc
10837         local after=$(date +%s)
10838         local diff=$((after - before))
10839         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10840
10841         rm -f $DIR/$tfile
10842 }
10843 run_test 80 "Page eviction is equally fast at high offsets too"
10844
10845 test_81a() { # LU-456
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost_nodsh && skip "remote OST with nodsh"
10848
10849         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10850         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10851         do_facet ost1 lctl set_param fail_loc=0x80000228
10852
10853         # write should trigger a retry and success
10854         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10855         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10856         RC=$?
10857         if [ $RC -ne 0 ] ; then
10858                 error "write should success, but failed for $RC"
10859         fi
10860 }
10861 run_test 81a "OST should retry write when get -ENOSPC ==============="
10862
10863 test_81b() { # LU-456
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         remote_ost_nodsh && skip "remote OST with nodsh"
10866
10867         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10868         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10869         do_facet ost1 lctl set_param fail_loc=0x228
10870
10871         # write should retry several times and return -ENOSPC finally
10872         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10873         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10874         RC=$?
10875         ENOSPC=28
10876         if [ $RC -ne $ENOSPC ] ; then
10877                 error "dd should fail for -ENOSPC, but succeed."
10878         fi
10879 }
10880 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10881
10882 test_99() {
10883         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10884
10885         test_mkdir $DIR/$tdir.cvsroot
10886         chown $RUNAS_ID $DIR/$tdir.cvsroot
10887
10888         cd $TMP
10889         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10890
10891         cd /etc/init.d
10892         # some versions of cvs import exit(1) when asked to import links or
10893         # files they can't read.  ignore those files.
10894         local toignore=$(find . -type l -printf '-I %f\n' -o \
10895                          ! -perm /4 -printf '-I %f\n')
10896         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10897                 $tdir.reposname vtag rtag
10898
10899         cd $DIR
10900         test_mkdir $DIR/$tdir.reposname
10901         chown $RUNAS_ID $DIR/$tdir.reposname
10902         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10903
10904         cd $DIR/$tdir.reposname
10905         $RUNAS touch foo99
10906         $RUNAS cvs add -m 'addmsg' foo99
10907         $RUNAS cvs update
10908         $RUNAS cvs commit -m 'nomsg' foo99
10909         rm -fr $DIR/$tdir.cvsroot
10910 }
10911 run_test 99 "cvs strange file/directory operations"
10912
10913 test_100() {
10914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10915         [[ "$NETTYPE" =~ tcp ]] ||
10916                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10917         remote_ost_nodsh && skip "remote OST with nodsh"
10918         remote_mds_nodsh && skip "remote MDS with nodsh"
10919         remote_servers ||
10920                 skip "useless for local single node setup"
10921
10922         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10923                 [ "$PROT" != "tcp" ] && continue
10924                 RPORT=$(echo $REMOTE | cut -d: -f2)
10925                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10926
10927                 rc=0
10928                 LPORT=`echo $LOCAL | cut -d: -f2`
10929                 if [ $LPORT -ge 1024 ]; then
10930                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10931                         netstat -tna
10932                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10933                 fi
10934         done
10935         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10936 }
10937 run_test 100 "check local port using privileged port ==========="
10938
10939 function get_named_value()
10940 {
10941     local tag=$1
10942
10943     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10944 }
10945
10946 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10947                    awk '/^max_cached_mb/ { print $2 }')
10948
10949 cleanup_101a() {
10950         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10951         trap 0
10952 }
10953
10954 test_101a() {
10955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10956
10957         local s
10958         local discard
10959         local nreads=10000
10960         local cache_limit=32
10961
10962         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10963         trap cleanup_101a EXIT
10964         $LCTL set_param -n llite.*.read_ahead_stats=0
10965         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10966
10967         #
10968         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10969         #
10970         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10971         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10972
10973         discard=0
10974         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10975                    get_named_value 'read.but.discarded'); do
10976                         discard=$(($discard + $s))
10977         done
10978         cleanup_101a
10979
10980         $LCTL get_param osc.*-osc*.rpc_stats
10981         $LCTL get_param llite.*.read_ahead_stats
10982
10983         # Discard is generally zero, but sometimes a few random reads line up
10984         # and trigger larger readahead, which is wasted & leads to discards.
10985         if [[ $(($discard)) -gt $nreads ]]; then
10986                 error "too many ($discard) discarded pages"
10987         fi
10988         rm -f $DIR/$tfile || true
10989 }
10990 run_test 101a "check read-ahead for random reads"
10991
10992 setup_test101bc() {
10993         test_mkdir $DIR/$tdir
10994         local ssize=$1
10995         local FILE_LENGTH=$2
10996         STRIPE_OFFSET=0
10997
10998         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10999
11000         local list=$(comma_list $(osts_nodes))
11001         set_osd_param $list '' read_cache_enable 0
11002         set_osd_param $list '' writethrough_cache_enable 0
11003
11004         trap cleanup_test101bc EXIT
11005         # prepare the read-ahead file
11006         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11007
11008         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11009                                 count=$FILE_SIZE_MB 2> /dev/null
11010
11011 }
11012
11013 cleanup_test101bc() {
11014         trap 0
11015         rm -rf $DIR/$tdir
11016         rm -f $DIR/$tfile
11017
11018         local list=$(comma_list $(osts_nodes))
11019         set_osd_param $list '' read_cache_enable 1
11020         set_osd_param $list '' writethrough_cache_enable 1
11021 }
11022
11023 calc_total() {
11024         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11025 }
11026
11027 ra_check_101() {
11028         local read_size=$1
11029         local stripe_size=$2
11030         local stride_length=$((stripe_size / read_size))
11031         local stride_width=$((stride_length * OSTCOUNT))
11032         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11033                                 (stride_width - stride_length) ))
11034         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11035                   get_named_value 'read.but.discarded' | calc_total)
11036
11037         if [[ $discard -gt $discard_limit ]]; then
11038                 $LCTL get_param llite.*.read_ahead_stats
11039                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11040         else
11041                 echo "Read-ahead success for size ${read_size}"
11042         fi
11043 }
11044
11045 test_101b() {
11046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11048
11049         local STRIPE_SIZE=1048576
11050         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11051
11052         if [ $SLOW == "yes" ]; then
11053                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11054         else
11055                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11056         fi
11057
11058         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11059
11060         # prepare the read-ahead file
11061         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11062         cancel_lru_locks osc
11063         for BIDX in 2 4 8 16 32 64 128 256
11064         do
11065                 local BSIZE=$((BIDX*4096))
11066                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11067                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11068                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11069                 $LCTL set_param -n llite.*.read_ahead_stats=0
11070                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11071                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11072                 cancel_lru_locks osc
11073                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11074         done
11075         cleanup_test101bc
11076         true
11077 }
11078 run_test 101b "check stride-io mode read-ahead ================="
11079
11080 test_101c() {
11081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11082
11083         local STRIPE_SIZE=1048576
11084         local FILE_LENGTH=$((STRIPE_SIZE*100))
11085         local nreads=10000
11086         local rsize=65536
11087         local osc_rpc_stats
11088
11089         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11090
11091         cancel_lru_locks osc
11092         $LCTL set_param osc.*.rpc_stats=0
11093         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11094         $LCTL get_param osc.*.rpc_stats
11095         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11096                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11097                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11098                 local size
11099
11100                 if [ $lines -le 20 ]; then
11101                         echo "continue debug"
11102                         continue
11103                 fi
11104                 for size in 1 2 4 8; do
11105                         local rpc=$(echo "$stats" |
11106                                     awk '($1 == "'$size':") {print $2; exit; }')
11107                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11108                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11109                 done
11110                 echo "$osc_rpc_stats check passed!"
11111         done
11112         cleanup_test101bc
11113         true
11114 }
11115 run_test 101c "check stripe_size aligned read-ahead"
11116
11117 test_101d() {
11118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11119
11120         local file=$DIR/$tfile
11121         local sz_MB=${FILESIZE_101d:-80}
11122         local ra_MB=${READAHEAD_MB:-40}
11123
11124         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11125         [ $free_MB -lt $sz_MB ] &&
11126                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11127
11128         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11129         $LFS setstripe -c -1 $file || error "setstripe failed"
11130
11131         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11132         echo Cancel LRU locks on lustre client to flush the client cache
11133         cancel_lru_locks osc
11134
11135         echo Disable read-ahead
11136         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11137         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11138         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11139         $LCTL get_param -n llite.*.max_read_ahead_mb
11140
11141         echo "Reading the test file $file with read-ahead disabled"
11142         local sz_KB=$((sz_MB * 1024 / 4))
11143         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11144         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11145         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11146                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11147
11148         echo "Cancel LRU locks on lustre client to flush the client cache"
11149         cancel_lru_locks osc
11150         echo Enable read-ahead with ${ra_MB}MB
11151         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11152
11153         echo "Reading the test file $file with read-ahead enabled"
11154         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11155                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11156
11157         echo "read-ahead disabled time read $raOFF"
11158         echo "read-ahead enabled time read $raON"
11159
11160         rm -f $file
11161         wait_delete_completed
11162
11163         # use awk for this check instead of bash because it handles decimals
11164         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11165                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11166 }
11167 run_test 101d "file read with and without read-ahead enabled"
11168
11169 test_101e() {
11170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11171
11172         local file=$DIR/$tfile
11173         local size_KB=500  #KB
11174         local count=100
11175         local bsize=1024
11176
11177         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11178         local need_KB=$((count * size_KB))
11179         [[ $free_KB -le $need_KB ]] &&
11180                 skip_env "Need free space $need_KB, have $free_KB"
11181
11182         echo "Creating $count ${size_KB}K test files"
11183         for ((i = 0; i < $count; i++)); do
11184                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11185         done
11186
11187         echo "Cancel LRU locks on lustre client to flush the client cache"
11188         cancel_lru_locks $OSC
11189
11190         echo "Reset readahead stats"
11191         $LCTL set_param -n llite.*.read_ahead_stats=0
11192
11193         for ((i = 0; i < $count; i++)); do
11194                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11195         done
11196
11197         $LCTL get_param llite.*.max_cached_mb
11198         $LCTL get_param llite.*.read_ahead_stats
11199         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11200                      get_named_value 'misses' | calc_total)
11201
11202         for ((i = 0; i < $count; i++)); do
11203                 rm -rf $file.$i 2>/dev/null
11204         done
11205
11206         #10000 means 20% reads are missing in readahead
11207         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11208 }
11209 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11210
11211 test_101f() {
11212         which iozone || skip_env "no iozone installed"
11213
11214         local old_debug=$($LCTL get_param debug)
11215         old_debug=${old_debug#*=}
11216         $LCTL set_param debug="reada mmap"
11217
11218         # create a test file
11219         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11220
11221         echo Cancel LRU locks on lustre client to flush the client cache
11222         cancel_lru_locks osc
11223
11224         echo Reset readahead stats
11225         $LCTL set_param -n llite.*.read_ahead_stats=0
11226
11227         echo mmap read the file with small block size
11228         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11229                 > /dev/null 2>&1
11230
11231         echo checking missing pages
11232         $LCTL get_param llite.*.read_ahead_stats
11233         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11234                         get_named_value 'misses' | calc_total)
11235
11236         $LCTL set_param debug="$old_debug"
11237         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11238         rm -f $DIR/$tfile
11239 }
11240 run_test 101f "check mmap read performance"
11241
11242 test_101g_brw_size_test() {
11243         local mb=$1
11244         local pages=$((mb * 1048576 / PAGE_SIZE))
11245         local file=$DIR/$tfile
11246
11247         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11248                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11249         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11250                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11251                         return 2
11252         done
11253
11254         stack_trap "rm -f $file" EXIT
11255         $LCTL set_param -n osc.*.rpc_stats=0
11256
11257         # 10 RPCs should be enough for the test
11258         local count=10
11259         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11260                 { error "dd write ${mb} MB blocks failed"; return 3; }
11261         cancel_lru_locks osc
11262         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11263                 { error "dd write ${mb} MB blocks failed"; return 4; }
11264
11265         # calculate number of full-sized read and write RPCs
11266         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11267                 sed -n '/pages per rpc/,/^$/p' |
11268                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11269                 END { print reads,writes }'))
11270         # allow one extra full-sized read RPC for async readahead
11271         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11272                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11273         [[ ${rpcs[1]} == $count ]] ||
11274                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11275 }
11276
11277 test_101g() {
11278         remote_ost_nodsh && skip "remote OST with nodsh"
11279
11280         local rpcs
11281         local osts=$(get_facets OST)
11282         local list=$(comma_list $(osts_nodes))
11283         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11284         local brw_size="obdfilter.*.brw_size"
11285
11286         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11287
11288         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11289
11290         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11291                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11292                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11293            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11294                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11295                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11296
11297                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11298                         suffix="M"
11299
11300                 if [[ $orig_mb -lt 16 ]]; then
11301                         save_lustre_params $osts "$brw_size" > $p
11302                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11303                                 error "set 16MB RPC size failed"
11304
11305                         echo "remount client to enable new RPC size"
11306                         remount_client $MOUNT || error "remount_client failed"
11307                 fi
11308
11309                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11310                 # should be able to set brw_size=12, but no rpc_stats for that
11311                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11312         fi
11313
11314         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11315
11316         if [[ $orig_mb -lt 16 ]]; then
11317                 restore_lustre_params < $p
11318                 remount_client $MOUNT || error "remount_client restore failed"
11319         fi
11320
11321         rm -f $p $DIR/$tfile
11322 }
11323 run_test 101g "Big bulk(4/16 MiB) readahead"
11324
11325 test_101h() {
11326         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11327
11328         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11329                 error "dd 70M file failed"
11330         echo Cancel LRU locks on lustre client to flush the client cache
11331         cancel_lru_locks osc
11332
11333         echo "Reset readahead stats"
11334         $LCTL set_param -n llite.*.read_ahead_stats 0
11335
11336         echo "Read 10M of data but cross 64M bundary"
11337         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11338         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11339                      get_named_value 'misses' | calc_total)
11340         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11341         rm -f $p $DIR/$tfile
11342 }
11343 run_test 101h "Readahead should cover current read window"
11344
11345 test_101i() {
11346         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11347                 error "dd 10M file failed"
11348
11349         local max_per_file_mb=$($LCTL get_param -n \
11350                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11351         cancel_lru_locks osc
11352         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11353         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11354                 error "set max_read_ahead_per_file_mb to 1 failed"
11355
11356         echo "Reset readahead stats"
11357         $LCTL set_param llite.*.read_ahead_stats=0
11358
11359         dd if=$DIR/$tfile of=/dev/null bs=2M
11360
11361         $LCTL get_param llite.*.read_ahead_stats
11362         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11363                      awk '/misses/ { print $2 }')
11364         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11365         rm -f $DIR/$tfile
11366 }
11367 run_test 101i "allow current readahead to exceed reservation"
11368
11369 test_101j() {
11370         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11371                 error "setstripe $DIR/$tfile failed"
11372         local file_size=$((1048576 * 16))
11373         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11374         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11375
11376         echo Disable read-ahead
11377         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11378
11379         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11380         for blk in $PAGE_SIZE 1048576 $file_size; do
11381                 cancel_lru_locks osc
11382                 echo "Reset readahead stats"
11383                 $LCTL set_param -n llite.*.read_ahead_stats=0
11384                 local count=$(($file_size / $blk))
11385                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11386                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11387                              get_named_value 'failed.to.fast.read' | calc_total)
11388                 $LCTL get_param -n llite.*.read_ahead_stats
11389                 [ $miss -eq $count ] || error "expected $count got $miss"
11390         done
11391
11392         rm -f $p $DIR/$tfile
11393 }
11394 run_test 101j "A complete read block should be submitted when no RA"
11395
11396 test_101k()
11397 {
11398         local file=$DIR/$tfile
11399
11400         check_set_fallocate_or_skip
11401
11402         $LCTL set_param -n llite.*.read_ahead_stats=0
11403         fallocate -l 16K $file || error "failed to fallocate $file"
11404         cancel_lru_locks osc
11405         $MULTIOP $file or1048576c
11406         $LCTL get_param llite.*.read_ahead_stats
11407 }
11408 run_test 101k "read ahead for small file"
11409
11410 setup_test102() {
11411         test_mkdir $DIR/$tdir
11412         chown $RUNAS_ID $DIR/$tdir
11413         STRIPE_SIZE=65536
11414         STRIPE_OFFSET=1
11415         STRIPE_COUNT=$OSTCOUNT
11416         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11417
11418         trap cleanup_test102 EXIT
11419         cd $DIR
11420         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11421         cd $DIR/$tdir
11422         for num in 1 2 3 4; do
11423                 for count in $(seq 1 $STRIPE_COUNT); do
11424                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11425                                 local size=`expr $STRIPE_SIZE \* $num`
11426                                 local file=file"$num-$idx-$count"
11427                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11428                         done
11429                 done
11430         done
11431
11432         cd $DIR
11433         $1 tar cf $TMP/f102.tar $tdir --xattrs
11434 }
11435
11436 cleanup_test102() {
11437         trap 0
11438         rm -f $TMP/f102.tar
11439         rm -rf $DIR/d0.sanity/d102
11440 }
11441
11442 test_102a() {
11443         [ "$UID" != 0 ] && skip "must run as root"
11444         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11445                 skip_env "must have user_xattr"
11446
11447         [ -z "$(which setfattr 2>/dev/null)" ] &&
11448                 skip_env "could not find setfattr"
11449
11450         local testfile=$DIR/$tfile
11451
11452         touch $testfile
11453         echo "set/get xattr..."
11454         setfattr -n trusted.name1 -v value1 $testfile ||
11455                 error "setfattr -n trusted.name1=value1 $testfile failed"
11456         getfattr -n trusted.name1 $testfile 2> /dev/null |
11457           grep "trusted.name1=.value1" ||
11458                 error "$testfile missing trusted.name1=value1"
11459
11460         setfattr -n user.author1 -v author1 $testfile ||
11461                 error "setfattr -n user.author1=author1 $testfile failed"
11462         getfattr -n user.author1 $testfile 2> /dev/null |
11463           grep "user.author1=.author1" ||
11464                 error "$testfile missing trusted.author1=author1"
11465
11466         echo "listxattr..."
11467         setfattr -n trusted.name2 -v value2 $testfile ||
11468                 error "$testfile unable to set trusted.name2"
11469         setfattr -n trusted.name3 -v value3 $testfile ||
11470                 error "$testfile unable to set trusted.name3"
11471         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11472             grep "trusted.name" | wc -l) -eq 3 ] ||
11473                 error "$testfile missing 3 trusted.name xattrs"
11474
11475         setfattr -n user.author2 -v author2 $testfile ||
11476                 error "$testfile unable to set user.author2"
11477         setfattr -n user.author3 -v author3 $testfile ||
11478                 error "$testfile unable to set user.author3"
11479         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11480             grep "user.author" | wc -l) -eq 3 ] ||
11481                 error "$testfile missing 3 user.author xattrs"
11482
11483         echo "remove xattr..."
11484         setfattr -x trusted.name1 $testfile ||
11485                 error "$testfile error deleting trusted.name1"
11486         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11487                 error "$testfile did not delete trusted.name1 xattr"
11488
11489         setfattr -x user.author1 $testfile ||
11490                 error "$testfile error deleting user.author1"
11491         echo "set lustre special xattr ..."
11492         $LFS setstripe -c1 $testfile
11493         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11494                 awk -F "=" '/trusted.lov/ { print $2 }' )
11495         setfattr -n "trusted.lov" -v $lovea $testfile ||
11496                 error "$testfile doesn't ignore setting trusted.lov again"
11497         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11498                 error "$testfile allow setting invalid trusted.lov"
11499         rm -f $testfile
11500 }
11501 run_test 102a "user xattr test =================================="
11502
11503 check_102b_layout() {
11504         local layout="$*"
11505         local testfile=$DIR/$tfile
11506
11507         echo "test layout '$layout'"
11508         $LFS setstripe $layout $testfile || error "setstripe failed"
11509         $LFS getstripe -y $testfile
11510
11511         echo "get/set/list trusted.lov xattr ..." # b=10930
11512         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11513         [[ "$value" =~ "trusted.lov" ]] ||
11514                 error "can't get trusted.lov from $testfile"
11515         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11516                 error "getstripe failed"
11517
11518         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11519
11520         value=$(cut -d= -f2 <<<$value)
11521         # LU-13168: truncated xattr should fail if short lov_user_md header
11522         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11523                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11524         for len in $lens; do
11525                 echo "setfattr $len $testfile.2"
11526                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11527                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11528         done
11529         local stripe_size=$($LFS getstripe -S $testfile.2)
11530         local stripe_count=$($LFS getstripe -c $testfile.2)
11531         [[ $stripe_size -eq 65536 ]] ||
11532                 error "stripe size $stripe_size != 65536"
11533         [[ $stripe_count -eq $stripe_count_orig ]] ||
11534                 error "stripe count $stripe_count != $stripe_count_orig"
11535         rm $testfile $testfile.2
11536 }
11537
11538 test_102b() {
11539         [ -z "$(which setfattr 2>/dev/null)" ] &&
11540                 skip_env "could not find setfattr"
11541         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11542
11543         # check plain layout
11544         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11545
11546         # and also check composite layout
11547         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11548
11549 }
11550 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11551
11552 test_102c() {
11553         [ -z "$(which setfattr 2>/dev/null)" ] &&
11554                 skip_env "could not find setfattr"
11555         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11556
11557         # b10930: get/set/list lustre.lov xattr
11558         echo "get/set/list lustre.lov xattr ..."
11559         test_mkdir $DIR/$tdir
11560         chown $RUNAS_ID $DIR/$tdir
11561         local testfile=$DIR/$tdir/$tfile
11562         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11563                 error "setstripe failed"
11564         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11565                 error "getstripe failed"
11566         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11567         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11568
11569         local testfile2=${testfile}2
11570         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11571                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11572
11573         $RUNAS $MCREATE $testfile2
11574         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11575         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11576         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11577         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11578         [ $stripe_count -eq $STRIPECOUNT ] ||
11579                 error "stripe count $stripe_count != $STRIPECOUNT"
11580 }
11581 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11582
11583 compare_stripe_info1() {
11584         local stripe_index_all_zero=true
11585
11586         for num in 1 2 3 4; do
11587                 for count in $(seq 1 $STRIPE_COUNT); do
11588                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11589                                 local size=$((STRIPE_SIZE * num))
11590                                 local file=file"$num-$offset-$count"
11591                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11592                                 [[ $stripe_size -ne $size ]] &&
11593                                     error "$file: size $stripe_size != $size"
11594                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11595                                 # allow fewer stripes to be created, ORI-601
11596                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11597                                     error "$file: count $stripe_count != $count"
11598                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11599                                 [[ $stripe_index -ne 0 ]] &&
11600                                         stripe_index_all_zero=false
11601                         done
11602                 done
11603         done
11604         $stripe_index_all_zero &&
11605                 error "all files are being extracted starting from OST index 0"
11606         return 0
11607 }
11608
11609 have_xattrs_include() {
11610         tar --help | grep -q xattrs-include &&
11611                 echo --xattrs-include="lustre.*"
11612 }
11613
11614 test_102d() {
11615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11617
11618         XINC=$(have_xattrs_include)
11619         setup_test102
11620         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11621         cd $DIR/$tdir/$tdir
11622         compare_stripe_info1
11623 }
11624 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11625
11626 test_102f() {
11627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11628         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11629
11630         XINC=$(have_xattrs_include)
11631         setup_test102
11632         test_mkdir $DIR/$tdir.restore
11633         cd $DIR
11634         tar cf - --xattrs $tdir | tar xf - \
11635                 -C $DIR/$tdir.restore --xattrs $XINC
11636         cd $DIR/$tdir.restore/$tdir
11637         compare_stripe_info1
11638 }
11639 run_test 102f "tar copy files, not keep osts"
11640
11641 grow_xattr() {
11642         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11643                 skip "must have user_xattr"
11644         [ -z "$(which setfattr 2>/dev/null)" ] &&
11645                 skip_env "could not find setfattr"
11646         [ -z "$(which getfattr 2>/dev/null)" ] &&
11647                 skip_env "could not find getfattr"
11648
11649         local xsize=${1:-1024}  # in bytes
11650         local file=$DIR/$tfile
11651         local value="$(generate_string $xsize)"
11652         local xbig=trusted.big
11653         local toobig=$2
11654
11655         touch $file
11656         log "save $xbig on $file"
11657         if [ -z "$toobig" ]
11658         then
11659                 setfattr -n $xbig -v $value $file ||
11660                         error "saving $xbig on $file failed"
11661         else
11662                 setfattr -n $xbig -v $value $file &&
11663                         error "saving $xbig on $file succeeded"
11664                 return 0
11665         fi
11666
11667         local orig=$(get_xattr_value $xbig $file)
11668         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11669
11670         local xsml=trusted.sml
11671         log "save $xsml on $file"
11672         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11673
11674         local new=$(get_xattr_value $xbig $file)
11675         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11676
11677         log "grow $xsml on $file"
11678         setfattr -n $xsml -v "$value" $file ||
11679                 error "growing $xsml on $file failed"
11680
11681         new=$(get_xattr_value $xbig $file)
11682         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11683         log "$xbig still valid after growing $xsml"
11684
11685         rm -f $file
11686 }
11687
11688 test_102h() { # bug 15777
11689         grow_xattr 1024
11690 }
11691 run_test 102h "grow xattr from inside inode to external block"
11692
11693 test_102ha() {
11694         large_xattr_enabled || skip_env "ea_inode feature disabled"
11695
11696         echo "setting xattr of max xattr size: $(max_xattr_size)"
11697         grow_xattr $(max_xattr_size)
11698
11699         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11700         echo "This should fail:"
11701         grow_xattr $(($(max_xattr_size) + 10)) 1
11702 }
11703 run_test 102ha "grow xattr from inside inode to external inode"
11704
11705 test_102i() { # bug 17038
11706         [ -z "$(which getfattr 2>/dev/null)" ] &&
11707                 skip "could not find getfattr"
11708
11709         touch $DIR/$tfile
11710         ln -s $DIR/$tfile $DIR/${tfile}link
11711         getfattr -n trusted.lov $DIR/$tfile ||
11712                 error "lgetxattr on $DIR/$tfile failed"
11713         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11714                 grep -i "no such attr" ||
11715                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11716         rm -f $DIR/$tfile $DIR/${tfile}link
11717 }
11718 run_test 102i "lgetxattr test on symbolic link ============"
11719
11720 test_102j() {
11721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11722         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11723
11724         XINC=$(have_xattrs_include)
11725         setup_test102 "$RUNAS"
11726         chown $RUNAS_ID $DIR/$tdir
11727         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11728         cd $DIR/$tdir/$tdir
11729         compare_stripe_info1 "$RUNAS"
11730 }
11731 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11732
11733 test_102k() {
11734         [ -z "$(which setfattr 2>/dev/null)" ] &&
11735                 skip "could not find setfattr"
11736
11737         touch $DIR/$tfile
11738         # b22187 just check that does not crash for regular file.
11739         setfattr -n trusted.lov $DIR/$tfile
11740         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11741         local test_kdir=$DIR/$tdir
11742         test_mkdir $test_kdir
11743         local default_size=$($LFS getstripe -S $test_kdir)
11744         local default_count=$($LFS getstripe -c $test_kdir)
11745         local default_offset=$($LFS getstripe -i $test_kdir)
11746         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11747                 error 'dir setstripe failed'
11748         setfattr -n trusted.lov $test_kdir
11749         local stripe_size=$($LFS getstripe -S $test_kdir)
11750         local stripe_count=$($LFS getstripe -c $test_kdir)
11751         local stripe_offset=$($LFS getstripe -i $test_kdir)
11752         [ $stripe_size -eq $default_size ] ||
11753                 error "stripe size $stripe_size != $default_size"
11754         [ $stripe_count -eq $default_count ] ||
11755                 error "stripe count $stripe_count != $default_count"
11756         [ $stripe_offset -eq $default_offset ] ||
11757                 error "stripe offset $stripe_offset != $default_offset"
11758         rm -rf $DIR/$tfile $test_kdir
11759 }
11760 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11761
11762 test_102l() {
11763         [ -z "$(which getfattr 2>/dev/null)" ] &&
11764                 skip "could not find getfattr"
11765
11766         # LU-532 trusted. xattr is invisible to non-root
11767         local testfile=$DIR/$tfile
11768
11769         touch $testfile
11770
11771         echo "listxattr as user..."
11772         chown $RUNAS_ID $testfile
11773         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11774             grep -q "trusted" &&
11775                 error "$testfile trusted xattrs are user visible"
11776
11777         return 0;
11778 }
11779 run_test 102l "listxattr size test =================================="
11780
11781 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11782         local path=$DIR/$tfile
11783         touch $path
11784
11785         listxattr_size_check $path || error "listattr_size_check $path failed"
11786 }
11787 run_test 102m "Ensure listxattr fails on small bufffer ========"
11788
11789 cleanup_test102
11790
11791 getxattr() { # getxattr path name
11792         # Return the base64 encoding of the value of xattr name on path.
11793         local path=$1
11794         local name=$2
11795
11796         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11797         # file: $path
11798         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11799         #
11800         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11801
11802         getfattr --absolute-names --encoding=base64 --name=$name $path |
11803                 awk -F= -v name=$name '$1 == name {
11804                         print substr($0, index($0, "=") + 1);
11805         }'
11806 }
11807
11808 test_102n() { # LU-4101 mdt: protect internal xattrs
11809         [ -z "$(which setfattr 2>/dev/null)" ] &&
11810                 skip "could not find setfattr"
11811         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11812         then
11813                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11814         fi
11815
11816         local file0=$DIR/$tfile.0
11817         local file1=$DIR/$tfile.1
11818         local xattr0=$TMP/$tfile.0
11819         local xattr1=$TMP/$tfile.1
11820         local namelist="lov lma lmv link fid version som hsm"
11821         local name
11822         local value
11823
11824         rm -rf $file0 $file1 $xattr0 $xattr1
11825         touch $file0 $file1
11826
11827         # Get 'before' xattrs of $file1.
11828         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11829
11830         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11831                 namelist+=" lfsck_namespace"
11832         for name in $namelist; do
11833                 # Try to copy xattr from $file0 to $file1.
11834                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11835
11836                 setfattr --name=trusted.$name --value="$value" $file1 ||
11837                         error "setxattr 'trusted.$name' failed"
11838
11839                 # Try to set a garbage xattr.
11840                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11841
11842                 if [[ x$name == "xlov" ]]; then
11843                         setfattr --name=trusted.lov --value="$value" $file1 &&
11844                         error "setxattr invalid 'trusted.lov' success"
11845                 else
11846                         setfattr --name=trusted.$name --value="$value" $file1 ||
11847                                 error "setxattr invalid 'trusted.$name' failed"
11848                 fi
11849
11850                 # Try to remove the xattr from $file1. We don't care if this
11851                 # appears to succeed or fail, we just don't want there to be
11852                 # any changes or crashes.
11853                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11854         done
11855
11856         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11857         then
11858                 name="lfsck_ns"
11859                 # Try to copy xattr from $file0 to $file1.
11860                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11861
11862                 setfattr --name=trusted.$name --value="$value" $file1 ||
11863                         error "setxattr 'trusted.$name' failed"
11864
11865                 # Try to set a garbage xattr.
11866                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11867
11868                 setfattr --name=trusted.$name --value="$value" $file1 ||
11869                         error "setxattr 'trusted.$name' failed"
11870
11871                 # Try to remove the xattr from $file1. We don't care if this
11872                 # appears to succeed or fail, we just don't want there to be
11873                 # any changes or crashes.
11874                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11875         fi
11876
11877         # Get 'after' xattrs of file1.
11878         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11879
11880         if ! diff $xattr0 $xattr1; then
11881                 error "before and after xattrs of '$file1' differ"
11882         fi
11883
11884         rm -rf $file0 $file1 $xattr0 $xattr1
11885
11886         return 0
11887 }
11888 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11889
11890 test_102p() { # LU-4703 setxattr did not check ownership
11891         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11892                 skip "MDS needs to be at least 2.5.56"
11893
11894         local testfile=$DIR/$tfile
11895
11896         touch $testfile
11897
11898         echo "setfacl as user..."
11899         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11900         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11901
11902         echo "setfattr as user..."
11903         setfacl -m "u:$RUNAS_ID:---" $testfile
11904         $RUNAS setfattr -x system.posix_acl_access $testfile
11905         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11906 }
11907 run_test 102p "check setxattr(2) correctly fails without permission"
11908
11909 test_102q() {
11910         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11911                 skip "MDS needs to be at least 2.6.92"
11912
11913         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11914 }
11915 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11916
11917 test_102r() {
11918         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11919                 skip "MDS needs to be at least 2.6.93"
11920
11921         touch $DIR/$tfile || error "touch"
11922         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11923         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11924         rm $DIR/$tfile || error "rm"
11925
11926         #normal directory
11927         mkdir -p $DIR/$tdir || error "mkdir"
11928         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11929         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11930         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11931                 error "$testfile error deleting user.author1"
11932         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11933                 grep "user.$(basename $tdir)" &&
11934                 error "$tdir did not delete user.$(basename $tdir)"
11935         rmdir $DIR/$tdir || error "rmdir"
11936
11937         #striped directory
11938         test_mkdir $DIR/$tdir
11939         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11940         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11941         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11942                 error "$testfile error deleting user.author1"
11943         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11944                 grep "user.$(basename $tdir)" &&
11945                 error "$tdir did not delete user.$(basename $tdir)"
11946         rmdir $DIR/$tdir || error "rm striped dir"
11947 }
11948 run_test 102r "set EAs with empty values"
11949
11950 test_102s() {
11951         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11952                 skip "MDS needs to be at least 2.11.52"
11953
11954         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11955
11956         save_lustre_params client "llite.*.xattr_cache" > $save
11957
11958         for cache in 0 1; do
11959                 lctl set_param llite.*.xattr_cache=$cache
11960
11961                 rm -f $DIR/$tfile
11962                 touch $DIR/$tfile || error "touch"
11963                 for prefix in lustre security system trusted user; do
11964                         # Note getxattr() may fail with 'Operation not
11965                         # supported' or 'No such attribute' depending
11966                         # on prefix and cache.
11967                         getfattr -n $prefix.n102s $DIR/$tfile &&
11968                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11969                 done
11970         done
11971
11972         restore_lustre_params < $save
11973 }
11974 run_test 102s "getting nonexistent xattrs should fail"
11975
11976 test_102t() {
11977         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11978                 skip "MDS needs to be at least 2.11.52"
11979
11980         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11981
11982         save_lustre_params client "llite.*.xattr_cache" > $save
11983
11984         for cache in 0 1; do
11985                 lctl set_param llite.*.xattr_cache=$cache
11986
11987                 for buf_size in 0 256; do
11988                         rm -f $DIR/$tfile
11989                         touch $DIR/$tfile || error "touch"
11990                         setfattr -n user.multiop $DIR/$tfile
11991                         $MULTIOP $DIR/$tfile oa$buf_size ||
11992                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11993                 done
11994         done
11995
11996         restore_lustre_params < $save
11997 }
11998 run_test 102t "zero length xattr values handled correctly"
11999
12000 run_acl_subtest()
12001 {
12002         local test=$LUSTRE/tests/acl/$1.test
12003         local tmp=$(mktemp -t $1-XXXXXX).test
12004         local bin=$2
12005         local dmn=$3
12006         local grp=$4
12007         local nbd=$5
12008         export LANG=C
12009
12010
12011         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12012         local sedgroups="-e s/:users/:$grp/g"
12013         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12014
12015         sed $sedusers $sedgroups < $test > $tmp
12016         stack_trap "rm -f $tmp"
12017         [[ -s $tmp ]] || error "sed failed to create test script"
12018
12019         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12020         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12021 }
12022
12023 test_103a() {
12024         [ "$UID" != 0 ] && skip "must run as root"
12025         $GSS && skip_env "could not run under gss"
12026         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12027                 skip_env "must have acl enabled"
12028         which setfacl || skip_env "could not find setfacl"
12029         remote_mds_nodsh && skip "remote MDS with nodsh"
12030
12031         ACLBIN=${ACLBIN:-"bin"}
12032         ACLDMN=${ACLDMN:-"daemon"}
12033         ACLGRP=${ACLGRP:-"users"}
12034         ACLNBD=${ACLNBD:-"nobody"}
12035
12036         if ! id $ACLBIN ||
12037            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12038                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12039                 ACLBIN=$USER0
12040                 if ! id $ACLBIN ; then
12041                         cat /etc/passwd
12042                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12043                 fi
12044         fi
12045         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12046            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12047                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12048                 ACLDMN=$USER1
12049                 if ! id $ACLDMN ; then
12050                         cat /etc/passwd
12051                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12052                 fi
12053         fi
12054         if ! getent group $ACLGRP; then
12055                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12056                 ACLGRP="$TSTUSR"
12057                 if ! getent group $ACLGRP; then
12058                         echo "cannot find group '$ACLGRP', adding it"
12059                         cat /etc/group
12060                         add_group 60000 $ACLGRP
12061                 fi
12062         fi
12063
12064         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12065         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12066         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12067
12068         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12069                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12070                 ACLGRP="$TSTUSR"
12071                 if ! getent group $ACLGRP; then
12072                         echo "cannot find group '$ACLGRP', adding it"
12073                         cat /etc/group
12074                         add_group 60000 $ACLGRP
12075                 fi
12076                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12077                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12078                         cat /etc/group
12079                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12080                 fi
12081         fi
12082
12083         gpasswd -a $ACLDMN $ACLBIN ||
12084                 error "setting client group failed"             # LU-5641
12085         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12086                 error "setting MDS group failed"                # LU-5641
12087
12088         declare -a identity_old
12089
12090         for num in $(seq $MDSCOUNT); do
12091                 switch_identity $num true || identity_old[$num]=$?
12092         done
12093
12094         SAVE_UMASK=$(umask)
12095         umask 0022
12096         mkdir -p $DIR/$tdir
12097         cd $DIR/$tdir
12098
12099         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12100         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12101         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12102         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12103         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12104         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12105         if ! id -u $ACLNBD ||
12106            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12107                 ACLNBD="nfsnobody"
12108                 if ! id -u $ACLNBD; then
12109                         ACLNBD=""
12110                 fi
12111         fi
12112         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12113                 add_group $(id -u $ACLNBD) $ACLNBD
12114                 if ! getent group $ACLNBD; then
12115                         ACLNBD=""
12116                 fi
12117         fi
12118         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12119            [[ -n "$ACLNBD" ]] && which setfattr; then
12120                 run_acl_subtest permissions_xattr \
12121                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12122         elif [[ -z "$ACLNBD" ]]; then
12123                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12124         else
12125                 echo "skip 'permission_xattr' test - missing setfattr command"
12126         fi
12127         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12128
12129         # inheritance test got from HP
12130         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12131         chmod +x make-tree || error "chmod +x failed"
12132         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12133         rm -f make-tree
12134
12135         echo "LU-974 ignore umask when acl is enabled..."
12136         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12137         if [ $MDSCOUNT -ge 2 ]; then
12138                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12139         fi
12140
12141         echo "LU-2561 newly created file is same size as directory..."
12142         if [ "$mds1_FSTYPE" != "zfs" ]; then
12143                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12144         else
12145                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12146         fi
12147
12148         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12149
12150         cd $SAVE_PWD
12151         umask $SAVE_UMASK
12152
12153         for num in $(seq $MDSCOUNT); do
12154                 if [ "${identity_old[$num]}" = 1 ]; then
12155                         switch_identity $num false || identity_old[$num]=$?
12156                 fi
12157         done
12158 }
12159 run_test 103a "acl test"
12160
12161 test_103b() {
12162         declare -a pids
12163         local U
12164
12165         for U in {0..511}; do
12166                 {
12167                 local O=$(printf "%04o" $U)
12168
12169                 umask $(printf "%04o" $((511 ^ $O)))
12170                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12171                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12172
12173                 (( $S == ($O & 0666) )) ||
12174                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12175
12176                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12177                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12178                 (( $S == ($O & 0666) )) ||
12179                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12180
12181                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12182                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12183                 (( $S == ($O & 0666) )) ||
12184                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12185                 rm -f $DIR/$tfile.[smp]$0
12186                 } &
12187                 local pid=$!
12188
12189                 # limit the concurrently running threads to 64. LU-11878
12190                 local idx=$((U % 64))
12191                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12192                 pids[idx]=$pid
12193         done
12194         wait
12195 }
12196 run_test 103b "umask lfs setstripe"
12197
12198 test_103c() {
12199         mkdir -p $DIR/$tdir
12200         cp -rp $DIR/$tdir $DIR/$tdir.bak
12201
12202         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12203                 error "$DIR/$tdir shouldn't contain default ACL"
12204         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12205                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12206         true
12207 }
12208 run_test 103c "'cp -rp' won't set empty acl"
12209
12210 test_103e() {
12211         local numacl
12212         local fileacl
12213         local saved_debug=$($LCTL get_param -n debug)
12214
12215         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12216                 skip "MDS needs to be at least 2.14.52"
12217
12218         large_xattr_enabled || skip_env "ea_inode feature disabled"
12219
12220         mkdir -p $DIR/$tdir
12221         # add big LOV EA to cause reply buffer overflow earlier
12222         $LFS setstripe -C 1000 $DIR/$tdir
12223         lctl set_param mdc.*-mdc*.stats=clear
12224
12225         $LCTL set_param debug=0
12226         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12227         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12228
12229         # add a large number of default ACLs (expect 8000+ for 2.13+)
12230         for U in {2..7000}; do
12231                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12232                         error "Able to add just $U default ACLs"
12233         done
12234         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12235         echo "$numacl default ACLs created"
12236
12237         stat $DIR/$tdir || error "Cannot stat directory"
12238         # check file creation
12239         touch $DIR/$tdir/$tfile ||
12240                 error "failed to create $tfile with $numacl default ACLs"
12241         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12242         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12243         echo "$fileacl ACLs were inherited"
12244         (( $fileacl == $numacl )) ||
12245                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12246         # check that new ACLs creation adds new ACLs to inherited ACLs
12247         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12248                 error "Cannot set new ACL"
12249         numacl=$((numacl + 1))
12250         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12251         (( $fileacl == $numacl )) ||
12252                 error "failed to add new ACL: $fileacl != $numacl as expected"
12253         # adds more ACLs to a file to reach their maximum at 8000+
12254         numacl=0
12255         for U in {20000..25000}; do
12256                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12257                 numacl=$((numacl + 1))
12258         done
12259         echo "Added $numacl more ACLs to the file"
12260         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12261         echo "Total $fileacl ACLs in file"
12262         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12263         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12264         rmdir $DIR/$tdir || error "Cannot remove directory"
12265 }
12266 run_test 103e "inheritance of big amount of default ACLs"
12267
12268 test_103f() {
12269         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12270                 skip "MDS needs to be at least 2.14.51"
12271
12272         large_xattr_enabled || skip_env "ea_inode feature disabled"
12273
12274         # enable changelog to consume more internal MDD buffers
12275         changelog_register
12276
12277         mkdir -p $DIR/$tdir
12278         # add big LOV EA
12279         $LFS setstripe -C 1000 $DIR/$tdir
12280         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12281         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12282         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12283         rmdir $DIR/$tdir || error "Cannot remove directory"
12284 }
12285 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12286
12287 test_104a() {
12288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12289
12290         touch $DIR/$tfile
12291         lfs df || error "lfs df failed"
12292         lfs df -ih || error "lfs df -ih failed"
12293         lfs df -h $DIR || error "lfs df -h $DIR failed"
12294         lfs df -i $DIR || error "lfs df -i $DIR failed"
12295         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12296         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12297
12298         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12299         lctl --device %$OSC deactivate
12300         lfs df || error "lfs df with deactivated OSC failed"
12301         lctl --device %$OSC activate
12302         # wait the osc back to normal
12303         wait_osc_import_ready client ost
12304
12305         lfs df || error "lfs df with reactivated OSC failed"
12306         rm -f $DIR/$tfile
12307 }
12308 run_test 104a "lfs df [-ih] [path] test ========================="
12309
12310 test_104b() {
12311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12312         [ $RUNAS_ID -eq $UID ] &&
12313                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12314
12315         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12316                         grep "Permission denied" | wc -l)))
12317         if [ $denied_cnt -ne 0 ]; then
12318                 error "lfs check servers test failed"
12319         fi
12320 }
12321 run_test 104b "$RUNAS lfs check servers test ===================="
12322
12323 #
12324 # Verify $1 is within range of $2.
12325 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12326 # $1 is <= 2% of $2. Else Fail.
12327 #
12328 value_in_range() {
12329         # Strip all units (M, G, T)
12330         actual=$(echo $1 | tr -d A-Z)
12331         expect=$(echo $2 | tr -d A-Z)
12332
12333         expect_lo=$(($expect * 98 / 100)) # 2% below
12334         expect_hi=$(($expect * 102 / 100)) # 2% above
12335
12336         # permit 2% drift above and below
12337         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12338 }
12339
12340 test_104c() {
12341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12342         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12343
12344         local ost_param="osd-zfs.$FSNAME-OST0000."
12345         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12346         local ofacets=$(get_facets OST)
12347         local mfacets=$(get_facets MDS)
12348         local saved_ost_blocks=
12349         local saved_mdt_blocks=
12350
12351         echo "Before recordsize change"
12352         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12353         df=($(df -h | grep "$MOUNT"$))
12354
12355         # For checking.
12356         echo "lfs output : ${lfs_df[*]}"
12357         echo "df  output : ${df[*]}"
12358
12359         for facet in ${ofacets//,/ }; do
12360                 if [ -z $saved_ost_blocks ]; then
12361                         saved_ost_blocks=$(do_facet $facet \
12362                                 lctl get_param -n $ost_param.blocksize)
12363                         echo "OST Blocksize: $saved_ost_blocks"
12364                 fi
12365                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12366                 do_facet $facet zfs set recordsize=32768 $ost
12367         done
12368
12369         # BS too small. Sufficient for functional testing.
12370         for facet in ${mfacets//,/ }; do
12371                 if [ -z $saved_mdt_blocks ]; then
12372                         saved_mdt_blocks=$(do_facet $facet \
12373                                 lctl get_param -n $mdt_param.blocksize)
12374                         echo "MDT Blocksize: $saved_mdt_blocks"
12375                 fi
12376                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12377                 do_facet $facet zfs set recordsize=32768 $mdt
12378         done
12379
12380         # Give new values chance to reflect change
12381         sleep 2
12382
12383         echo "After recordsize change"
12384         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12385         df_after=($(df -h | grep "$MOUNT"$))
12386
12387         # For checking.
12388         echo "lfs output : ${lfs_df_after[*]}"
12389         echo "df  output : ${df_after[*]}"
12390
12391         # Verify lfs df
12392         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12393                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12394         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12395                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12396         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12397                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12398
12399         # Verify df
12400         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12401                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12402         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12403                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12404         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12405                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12406
12407         # Restore MDT recordize back to original
12408         for facet in ${mfacets//,/ }; do
12409                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12410                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12411         done
12412
12413         # Restore OST recordize back to original
12414         for facet in ${ofacets//,/ }; do
12415                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12416                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12417         done
12418
12419         return 0
12420 }
12421 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12422
12423 test_104d() {
12424         (( $RUNAS_ID != $UID )) ||
12425                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12426
12427         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12428                 skip "lustre version doesn't support lctl dl with non-root"
12429
12430         # debugfs only allows root users to access files, so the
12431         # previous move of the "devices" file to debugfs broke
12432         # "lctl dl" for non-root users. The LU-9680 Netlink
12433         # interface again allows non-root users to list devices.
12434         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12435                 error "lctl dl doesn't work for non root"
12436
12437         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12438         [ "$ost_count" -eq $OSTCOUNT ]  ||
12439                 error "lctl dl reports wrong number of OST devices"
12440
12441         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12442         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12443                 error "lctl dl reports wrong number of MDT devices"
12444 }
12445 run_test 104d "$RUNAS lctl dl test"
12446
12447 test_105a() {
12448         # doesn't work on 2.4 kernels
12449         touch $DIR/$tfile
12450         if $(flock_is_enabled); then
12451                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12452         else
12453                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12454         fi
12455         rm -f $DIR/$tfile
12456 }
12457 run_test 105a "flock when mounted without -o flock test ========"
12458
12459 test_105b() {
12460         touch $DIR/$tfile
12461         if $(flock_is_enabled); then
12462                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12463         else
12464                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12465         fi
12466         rm -f $DIR/$tfile
12467 }
12468 run_test 105b "fcntl when mounted without -o flock test ========"
12469
12470 test_105c() {
12471         touch $DIR/$tfile
12472         if $(flock_is_enabled); then
12473                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12474         else
12475                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12476         fi
12477         rm -f $DIR/$tfile
12478 }
12479 run_test 105c "lockf when mounted without -o flock test"
12480
12481 test_105d() { # bug 15924
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483
12484         test_mkdir $DIR/$tdir
12485         flock_is_enabled || skip_env "mount w/o flock enabled"
12486         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12487         $LCTL set_param fail_loc=0x80000315
12488         flocks_test 2 $DIR/$tdir
12489 }
12490 run_test 105d "flock race (should not freeze) ========"
12491
12492 test_105e() { # bug 22660 && 22040
12493         flock_is_enabled || skip_env "mount w/o flock enabled"
12494
12495         touch $DIR/$tfile
12496         flocks_test 3 $DIR/$tfile
12497 }
12498 run_test 105e "Two conflicting flocks from same process"
12499
12500 test_106() { #bug 10921
12501         test_mkdir $DIR/$tdir
12502         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12503         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12504 }
12505 run_test 106 "attempt exec of dir followed by chown of that dir"
12506
12507 test_107() {
12508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12509
12510         CDIR=`pwd`
12511         local file=core
12512
12513         cd $DIR
12514         rm -f $file
12515
12516         local save_pattern=$(sysctl -n kernel.core_pattern)
12517         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12518         sysctl -w kernel.core_pattern=$file
12519         sysctl -w kernel.core_uses_pid=0
12520
12521         ulimit -c unlimited
12522         sleep 60 &
12523         SLEEPPID=$!
12524
12525         sleep 1
12526
12527         kill -s 11 $SLEEPPID
12528         wait $SLEEPPID
12529         if [ -e $file ]; then
12530                 size=`stat -c%s $file`
12531                 [ $size -eq 0 ] && error "Fail to create core file $file"
12532         else
12533                 error "Fail to create core file $file"
12534         fi
12535         rm -f $file
12536         sysctl -w kernel.core_pattern=$save_pattern
12537         sysctl -w kernel.core_uses_pid=$save_uses_pid
12538         cd $CDIR
12539 }
12540 run_test 107 "Coredump on SIG"
12541
12542 test_110() {
12543         test_mkdir $DIR/$tdir
12544         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12545         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12546                 error "mkdir with 256 char should fail, but did not"
12547         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12548                 error "create with 255 char failed"
12549         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12550                 error "create with 256 char should fail, but did not"
12551
12552         ls -l $DIR/$tdir
12553         rm -rf $DIR/$tdir
12554 }
12555 run_test 110 "filename length checking"
12556
12557 test_116a() { # was previously test_116()
12558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12559         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12560         remote_mds_nodsh && skip "remote MDS with nodsh"
12561
12562         echo -n "Free space priority "
12563         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12564                 head -n1
12565         declare -a AVAIL
12566         free_min_max
12567
12568         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12569         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12570         stack_trap simple_cleanup_common
12571
12572         # Check if we need to generate uneven OSTs
12573         test_mkdir -p $DIR/$tdir/OST${MINI}
12574         local FILL=$((MINV / 4))
12575         local DIFF=$((MAXV - MINV))
12576         local DIFF2=$((DIFF * 100 / MINV))
12577
12578         local threshold=$(do_facet $SINGLEMDS \
12579                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12580         threshold=${threshold%%%}
12581         echo -n "Check for uneven OSTs: "
12582         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12583
12584         if [[ $DIFF2 -gt $threshold ]]; then
12585                 echo "ok"
12586                 echo "Don't need to fill OST$MINI"
12587         else
12588                 # generate uneven OSTs. Write 2% over the QOS threshold value
12589                 echo "no"
12590                 DIFF=$((threshold - DIFF2 + 2))
12591                 DIFF2=$((MINV * DIFF / 100))
12592                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12593                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12594                         error "setstripe failed"
12595                 DIFF=$((DIFF2 / 2048))
12596                 i=0
12597                 while [ $i -lt $DIFF ]; do
12598                         i=$((i + 1))
12599                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12600                                 bs=2M count=1 2>/dev/null
12601                         echo -n .
12602                 done
12603                 echo .
12604                 sync
12605                 sleep_maxage
12606                 free_min_max
12607         fi
12608
12609         DIFF=$((MAXV - MINV))
12610         DIFF2=$((DIFF * 100 / MINV))
12611         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12612         if [ $DIFF2 -gt $threshold ]; then
12613                 echo "ok"
12614         else
12615                 skip "QOS imbalance criteria not met"
12616         fi
12617
12618         MINI1=$MINI
12619         MINV1=$MINV
12620         MAXI1=$MAXI
12621         MAXV1=$MAXV
12622
12623         # now fill using QOS
12624         $LFS setstripe -c 1 $DIR/$tdir
12625         FILL=$((FILL / 200))
12626         if [ $FILL -gt 600 ]; then
12627                 FILL=600
12628         fi
12629         echo "writing $FILL files to QOS-assigned OSTs"
12630         i=0
12631         while [ $i -lt $FILL ]; do
12632                 i=$((i + 1))
12633                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12634                         count=1 2>/dev/null
12635                 echo -n .
12636         done
12637         echo "wrote $i 200k files"
12638         sync
12639         sleep_maxage
12640
12641         echo "Note: free space may not be updated, so measurements might be off"
12642         free_min_max
12643         DIFF2=$((MAXV - MINV))
12644         echo "free space delta: orig $DIFF final $DIFF2"
12645         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12646         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12647         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12648         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12649         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12650         if [[ $DIFF -gt 0 ]]; then
12651                 FILL=$((DIFF2 * 100 / DIFF - 100))
12652                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12653         fi
12654
12655         # Figure out which files were written where
12656         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12657                awk '/'$MINI1': / {print $2; exit}')
12658         echo $UUID
12659         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12660         echo "$MINC files created on smaller OST $MINI1"
12661         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12662                awk '/'$MAXI1': / {print $2; exit}')
12663         echo $UUID
12664         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12665         echo "$MAXC files created on larger OST $MAXI1"
12666         if [[ $MINC -gt 0 ]]; then
12667                 FILL=$((MAXC * 100 / MINC - 100))
12668                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12669         fi
12670         [[ $MAXC -gt $MINC ]] ||
12671                 error_ignore LU-9 "stripe QOS didn't balance free space"
12672 }
12673 run_test 116a "stripe QOS: free space balance ==================="
12674
12675 test_116b() { # LU-2093
12676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12677         remote_mds_nodsh && skip "remote MDS with nodsh"
12678
12679 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12680         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12681                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12682         [ -z "$old_rr" ] && skip "no QOS"
12683         do_facet $SINGLEMDS lctl set_param \
12684                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12685         mkdir -p $DIR/$tdir
12686         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12687         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12688         do_facet $SINGLEMDS lctl set_param fail_loc=0
12689         rm -rf $DIR/$tdir
12690         do_facet $SINGLEMDS lctl set_param \
12691                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12692 }
12693 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12694
12695 test_117() # bug 10891
12696 {
12697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12698
12699         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12700         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12701         lctl set_param fail_loc=0x21e
12702         > $DIR/$tfile || error "truncate failed"
12703         lctl set_param fail_loc=0
12704         echo "Truncate succeeded."
12705         rm -f $DIR/$tfile
12706 }
12707 run_test 117 "verify osd extend =========="
12708
12709 NO_SLOW_RESENDCOUNT=4
12710 export OLD_RESENDCOUNT=""
12711 set_resend_count () {
12712         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12713         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12714         lctl set_param -n $PROC_RESENDCOUNT $1
12715         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12716 }
12717
12718 # for reduce test_118* time (b=14842)
12719 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12720
12721 # Reset async IO behavior after error case
12722 reset_async() {
12723         FILE=$DIR/reset_async
12724
12725         # Ensure all OSCs are cleared
12726         $LFS setstripe -c -1 $FILE
12727         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12728         sync
12729         rm $FILE
12730 }
12731
12732 test_118a() #bug 11710
12733 {
12734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12735
12736         reset_async
12737
12738         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12739         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12740         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12741
12742         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12743                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12744                 return 1;
12745         fi
12746         rm -f $DIR/$tfile
12747 }
12748 run_test 118a "verify O_SYNC works =========="
12749
12750 test_118b()
12751 {
12752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12753         remote_ost_nodsh && skip "remote OST with nodsh"
12754
12755         reset_async
12756
12757         #define OBD_FAIL_SRV_ENOENT 0x217
12758         set_nodes_failloc "$(osts_nodes)" 0x217
12759         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12760         RC=$?
12761         set_nodes_failloc "$(osts_nodes)" 0
12762         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12763         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12764                     grep -c writeback)
12765
12766         if [[ $RC -eq 0 ]]; then
12767                 error "Must return error due to dropped pages, rc=$RC"
12768                 return 1;
12769         fi
12770
12771         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12772                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12773                 return 1;
12774         fi
12775
12776         echo "Dirty pages not leaked on ENOENT"
12777
12778         # Due to the above error the OSC will issue all RPCs syncronously
12779         # until a subsequent RPC completes successfully without error.
12780         $MULTIOP $DIR/$tfile Ow4096yc
12781         rm -f $DIR/$tfile
12782
12783         return 0
12784 }
12785 run_test 118b "Reclaim dirty pages on fatal error =========="
12786
12787 test_118c()
12788 {
12789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12790
12791         # for 118c, restore the original resend count, LU-1940
12792         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12793                                 set_resend_count $OLD_RESENDCOUNT
12794         remote_ost_nodsh && skip "remote OST with nodsh"
12795
12796         reset_async
12797
12798         #define OBD_FAIL_OST_EROFS               0x216
12799         set_nodes_failloc "$(osts_nodes)" 0x216
12800
12801         # multiop should block due to fsync until pages are written
12802         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12803         MULTIPID=$!
12804         sleep 1
12805
12806         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12807                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12808         fi
12809
12810         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12811                     grep -c writeback)
12812         if [[ $WRITEBACK -eq 0 ]]; then
12813                 error "No page in writeback, writeback=$WRITEBACK"
12814         fi
12815
12816         set_nodes_failloc "$(osts_nodes)" 0
12817         wait $MULTIPID
12818         RC=$?
12819         if [[ $RC -ne 0 ]]; then
12820                 error "Multiop fsync failed, rc=$RC"
12821         fi
12822
12823         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12824         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12825                     grep -c writeback)
12826         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12827                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12828         fi
12829
12830         rm -f $DIR/$tfile
12831         echo "Dirty pages flushed via fsync on EROFS"
12832         return 0
12833 }
12834 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12835
12836 # continue to use small resend count to reduce test_118* time (b=14842)
12837 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12838
12839 test_118d()
12840 {
12841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12842         remote_ost_nodsh && skip "remote OST with nodsh"
12843
12844         reset_async
12845
12846         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12847         set_nodes_failloc "$(osts_nodes)" 0x214
12848         # multiop should block due to fsync until pages are written
12849         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12850         MULTIPID=$!
12851         sleep 1
12852
12853         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12854                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12855         fi
12856
12857         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12858                     grep -c writeback)
12859         if [[ $WRITEBACK -eq 0 ]]; then
12860                 error "No page in writeback, writeback=$WRITEBACK"
12861         fi
12862
12863         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12864         set_nodes_failloc "$(osts_nodes)" 0
12865
12866         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12867         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12868                     grep -c writeback)
12869         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12870                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12871         fi
12872
12873         rm -f $DIR/$tfile
12874         echo "Dirty pages gaurenteed flushed via fsync"
12875         return 0
12876 }
12877 run_test 118d "Fsync validation inject a delay of the bulk =========="
12878
12879 test_118f() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881
12882         reset_async
12883
12884         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12885         lctl set_param fail_loc=0x8000040a
12886
12887         # Should simulate EINVAL error which is fatal
12888         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12889         RC=$?
12890         if [[ $RC -eq 0 ]]; then
12891                 error "Must return error due to dropped pages, rc=$RC"
12892         fi
12893
12894         lctl set_param fail_loc=0x0
12895
12896         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12897         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12898         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12899                     grep -c writeback)
12900         if [[ $LOCKED -ne 0 ]]; then
12901                 error "Locked pages remain in cache, locked=$LOCKED"
12902         fi
12903
12904         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12905                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12906         fi
12907
12908         rm -f $DIR/$tfile
12909         echo "No pages locked after fsync"
12910
12911         reset_async
12912         return 0
12913 }
12914 run_test 118f "Simulate unrecoverable OSC side error =========="
12915
12916 test_118g() {
12917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12918
12919         reset_async
12920
12921         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12922         lctl set_param fail_loc=0x406
12923
12924         # simulate local -ENOMEM
12925         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12926         RC=$?
12927
12928         lctl set_param fail_loc=0
12929         if [[ $RC -eq 0 ]]; then
12930                 error "Must return error due to dropped pages, rc=$RC"
12931         fi
12932
12933         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12934         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12935         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12936                         grep -c writeback)
12937         if [[ $LOCKED -ne 0 ]]; then
12938                 error "Locked pages remain in cache, locked=$LOCKED"
12939         fi
12940
12941         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12942                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12943         fi
12944
12945         rm -f $DIR/$tfile
12946         echo "No pages locked after fsync"
12947
12948         reset_async
12949         return 0
12950 }
12951 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12952
12953 test_118h() {
12954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12955         remote_ost_nodsh && skip "remote OST with nodsh"
12956
12957         reset_async
12958
12959         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12960         set_nodes_failloc "$(osts_nodes)" 0x20e
12961         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12962         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12963         RC=$?
12964
12965         set_nodes_failloc "$(osts_nodes)" 0
12966         if [[ $RC -eq 0 ]]; then
12967                 error "Must return error due to dropped pages, rc=$RC"
12968         fi
12969
12970         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12971         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12972         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12973                     grep -c writeback)
12974         if [[ $LOCKED -ne 0 ]]; then
12975                 error "Locked pages remain in cache, locked=$LOCKED"
12976         fi
12977
12978         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12979                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12980         fi
12981
12982         rm -f $DIR/$tfile
12983         echo "No pages locked after fsync"
12984
12985         return 0
12986 }
12987 run_test 118h "Verify timeout in handling recoverables errors  =========="
12988
12989 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12990
12991 test_118i() {
12992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12993         remote_ost_nodsh && skip "remote OST with nodsh"
12994
12995         reset_async
12996
12997         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12998         set_nodes_failloc "$(osts_nodes)" 0x20e
12999
13000         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13001         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13002         PID=$!
13003         sleep 5
13004         set_nodes_failloc "$(osts_nodes)" 0
13005
13006         wait $PID
13007         RC=$?
13008         if [[ $RC -ne 0 ]]; then
13009                 error "got error, but should be not, rc=$RC"
13010         fi
13011
13012         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13013         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13014         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13015         if [[ $LOCKED -ne 0 ]]; then
13016                 error "Locked pages remain in cache, locked=$LOCKED"
13017         fi
13018
13019         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13020                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13021         fi
13022
13023         rm -f $DIR/$tfile
13024         echo "No pages locked after fsync"
13025
13026         return 0
13027 }
13028 run_test 118i "Fix error before timeout in recoverable error  =========="
13029
13030 [ "$SLOW" = "no" ] && set_resend_count 4
13031
13032 test_118j() {
13033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13034         remote_ost_nodsh && skip "remote OST with nodsh"
13035
13036         reset_async
13037
13038         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13039         set_nodes_failloc "$(osts_nodes)" 0x220
13040
13041         # return -EIO from OST
13042         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13043         RC=$?
13044         set_nodes_failloc "$(osts_nodes)" 0x0
13045         if [[ $RC -eq 0 ]]; then
13046                 error "Must return error due to dropped pages, rc=$RC"
13047         fi
13048
13049         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13050         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13051         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13052         if [[ $LOCKED -ne 0 ]]; then
13053                 error "Locked pages remain in cache, locked=$LOCKED"
13054         fi
13055
13056         # in recoverable error on OST we want resend and stay until it finished
13057         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13058                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13059         fi
13060
13061         rm -f $DIR/$tfile
13062         echo "No pages locked after fsync"
13063
13064         return 0
13065 }
13066 run_test 118j "Simulate unrecoverable OST side error =========="
13067
13068 test_118k()
13069 {
13070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13071         remote_ost_nodsh && skip "remote OSTs with nodsh"
13072
13073         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13074         set_nodes_failloc "$(osts_nodes)" 0x20e
13075         test_mkdir $DIR/$tdir
13076
13077         for ((i=0;i<10;i++)); do
13078                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13079                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13080                 SLEEPPID=$!
13081                 sleep 0.500s
13082                 kill $SLEEPPID
13083                 wait $SLEEPPID
13084         done
13085
13086         set_nodes_failloc "$(osts_nodes)" 0
13087         rm -rf $DIR/$tdir
13088 }
13089 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13090
13091 test_118l() # LU-646
13092 {
13093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13094
13095         test_mkdir $DIR/$tdir
13096         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13097         rm -rf $DIR/$tdir
13098 }
13099 run_test 118l "fsync dir"
13100
13101 test_118m() # LU-3066
13102 {
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104
13105         test_mkdir $DIR/$tdir
13106         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13107         rm -rf $DIR/$tdir
13108 }
13109 run_test 118m "fdatasync dir ========="
13110
13111 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13112
13113 test_118n()
13114 {
13115         local begin
13116         local end
13117
13118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13119         remote_ost_nodsh && skip "remote OSTs with nodsh"
13120
13121         # Sleep to avoid a cached response.
13122         #define OBD_STATFS_CACHE_SECONDS 1
13123         sleep 2
13124
13125         # Inject a 10 second delay in the OST_STATFS handler.
13126         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13127         set_nodes_failloc "$(osts_nodes)" 0x242
13128
13129         begin=$SECONDS
13130         stat --file-system $MOUNT > /dev/null
13131         end=$SECONDS
13132
13133         set_nodes_failloc "$(osts_nodes)" 0
13134
13135         if ((end - begin > 20)); then
13136             error "statfs took $((end - begin)) seconds, expected 10"
13137         fi
13138 }
13139 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13140
13141 test_119a() # bug 11737
13142 {
13143         BSIZE=$((512 * 1024))
13144         directio write $DIR/$tfile 0 1 $BSIZE
13145         # We ask to read two blocks, which is more than a file size.
13146         # directio will indicate an error when requested and actual
13147         # sizes aren't equeal (a normal situation in this case) and
13148         # print actual read amount.
13149         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13150         if [ "$NOB" != "$BSIZE" ]; then
13151                 error "read $NOB bytes instead of $BSIZE"
13152         fi
13153         rm -f $DIR/$tfile
13154 }
13155 run_test 119a "Short directIO read must return actual read amount"
13156
13157 test_119b() # bug 11737
13158 {
13159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13160
13161         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13162         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13163         sync
13164         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13165                 error "direct read failed"
13166         rm -f $DIR/$tfile
13167 }
13168 run_test 119b "Sparse directIO read must return actual read amount"
13169
13170 test_119c() # bug 13099
13171 {
13172         BSIZE=1048576
13173         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13174         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13175         rm -f $DIR/$tfile
13176 }
13177 run_test 119c "Testing for direct read hitting hole"
13178
13179 test_119d() # bug 15950
13180 {
13181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13182
13183         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13184         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13185         BSIZE=1048576
13186         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13187         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13188         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13189         lctl set_param fail_loc=0x40d
13190         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13191         pid_dio=$!
13192         sleep 1
13193         cat $DIR/$tfile > /dev/null &
13194         lctl set_param fail_loc=0
13195         pid_reads=$!
13196         wait $pid_dio
13197         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13198         sleep 2
13199         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13200         error "the read rpcs have not completed in 2s"
13201         rm -f $DIR/$tfile
13202         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13203 }
13204 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13205
13206 test_120a() {
13207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13208         remote_mds_nodsh && skip "remote MDS with nodsh"
13209         test_mkdir -i0 -c1 $DIR/$tdir
13210         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13211                 skip_env "no early lock cancel on server"
13212
13213         lru_resize_disable mdc
13214         lru_resize_disable osc
13215         cancel_lru_locks mdc
13216         # asynchronous object destroy at MDT could cause bl ast to client
13217         cancel_lru_locks osc
13218
13219         stat $DIR/$tdir > /dev/null
13220         can1=$(do_facet mds1 \
13221                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13222                awk '/ldlm_cancel/ {print $2}')
13223         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13224                awk '/ldlm_bl_callback/ {print $2}')
13225         test_mkdir -i0 -c1 $DIR/$tdir/d1
13226         can2=$(do_facet mds1 \
13227                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13228                awk '/ldlm_cancel/ {print $2}')
13229         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13230                awk '/ldlm_bl_callback/ {print $2}')
13231         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13232         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13233         lru_resize_enable mdc
13234         lru_resize_enable osc
13235 }
13236 run_test 120a "Early Lock Cancel: mkdir test"
13237
13238 test_120b() {
13239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13240         remote_mds_nodsh && skip "remote MDS with nodsh"
13241         test_mkdir $DIR/$tdir
13242         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13243                 skip_env "no early lock cancel on server"
13244
13245         lru_resize_disable mdc
13246         lru_resize_disable osc
13247         cancel_lru_locks mdc
13248         stat $DIR/$tdir > /dev/null
13249         can1=$(do_facet $SINGLEMDS \
13250                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13251                awk '/ldlm_cancel/ {print $2}')
13252         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13253                awk '/ldlm_bl_callback/ {print $2}')
13254         touch $DIR/$tdir/f1
13255         can2=$(do_facet $SINGLEMDS \
13256                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13257                awk '/ldlm_cancel/ {print $2}')
13258         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13259                awk '/ldlm_bl_callback/ {print $2}')
13260         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13261         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13262         lru_resize_enable mdc
13263         lru_resize_enable osc
13264 }
13265 run_test 120b "Early Lock Cancel: create test"
13266
13267 test_120c() {
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         remote_mds_nodsh && skip "remote MDS with nodsh"
13270         test_mkdir -i0 -c1 $DIR/$tdir
13271         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13272                 skip "no early lock cancel on server"
13273
13274         lru_resize_disable mdc
13275         lru_resize_disable osc
13276         test_mkdir -i0 -c1 $DIR/$tdir/d1
13277         test_mkdir -i0 -c1 $DIR/$tdir/d2
13278         touch $DIR/$tdir/d1/f1
13279         cancel_lru_locks mdc
13280         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13281         can1=$(do_facet mds1 \
13282                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13283                awk '/ldlm_cancel/ {print $2}')
13284         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13285                awk '/ldlm_bl_callback/ {print $2}')
13286         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13287         can2=$(do_facet mds1 \
13288                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13289                awk '/ldlm_cancel/ {print $2}')
13290         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13291                awk '/ldlm_bl_callback/ {print $2}')
13292         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13293         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13294         lru_resize_enable mdc
13295         lru_resize_enable osc
13296 }
13297 run_test 120c "Early Lock Cancel: link test"
13298
13299 test_120d() {
13300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13301         remote_mds_nodsh && skip "remote MDS with nodsh"
13302         test_mkdir -i0 -c1 $DIR/$tdir
13303         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13304                 skip_env "no early lock cancel on server"
13305
13306         lru_resize_disable mdc
13307         lru_resize_disable osc
13308         touch $DIR/$tdir
13309         cancel_lru_locks mdc
13310         stat $DIR/$tdir > /dev/null
13311         can1=$(do_facet mds1 \
13312                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13313                awk '/ldlm_cancel/ {print $2}')
13314         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13315                awk '/ldlm_bl_callback/ {print $2}')
13316         chmod a+x $DIR/$tdir
13317         can2=$(do_facet mds1 \
13318                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13319                awk '/ldlm_cancel/ {print $2}')
13320         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13321                awk '/ldlm_bl_callback/ {print $2}')
13322         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13323         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13324         lru_resize_enable mdc
13325         lru_resize_enable osc
13326 }
13327 run_test 120d "Early Lock Cancel: setattr test"
13328
13329 test_120e() {
13330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13331         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13332                 skip_env "no early lock cancel on server"
13333         remote_mds_nodsh && skip "remote MDS with nodsh"
13334
13335         local dlmtrace_set=false
13336
13337         test_mkdir -i0 -c1 $DIR/$tdir
13338         lru_resize_disable mdc
13339         lru_resize_disable osc
13340         ! $LCTL get_param debug | grep -q dlmtrace &&
13341                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13342         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13343         cancel_lru_locks mdc
13344         cancel_lru_locks osc
13345         dd if=$DIR/$tdir/f1 of=/dev/null
13346         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13347         # XXX client can not do early lock cancel of OST lock
13348         # during unlink (LU-4206), so cancel osc lock now.
13349         sleep 2
13350         cancel_lru_locks osc
13351         can1=$(do_facet mds1 \
13352                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13353                awk '/ldlm_cancel/ {print $2}')
13354         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13355                awk '/ldlm_bl_callback/ {print $2}')
13356         unlink $DIR/$tdir/f1
13357         sleep 5
13358         can2=$(do_facet mds1 \
13359                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13360                awk '/ldlm_cancel/ {print $2}')
13361         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13362                awk '/ldlm_bl_callback/ {print $2}')
13363         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13364                 $LCTL dk $TMP/cancel.debug.txt
13365         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13366                 $LCTL dk $TMP/blocking.debug.txt
13367         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13368         lru_resize_enable mdc
13369         lru_resize_enable osc
13370 }
13371 run_test 120e "Early Lock Cancel: unlink test"
13372
13373 test_120f() {
13374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13375         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13376                 skip_env "no early lock cancel on server"
13377         remote_mds_nodsh && skip "remote MDS with nodsh"
13378
13379         test_mkdir -i0 -c1 $DIR/$tdir
13380         lru_resize_disable mdc
13381         lru_resize_disable osc
13382         test_mkdir -i0 -c1 $DIR/$tdir/d1
13383         test_mkdir -i0 -c1 $DIR/$tdir/d2
13384         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13385         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13386         cancel_lru_locks mdc
13387         cancel_lru_locks osc
13388         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13389         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13390         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13391         # XXX client can not do early lock cancel of OST lock
13392         # during rename (LU-4206), so cancel osc lock now.
13393         sleep 2
13394         cancel_lru_locks osc
13395         can1=$(do_facet mds1 \
13396                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13397                awk '/ldlm_cancel/ {print $2}')
13398         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13399                awk '/ldlm_bl_callback/ {print $2}')
13400         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13401         sleep 5
13402         can2=$(do_facet mds1 \
13403                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13404                awk '/ldlm_cancel/ {print $2}')
13405         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13406                awk '/ldlm_bl_callback/ {print $2}')
13407         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13408         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13409         lru_resize_enable mdc
13410         lru_resize_enable osc
13411 }
13412 run_test 120f "Early Lock Cancel: rename test"
13413
13414 test_120g() {
13415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13416         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13417                 skip_env "no early lock cancel on server"
13418         remote_mds_nodsh && skip "remote MDS with nodsh"
13419
13420         lru_resize_disable mdc
13421         lru_resize_disable osc
13422         count=10000
13423         echo create $count files
13424         test_mkdir $DIR/$tdir
13425         cancel_lru_locks mdc
13426         cancel_lru_locks osc
13427         t0=$(date +%s)
13428
13429         can0=$(do_facet $SINGLEMDS \
13430                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13431                awk '/ldlm_cancel/ {print $2}')
13432         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13433                awk '/ldlm_bl_callback/ {print $2}')
13434         createmany -o $DIR/$tdir/f $count
13435         sync
13436         can1=$(do_facet $SINGLEMDS \
13437                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13438                awk '/ldlm_cancel/ {print $2}')
13439         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13440                awk '/ldlm_bl_callback/ {print $2}')
13441         t1=$(date +%s)
13442         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13443         echo rm $count files
13444         rm -r $DIR/$tdir
13445         sync
13446         can2=$(do_facet $SINGLEMDS \
13447                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13448                awk '/ldlm_cancel/ {print $2}')
13449         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13450                awk '/ldlm_bl_callback/ {print $2}')
13451         t2=$(date +%s)
13452         echo total: $count removes in $((t2-t1))
13453         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13454         sleep 2
13455         # wait for commitment of removal
13456         lru_resize_enable mdc
13457         lru_resize_enable osc
13458 }
13459 run_test 120g "Early Lock Cancel: performance test"
13460
13461 test_121() { #bug #10589
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         rm -rf $DIR/$tfile
13465         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13466 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13467         lctl set_param fail_loc=0x310
13468         cancel_lru_locks osc > /dev/null
13469         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13470         lctl set_param fail_loc=0
13471         [[ $reads -eq $writes ]] ||
13472                 error "read $reads blocks, must be $writes blocks"
13473 }
13474 run_test 121 "read cancel race ========="
13475
13476 test_123a_base() { # was test 123, statahead(bug 11401)
13477         local lsx="$1"
13478
13479         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13480
13481         SLOWOK=0
13482         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13483                 log "testing UP system. Performance may be lower than expected."
13484                 SLOWOK=1
13485         fi
13486         running_in_vm && SLOWOK=1
13487
13488         rm -rf $DIR/$tdir
13489         test_mkdir $DIR/$tdir
13490         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13491         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13492         MULT=10
13493         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13494                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13495
13496                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13497                 lctl set_param -n llite.*.statahead_max 0
13498                 lctl get_param llite.*.statahead_max
13499                 cancel_lru_locks mdc
13500                 cancel_lru_locks osc
13501                 stime=$(date +%s)
13502                 time $lsx $DIR/$tdir | wc -l
13503                 etime=$(date +%s)
13504                 delta=$((etime - stime))
13505                 log "$lsx $i files without statahead: $delta sec"
13506                 lctl set_param llite.*.statahead_max=$max
13507
13508                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13509                          awk '/statahead.wrong:/ { print $NF }')
13510                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13511                 cancel_lru_locks mdc
13512                 cancel_lru_locks osc
13513                 stime=$(date +%s)
13514                 time $lsx $DIR/$tdir | wc -l
13515                 etime=$(date +%s)
13516                 delta_sa=$((etime - stime))
13517                 log "$lsx $i files with statahead: $delta_sa sec"
13518                 lctl get_param -n llite.*.statahead_stats
13519                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13520                          awk '/statahead.wrong:/ { print $NF }')
13521
13522                 [[ $swrong -lt $ewrong ]] &&
13523                         log "statahead was stopped, maybe too many locks held!"
13524                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13525
13526                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13527                         max=$(lctl get_param -n llite.*.statahead_max |
13528                                 head -n 1)
13529                         lctl set_param -n llite.*.statahead_max 0
13530                         lctl get_param llite.*.statahead_max
13531                         cancel_lru_locks mdc
13532                         cancel_lru_locks osc
13533                         stime=$(date +%s)
13534                         time $lsx $DIR/$tdir | wc -l
13535                         etime=$(date +%s)
13536                         delta=$((etime - stime))
13537                         log "$lsx $i files again without statahead: $delta sec"
13538                         lctl set_param llite.*.statahead_max=$max
13539                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13540                                 if [ $SLOWOK -eq 0 ]; then
13541                                         error "$lsx $i files is slower with statahead!"
13542                                 else
13543                                         log "$lsx $i files is slower with statahead!"
13544                                 fi
13545                                 break
13546                         fi
13547                 fi
13548
13549                 [ $delta -gt 20 ] && break
13550                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13551                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13552         done
13553         log "$lsx done"
13554
13555         stime=$(date +%s)
13556         rm -r $DIR/$tdir
13557         sync
13558         etime=$(date +%s)
13559         delta=$((etime - stime))
13560         log "rm -r $DIR/$tdir/: $delta seconds"
13561         log "rm done"
13562         lctl get_param -n llite.*.statahead_stats
13563 }
13564
13565 test_123aa() {
13566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13567
13568         test_123a_base "ls -l"
13569 }
13570 run_test 123aa "verify statahead work"
13571
13572 test_123ab() {
13573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13574
13575         statx_supported || skip_env "Test must be statx() syscall supported"
13576
13577         test_123a_base "$STATX -l"
13578 }
13579 run_test 123ab "verify statahead work by using statx"
13580
13581 test_123ac() {
13582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13583
13584         statx_supported || skip_env "Test must be statx() syscall supported"
13585
13586         local rpcs_before
13587         local rpcs_after
13588         local agl_before
13589         local agl_after
13590
13591         cancel_lru_locks $OSC
13592         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13593         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13594                      awk '/agl.total:/ { print $NF }')
13595         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13596         test_123a_base "$STATX --cached=always -D"
13597         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13598                     awk '/agl.total:/ { print $NF }')
13599         [ $agl_before -eq $agl_after ] ||
13600                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13601         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13602         [ $rpcs_after -eq $rpcs_before ] ||
13603                 error "$STATX should not send glimpse RPCs to $OSC"
13604 }
13605 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13606
13607 test_123b () { # statahead(bug 15027)
13608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13609
13610         test_mkdir $DIR/$tdir
13611         createmany -o $DIR/$tdir/$tfile-%d 1000
13612
13613         cancel_lru_locks mdc
13614         cancel_lru_locks osc
13615
13616 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13617         lctl set_param fail_loc=0x80000803
13618         ls -lR $DIR/$tdir > /dev/null
13619         log "ls done"
13620         lctl set_param fail_loc=0x0
13621         lctl get_param -n llite.*.statahead_stats
13622         rm -r $DIR/$tdir
13623         sync
13624
13625 }
13626 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13627
13628 test_123c() {
13629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13630
13631         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13632         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13633         touch $DIR/$tdir.1/{1..3}
13634         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13635
13636         remount_client $MOUNT
13637
13638         $MULTIOP $DIR/$tdir.0 Q
13639
13640         # let statahead to complete
13641         ls -l $DIR/$tdir.0 > /dev/null
13642
13643         testid=$(echo $TESTNAME | tr '_' ' ')
13644         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13645                 error "statahead warning" || true
13646 }
13647 run_test 123c "Can not initialize inode warning on DNE statahead"
13648
13649 test_123d() {
13650         local num=100
13651         local swrong
13652         local ewrong
13653
13654         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13655         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13656                 error "setdirstripe $DIR/$tdir failed"
13657         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13658         remount_client $MOUNT
13659         $LCTL get_param llite.*.statahead_max
13660         $LCTL set_param llite.*.statahead_stats=0 ||
13661                 error "clear statahead_stats failed"
13662         swrong=$(lctl get_param -n llite.*.statahead_stats |
13663                  awk '/statahead.wrong:/ { print $NF }')
13664         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13665         # wait for statahead thread finished to update hit/miss stats.
13666         sleep 1
13667         $LCTL get_param -n llite.*.statahead_stats
13668         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13669                  awk '/statahead.wrong:/ { print $NF }')
13670         (( $swrong == $ewrong )) ||
13671                 log "statahead was stopped, maybe too many locks held!"
13672 }
13673 run_test 123d "Statahead on striped directories works correctly"
13674
13675 test_124a() {
13676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13677         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13678                 skip_env "no lru resize on server"
13679
13680         local NR=2000
13681
13682         test_mkdir $DIR/$tdir
13683
13684         log "create $NR files at $DIR/$tdir"
13685         createmany -o $DIR/$tdir/f $NR ||
13686                 error "failed to create $NR files in $DIR/$tdir"
13687
13688         cancel_lru_locks mdc
13689         ls -l $DIR/$tdir > /dev/null
13690
13691         local NSDIR=""
13692         local LRU_SIZE=0
13693         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13694                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13695                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13696                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13697                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13698                         log "NSDIR=$NSDIR"
13699                         log "NS=$(basename $NSDIR)"
13700                         break
13701                 fi
13702         done
13703
13704         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13705                 skip "Not enough cached locks created!"
13706         fi
13707         log "LRU=$LRU_SIZE"
13708
13709         local SLEEP=30
13710
13711         # We know that lru resize allows one client to hold $LIMIT locks
13712         # for 10h. After that locks begin to be killed by client.
13713         local MAX_HRS=10
13714         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13715         log "LIMIT=$LIMIT"
13716         if [ $LIMIT -lt $LRU_SIZE ]; then
13717                 skip "Limit is too small $LIMIT"
13718         fi
13719
13720         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13721         # killing locks. Some time was spent for creating locks. This means
13722         # that up to the moment of sleep finish we must have killed some of
13723         # them (10-100 locks). This depends on how fast ther were created.
13724         # Many of them were touched in almost the same moment and thus will
13725         # be killed in groups.
13726         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13727
13728         # Use $LRU_SIZE_B here to take into account real number of locks
13729         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13730         local LRU_SIZE_B=$LRU_SIZE
13731         log "LVF=$LVF"
13732         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13733         log "OLD_LVF=$OLD_LVF"
13734         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13735
13736         # Let's make sure that we really have some margin. Client checks
13737         # cached locks every 10 sec.
13738         SLEEP=$((SLEEP+20))
13739         log "Sleep ${SLEEP} sec"
13740         local SEC=0
13741         while ((SEC<$SLEEP)); do
13742                 echo -n "..."
13743                 sleep 5
13744                 SEC=$((SEC+5))
13745                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13746                 echo -n "$LRU_SIZE"
13747         done
13748         echo ""
13749         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13750         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13751
13752         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13753                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13754                 unlinkmany $DIR/$tdir/f $NR
13755                 return
13756         }
13757
13758         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13759         log "unlink $NR files at $DIR/$tdir"
13760         unlinkmany $DIR/$tdir/f $NR
13761 }
13762 run_test 124a "lru resize ======================================="
13763
13764 get_max_pool_limit()
13765 {
13766         local limit=$($LCTL get_param \
13767                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13768         local max=0
13769         for l in $limit; do
13770                 if [[ $l -gt $max ]]; then
13771                         max=$l
13772                 fi
13773         done
13774         echo $max
13775 }
13776
13777 test_124b() {
13778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13779         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13780                 skip_env "no lru resize on server"
13781
13782         LIMIT=$(get_max_pool_limit)
13783
13784         NR=$(($(default_lru_size)*20))
13785         if [[ $NR -gt $LIMIT ]]; then
13786                 log "Limit lock number by $LIMIT locks"
13787                 NR=$LIMIT
13788         fi
13789
13790         IFree=$(mdsrate_inodes_available)
13791         if [ $IFree -lt $NR ]; then
13792                 log "Limit lock number by $IFree inodes"
13793                 NR=$IFree
13794         fi
13795
13796         lru_resize_disable mdc
13797         test_mkdir -p $DIR/$tdir/disable_lru_resize
13798
13799         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13800         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13801         cancel_lru_locks mdc
13802         stime=`date +%s`
13803         PID=""
13804         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13805         PID="$PID $!"
13806         sleep 2
13807         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13808         PID="$PID $!"
13809         sleep 2
13810         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13811         PID="$PID $!"
13812         wait $PID
13813         etime=`date +%s`
13814         nolruresize_delta=$((etime-stime))
13815         log "ls -la time: $nolruresize_delta seconds"
13816         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13817         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13818
13819         lru_resize_enable mdc
13820         test_mkdir -p $DIR/$tdir/enable_lru_resize
13821
13822         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13823         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13824         cancel_lru_locks mdc
13825         stime=`date +%s`
13826         PID=""
13827         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13828         PID="$PID $!"
13829         sleep 2
13830         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13831         PID="$PID $!"
13832         sleep 2
13833         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13834         PID="$PID $!"
13835         wait $PID
13836         etime=`date +%s`
13837         lruresize_delta=$((etime-stime))
13838         log "ls -la time: $lruresize_delta seconds"
13839         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13840
13841         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13842                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13843         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13844                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13845         else
13846                 log "lru resize performs the same with no lru resize"
13847         fi
13848         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13849 }
13850 run_test 124b "lru resize (performance test) ======================="
13851
13852 test_124c() {
13853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13854         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13855                 skip_env "no lru resize on server"
13856
13857         # cache ununsed locks on client
13858         local nr=100
13859         cancel_lru_locks mdc
13860         test_mkdir $DIR/$tdir
13861         createmany -o $DIR/$tdir/f $nr ||
13862                 error "failed to create $nr files in $DIR/$tdir"
13863         ls -l $DIR/$tdir > /dev/null
13864
13865         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13866         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13867         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13868         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13869         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13870
13871         # set lru_max_age to 1 sec
13872         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13873         echo "sleep $((recalc_p * 2)) seconds..."
13874         sleep $((recalc_p * 2))
13875
13876         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13877         # restore lru_max_age
13878         $LCTL set_param -n $nsdir.lru_max_age $max_age
13879         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13880         unlinkmany $DIR/$tdir/f $nr
13881 }
13882 run_test 124c "LRUR cancel very aged locks"
13883
13884 test_124d() {
13885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13886         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13887                 skip_env "no lru resize on server"
13888
13889         # cache ununsed locks on client
13890         local nr=100
13891
13892         lru_resize_disable mdc
13893         stack_trap "lru_resize_enable mdc" EXIT
13894
13895         cancel_lru_locks mdc
13896
13897         # asynchronous object destroy at MDT could cause bl ast to client
13898         test_mkdir $DIR/$tdir
13899         createmany -o $DIR/$tdir/f $nr ||
13900                 error "failed to create $nr files in $DIR/$tdir"
13901         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13902
13903         ls -l $DIR/$tdir > /dev/null
13904
13905         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13906         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13907         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13908         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13909
13910         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13911
13912         # set lru_max_age to 1 sec
13913         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13914         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13915
13916         echo "sleep $((recalc_p * 2)) seconds..."
13917         sleep $((recalc_p * 2))
13918
13919         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13920
13921         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13922 }
13923 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13924
13925 test_125() { # 13358
13926         $LCTL get_param -n llite.*.client_type | grep -q local ||
13927                 skip "must run as local client"
13928         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13929                 skip_env "must have acl enabled"
13930         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13931
13932         test_mkdir $DIR/$tdir
13933         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13934         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13935                 error "setfacl $DIR/$tdir failed"
13936         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13937 }
13938 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13939
13940 test_126() { # bug 12829/13455
13941         $GSS && skip_env "must run as gss disabled"
13942         $LCTL get_param -n llite.*.client_type | grep -q local ||
13943                 skip "must run as local client"
13944         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13945
13946         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13947         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13948         rm -f $DIR/$tfile
13949         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13950 }
13951 run_test 126 "check that the fsgid provided by the client is taken into account"
13952
13953 test_127a() { # bug 15521
13954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13955         local name count samp unit min max sum sumsq
13956         local tmpfile=$TMP/$tfile.tmp
13957
13958         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13959         echo "stats before reset"
13960         stack_trap "rm -f $tmpfile"
13961         local now=$(date +%s)
13962
13963         $LCTL get_param osc.*.stats | tee $tmpfile
13964
13965         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13966         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13967         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13968         local uptime=$(awk '{ print $1 }' /proc/uptime)
13969
13970         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13971         (( ${snapshot_time%\.*} >= $now - 5 &&
13972            ${snapshot_time%\.*} <= $now + 5 )) ||
13973                 error "snapshot_time=$snapshot_time != now=$now"
13974         # elapsed _should_ be from mount, but at least less than uptime
13975         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13976                 error "elapsed=$elapsed > uptime=$uptime"
13977         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13978            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13979                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13980
13981         $LCTL set_param osc.*.stats=0
13982         local reset=$(date +%s)
13983         local fsize=$((2048 * 1024))
13984
13985         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13986         cancel_lru_locks osc
13987         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13988
13989         now=$(date +%s)
13990         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13991         while read name count samp unit min max sum sumsq; do
13992                 [[ "$samp" == "samples" ]] || continue
13993
13994                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13995                 [ ! $min ] && error "Missing min value for $name proc entry"
13996                 eval $name=$count || error "Wrong proc format"
13997
13998                 case $name in
13999                 read_bytes|write_bytes)
14000                         [[ "$unit" =~ "bytes" ]] ||
14001                                 error "unit is not 'bytes': $unit"
14002                         (( $min >= 4096 )) || error "min is too small: $min"
14003                         (( $min <= $fsize )) || error "min is too big: $min"
14004                         (( $max >= 4096 )) || error "max is too small: $max"
14005                         (( $max <= $fsize )) || error "max is too big: $max"
14006                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14007                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14008                                 error "sumsquare is too small: $sumsq"
14009                         (( $sumsq <= $fsize * $fsize )) ||
14010                                 error "sumsquare is too big: $sumsq"
14011                         ;;
14012                 ost_read|ost_write)
14013                         [[ "$unit" =~ "usec" ]] ||
14014                                 error "unit is not 'usec': $unit"
14015                         ;;
14016                 *)      ;;
14017                 esac
14018         done < $tmpfile
14019
14020         #check that we actually got some stats
14021         [ "$read_bytes" ] || error "Missing read_bytes stats"
14022         [ "$write_bytes" ] || error "Missing write_bytes stats"
14023         [ "$read_bytes" != 0 ] || error "no read done"
14024         [ "$write_bytes" != 0 ] || error "no write done"
14025
14026         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14027         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14028         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14029
14030         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14031         (( ${snapshot_time%\.*} >= $now - 5 &&
14032            ${snapshot_time%\.*} <= $now + 5 )) ||
14033                 error "reset snapshot_time=$snapshot_time != now=$now"
14034         # elapsed should be from time of stats reset
14035         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14036            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14037                 error "reset elapsed=$elapsed > $now - $reset"
14038         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14039            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14040                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14041 }
14042 run_test 127a "verify the client stats are sane"
14043
14044 test_127b() { # bug LU-333
14045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14046         local name count samp unit min max sum sumsq
14047
14048         echo "stats before reset"
14049         $LCTL get_param llite.*.stats
14050         $LCTL set_param llite.*.stats=0
14051
14052         # perform 2 reads and writes so MAX is different from SUM.
14053         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14054         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14055         cancel_lru_locks osc
14056         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14057         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14058
14059         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14060         stack_trap "rm -f $TMP/$tfile.tmp"
14061         while read name count samp unit min max sum sumsq; do
14062                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14063                 eval $name=$count || error "Wrong proc format"
14064
14065                 case $name in
14066                 read_bytes|write_bytes)
14067                         [[ "$unit" =~ "bytes" ]] ||
14068                                 error "unit is not 'bytes': $unit"
14069                         (( $count == 2 )) || error "count is not 2: $count"
14070                         (( $min == $PAGE_SIZE )) ||
14071                                 error "min is not $PAGE_SIZE: $min"
14072                         (( $max == $PAGE_SIZE )) ||
14073                                 error "max is not $PAGE_SIZE: $max"
14074                         (( $sum == $PAGE_SIZE * 2 )) ||
14075                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14076                         ;;
14077                 read|write)
14078                         [[ "$unit" =~ "usec" ]] ||
14079                                 error "unit is not 'usec': $unit"
14080                         ;;
14081                 *)      ;;
14082                 esac
14083         done < $TMP/$tfile.tmp
14084
14085         #check that we actually got some stats
14086         [ "$read_bytes" ] || error "Missing read_bytes stats"
14087         [ "$write_bytes" ] || error "Missing write_bytes stats"
14088         [ "$read_bytes" != 0 ] || error "no read done"
14089         [ "$write_bytes" != 0 ] || error "no write done"
14090 }
14091 run_test 127b "verify the llite client stats are sane"
14092
14093 test_127c() { # LU-12394
14094         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14095         local size
14096         local bsize
14097         local reads
14098         local writes
14099         local count
14100
14101         $LCTL set_param llite.*.extents_stats=1
14102         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14103
14104         # Use two stripes so there is enough space in default config
14105         $LFS setstripe -c 2 $DIR/$tfile
14106
14107         # Extent stats start at 0-4K and go in power of two buckets
14108         # LL_HIST_START = 12 --> 2^12 = 4K
14109         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14110         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14111         # small configs
14112         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14113                 do
14114                 # Write and read, 2x each, second time at a non-zero offset
14115                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14116                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14117                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14118                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14119                 rm -f $DIR/$tfile
14120         done
14121
14122         $LCTL get_param llite.*.extents_stats
14123
14124         count=2
14125         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14126                 do
14127                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14128                                 grep -m 1 $bsize)
14129                 reads=$(echo $bucket | awk '{print $5}')
14130                 writes=$(echo $bucket | awk '{print $9}')
14131                 [ "$reads" -eq $count ] ||
14132                         error "$reads reads in < $bsize bucket, expect $count"
14133                 [ "$writes" -eq $count ] ||
14134                         error "$writes writes in < $bsize bucket, expect $count"
14135         done
14136
14137         # Test mmap write and read
14138         $LCTL set_param llite.*.extents_stats=c
14139         size=512
14140         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14141         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14142         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14143
14144         $LCTL get_param llite.*.extents_stats
14145
14146         count=$(((size*1024) / PAGE_SIZE))
14147
14148         bsize=$((2 * PAGE_SIZE / 1024))K
14149
14150         bucket=$($LCTL get_param -n llite.*.extents_stats |
14151                         grep -m 1 $bsize)
14152         reads=$(echo $bucket | awk '{print $5}')
14153         writes=$(echo $bucket | awk '{print $9}')
14154         # mmap writes fault in the page first, creating an additonal read
14155         [ "$reads" -eq $((2 * count)) ] ||
14156                 error "$reads reads in < $bsize bucket, expect $count"
14157         [ "$writes" -eq $count ] ||
14158                 error "$writes writes in < $bsize bucket, expect $count"
14159 }
14160 run_test 127c "test llite extent stats with regular & mmap i/o"
14161
14162 test_128() { # bug 15212
14163         touch $DIR/$tfile
14164         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14165                 find $DIR/$tfile
14166                 find $DIR/$tfile
14167         EOF
14168
14169         result=$(grep error $TMP/$tfile.log)
14170         rm -f $DIR/$tfile $TMP/$tfile.log
14171         [ -z "$result" ] ||
14172                 error "consecutive find's under interactive lfs failed"
14173 }
14174 run_test 128 "interactive lfs for 2 consecutive find's"
14175
14176 set_dir_limits () {
14177         local mntdev
14178         local canondev
14179         local node
14180
14181         local ldproc=/proc/fs/ldiskfs
14182         local facets=$(get_facets MDS)
14183
14184         for facet in ${facets//,/ }; do
14185                 canondev=$(ldiskfs_canon \
14186                            *.$(convert_facet2label $facet).mntdev $facet)
14187                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14188                         ldproc=/sys/fs/ldiskfs
14189                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14190                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14191         done
14192 }
14193
14194 check_mds_dmesg() {
14195         local facets=$(get_facets MDS)
14196         for facet in ${facets//,/ }; do
14197                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14198         done
14199         return 1
14200 }
14201
14202 test_129() {
14203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14204         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14205                 skip "Need MDS version with at least 2.5.56"
14206         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14207                 skip_env "ldiskfs only test"
14208         fi
14209         remote_mds_nodsh && skip "remote MDS with nodsh"
14210
14211         local ENOSPC=28
14212         local has_warning=false
14213
14214         rm -rf $DIR/$tdir
14215         mkdir -p $DIR/$tdir
14216
14217         # block size of mds1
14218         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14219         set_dir_limits $maxsize $((maxsize * 6 / 8))
14220         stack_trap "set_dir_limits 0 0"
14221         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14222         local dirsize=$(stat -c%s "$DIR/$tdir")
14223         local nfiles=0
14224         while (( $dirsize <= $maxsize )); do
14225                 $MCREATE $DIR/$tdir/file_base_$nfiles
14226                 rc=$?
14227                 # check two errors:
14228                 # ENOSPC for ext4 max_dir_size, which has been used since
14229                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14230                 if (( rc == ENOSPC )); then
14231                         set_dir_limits 0 0
14232                         echo "rc=$rc returned as expected after $nfiles files"
14233
14234                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14235                                 error "create failed w/o dir size limit"
14236
14237                         # messages may be rate limited if test is run repeatedly
14238                         check_mds_dmesg '"is approaching max"' ||
14239                                 echo "warning message should be output"
14240                         check_mds_dmesg '"has reached max"' ||
14241                                 echo "reached message should be output"
14242
14243                         dirsize=$(stat -c%s "$DIR/$tdir")
14244
14245                         [[ $dirsize -ge $maxsize ]] && return 0
14246                         error "dirsize $dirsize < $maxsize after $nfiles files"
14247                 elif (( rc != 0 )); then
14248                         break
14249                 fi
14250                 nfiles=$((nfiles + 1))
14251                 dirsize=$(stat -c%s "$DIR/$tdir")
14252         done
14253
14254         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14255 }
14256 run_test 129 "test directory size limit ========================"
14257
14258 OLDIFS="$IFS"
14259 cleanup_130() {
14260         trap 0
14261         IFS="$OLDIFS"
14262 }
14263
14264 test_130a() {
14265         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14266         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14267
14268         trap cleanup_130 EXIT RETURN
14269
14270         local fm_file=$DIR/$tfile
14271         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14272         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14273                 error "dd failed for $fm_file"
14274
14275         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14276         filefrag -ves $fm_file
14277         local rc=$?
14278         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14279                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14280         (( $rc == 0 )) || error "filefrag $fm_file failed"
14281
14282         filefrag_op=$(filefrag -ve -k $fm_file |
14283                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14284         local lun=$($LFS getstripe -i $fm_file)
14285
14286         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14287         IFS=$'\n'
14288         local tot_len=0
14289         for line in $filefrag_op; do
14290                 local frag_lun=$(echo $line | cut -d: -f5)
14291                 local ext_len=$(echo $line | cut -d: -f4)
14292
14293                 if (( $frag_lun != $lun )); then
14294                         error "FIEMAP on 1-stripe file($fm_file) failed"
14295                         return
14296                 fi
14297                 (( tot_len += ext_len ))
14298         done
14299
14300         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14301                 error "FIEMAP on 1-stripe file($fm_file) failed"
14302                 return
14303         fi
14304
14305         echo "FIEMAP on single striped file succeeded"
14306 }
14307 run_test 130a "FIEMAP (1-stripe file)"
14308
14309 test_130b() {
14310         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14311
14312         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14313         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14314         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14315                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14316
14317         trap cleanup_130 EXIT RETURN
14318
14319         local fm_file=$DIR/$tfile
14320         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14321                 error "setstripe on $fm_file"
14322
14323         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14324                 error "dd failed on $fm_file"
14325
14326         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14327         filefrag_op=$(filefrag -ve -k $fm_file |
14328                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14329
14330         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14331                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14332
14333         IFS=$'\n'
14334         local tot_len=0
14335         local num_luns=1
14336
14337         for line in $filefrag_op; do
14338                 local frag_lun=$(echo $line | cut -d: -f5 |
14339                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14340                 local ext_len=$(echo $line | cut -d: -f4)
14341                 if (( $frag_lun != $last_lun )); then
14342                         if (( tot_len != 1024 )); then
14343                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14344                                 return
14345                         else
14346                                 (( num_luns += 1 ))
14347                                 tot_len=0
14348                         fi
14349                 fi
14350                 (( tot_len += ext_len ))
14351                 last_lun=$frag_lun
14352         done
14353         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14354                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14355                 return
14356         fi
14357
14358         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14359 }
14360 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14361
14362 test_130c() {
14363         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14364
14365         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14366         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14367         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14368                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14369
14370         trap cleanup_130 EXIT RETURN
14371
14372         local fm_file=$DIR/$tfile
14373         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14374
14375         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14376                 error "dd failed on $fm_file"
14377
14378         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14379         filefrag_op=$(filefrag -ve -k $fm_file |
14380                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14381
14382         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14383                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14384
14385         IFS=$'\n'
14386         local tot_len=0
14387         local num_luns=1
14388         for line in $filefrag_op; do
14389                 local frag_lun=$(echo $line | cut -d: -f5 |
14390                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14391                 local ext_len=$(echo $line | cut -d: -f4)
14392                 if (( $frag_lun != $last_lun )); then
14393                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14394                         if (( logical != 512 )); then
14395                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14396                                 return
14397                         fi
14398                         if (( tot_len != 512 )); then
14399                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14400                                 return
14401                         else
14402                                 (( num_luns += 1 ))
14403                                 tot_len=0
14404                         fi
14405                 fi
14406                 (( tot_len += ext_len ))
14407                 last_lun=$frag_lun
14408         done
14409         if (( num_luns != 2 || tot_len != 512 )); then
14410                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14411                 return
14412         fi
14413
14414         echo "FIEMAP on 2-stripe file with hole succeeded"
14415 }
14416 run_test 130c "FIEMAP (2-stripe file with hole)"
14417
14418 test_130d() {
14419         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14420
14421         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14422         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14423         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14424                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14425
14426         trap cleanup_130 EXIT RETURN
14427
14428         local fm_file=$DIR/$tfile
14429         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14430                         error "setstripe on $fm_file"
14431
14432         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14433         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14434                 error "dd failed on $fm_file"
14435
14436         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14437         filefrag_op=$(filefrag -ve -k $fm_file |
14438                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14439
14440         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14441                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14442
14443         IFS=$'\n'
14444         local tot_len=0
14445         local num_luns=1
14446         for line in $filefrag_op; do
14447                 local frag_lun=$(echo $line | cut -d: -f5 |
14448                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14449                 local ext_len=$(echo $line | cut -d: -f4)
14450                 if (( $frag_lun != $last_lun )); then
14451                         if (( tot_len != 1024 )); then
14452                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14453                                 return
14454                         else
14455                                 (( num_luns += 1 ))
14456                                 local tot_len=0
14457                         fi
14458                 fi
14459                 (( tot_len += ext_len ))
14460                 last_lun=$frag_lun
14461         done
14462         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14463                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14464                 return
14465         fi
14466
14467         echo "FIEMAP on N-stripe file succeeded"
14468 }
14469 run_test 130d "FIEMAP (N-stripe file)"
14470
14471 test_130e() {
14472         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14473
14474         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14475         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14476         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14477                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14478
14479         trap cleanup_130 EXIT RETURN
14480
14481         local fm_file=$DIR/$tfile
14482         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14483
14484         local num_blks=512
14485         local expected_len=$(( (num_blks / 2) * 64 ))
14486         for ((i = 0; i < $num_blks; i++)); do
14487                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14488                         conv=notrunc > /dev/null 2>&1
14489         done
14490
14491         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14492         filefrag_op=$(filefrag -ve -k $fm_file |
14493                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14494
14495         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14496
14497         IFS=$'\n'
14498         local tot_len=0
14499         local num_luns=1
14500         for line in $filefrag_op; do
14501                 local frag_lun=$(echo $line | cut -d: -f5)
14502                 local ext_len=$(echo $line | cut -d: -f4)
14503                 if (( $frag_lun != $last_lun )); then
14504                         if (( tot_len != $expected_len )); then
14505                                 error "OST$last_lun $tot_len != $expected_len"
14506                         else
14507                                 (( num_luns += 1 ))
14508                                 tot_len=0
14509                         fi
14510                 fi
14511                 (( tot_len += ext_len ))
14512                 last_lun=$frag_lun
14513         done
14514         if (( num_luns != 2 || tot_len != $expected_len )); then
14515                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14516         fi
14517
14518         echo "FIEMAP with continuation calls succeeded"
14519 }
14520 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14521
14522 test_130f() {
14523         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14524         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14525         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14526                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14527
14528         local fm_file=$DIR/$tfile
14529         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14530                 error "multiop create with lov_delay_create on $fm_file"
14531
14532         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14533         filefrag_extents=$(filefrag -vek $fm_file |
14534                            awk '/extents? found/ { print $2 }')
14535         if (( $filefrag_extents != 0 )); then
14536                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14537         fi
14538
14539         rm -f $fm_file
14540 }
14541 run_test 130f "FIEMAP (unstriped file)"
14542
14543 test_130g() {
14544         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14545                 skip "Need MDS version with at least 2.12.53 for overstriping"
14546         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14547         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14548         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14549                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14550
14551         local file=$DIR/$tfile
14552         local nr=$((OSTCOUNT * 100))
14553
14554         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14555
14556         stack_trap "rm -f $file"
14557         dd if=/dev/zero of=$file count=$nr bs=1M
14558         sync
14559         nr=$($LFS getstripe -c $file)
14560
14561         local extents=$(filefrag -v $file |
14562                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14563
14564         echo "filefrag list $extents extents in file with stripecount $nr"
14565         if (( extents < nr )); then
14566                 $LFS getstripe $file
14567                 filefrag -v $file
14568                 error "filefrag printed $extents < $nr extents"
14569         fi
14570 }
14571 run_test 130g "FIEMAP (overstripe file)"
14572
14573 # Test for writev/readv
14574 test_131a() {
14575         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14576                 error "writev test failed"
14577         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14578                 error "readv failed"
14579         rm -f $DIR/$tfile
14580 }
14581 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14582
14583 test_131b() {
14584         local fsize=$((524288 + 1048576 + 1572864))
14585         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14586                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14587                         error "append writev test failed"
14588
14589         ((fsize += 1572864 + 1048576))
14590         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14591                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14592                         error "append writev test failed"
14593         rm -f $DIR/$tfile
14594 }
14595 run_test 131b "test append writev"
14596
14597 test_131c() {
14598         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14599         error "NOT PASS"
14600 }
14601 run_test 131c "test read/write on file w/o objects"
14602
14603 test_131d() {
14604         rwv -f $DIR/$tfile -w -n 1 1572864
14605         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14606         if [ "$NOB" != 1572864 ]; then
14607                 error "Short read filed: read $NOB bytes instead of 1572864"
14608         fi
14609         rm -f $DIR/$tfile
14610 }
14611 run_test 131d "test short read"
14612
14613 test_131e() {
14614         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14615         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14616         error "read hitting hole failed"
14617         rm -f $DIR/$tfile
14618 }
14619 run_test 131e "test read hitting hole"
14620
14621 check_stats() {
14622         local facet=$1
14623         local op=$2
14624         local want=${3:-0}
14625         local res
14626
14627         # open             11 samples [usecs] 468 4793 13658 35791898
14628         case $facet in
14629         mds*) res=($(do_facet $facet \
14630                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14631                  ;;
14632         ost*) res=($(do_facet $facet \
14633                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14634                  ;;
14635         *) error "Wrong facet '$facet'" ;;
14636         esac
14637         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14638         # if $want is zero, it means any stat increment is ok.
14639         if (( $want > 0 )); then
14640                 local count=${res[1]}
14641
14642                 if (( $count != $want )); then
14643                         if [[ $facet =~ "mds" ]]; then
14644                                 do_nodes $(comma_list $(mdts_nodes)) \
14645                                         $LCTL get_param mdt.*.md_stats
14646                         else
14647                                 do_nodes $(comma_list $(osts-nodes)) \
14648                                         $LCTL get_param obdfilter.*.stats
14649                         fi
14650                         error "The $op counter on $facet is $count, not $want"
14651                 fi
14652         fi
14653 }
14654
14655 test_133a() {
14656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14657         remote_ost_nodsh && skip "remote OST with nodsh"
14658         remote_mds_nodsh && skip "remote MDS with nodsh"
14659         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14660                 skip_env "MDS doesn't support rename stats"
14661
14662         local testdir=$DIR/${tdir}/stats_testdir
14663
14664         mkdir -p $DIR/${tdir}
14665
14666         # clear stats.
14667         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14668         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14669
14670         # verify mdt stats first.
14671         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14672         check_stats $SINGLEMDS "mkdir" 1
14673
14674         # clear "open" from "lfs mkdir" above
14675         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14676         touch ${testdir}/${tfile} || error "touch failed"
14677         check_stats $SINGLEMDS "open" 1
14678         check_stats $SINGLEMDS "close" 1
14679         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14680                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14681                 check_stats $SINGLEMDS "mknod" 2
14682         }
14683         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14684         check_stats $SINGLEMDS "unlink" 1
14685         rm -f ${testdir}/${tfile} || error "file remove failed"
14686         check_stats $SINGLEMDS "unlink" 2
14687
14688         # remove working dir and check mdt stats again.
14689         rmdir ${testdir} || error "rmdir failed"
14690         check_stats $SINGLEMDS "rmdir" 1
14691
14692         local testdir1=$DIR/${tdir}/stats_testdir1
14693         mkdir_on_mdt0 -p ${testdir}
14694         mkdir_on_mdt0 -p ${testdir1}
14695         touch ${testdir1}/test1
14696         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14697         check_stats $SINGLEMDS "crossdir_rename" 1
14698
14699         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14700         check_stats $SINGLEMDS "samedir_rename" 1
14701
14702         rm -rf $DIR/${tdir}
14703 }
14704 run_test 133a "Verifying MDT stats ========================================"
14705
14706 test_133b() {
14707         local res
14708
14709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14710         remote_ost_nodsh && skip "remote OST with nodsh"
14711         remote_mds_nodsh && skip "remote MDS with nodsh"
14712
14713         local testdir=$DIR/${tdir}/stats_testdir
14714
14715         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14716         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14717         touch ${testdir}/${tfile} || error "touch failed"
14718         cancel_lru_locks mdc
14719
14720         # clear stats.
14721         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14722         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14723
14724         # extra mdt stats verification.
14725         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14726         check_stats $SINGLEMDS "setattr" 1
14727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14728         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14729         then            # LU-1740
14730                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14731                 check_stats $SINGLEMDS "getattr" 1
14732         fi
14733         rm -rf $DIR/${tdir}
14734
14735         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14736         # so the check below is not reliable
14737         [ $MDSCOUNT -eq 1 ] || return 0
14738
14739         # Sleep to avoid a cached response.
14740         #define OBD_STATFS_CACHE_SECONDS 1
14741         sleep 2
14742         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14743         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14744         $LFS df || error "lfs failed"
14745         check_stats $SINGLEMDS "statfs" 1
14746
14747         # check aggregated statfs (LU-10018)
14748         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14749                 return 0
14750         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14751                 return 0
14752         sleep 2
14753         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14754         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14755         df $DIR
14756         check_stats $SINGLEMDS "statfs" 1
14757
14758         # We want to check that the client didn't send OST_STATFS to
14759         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14760         # extra care is needed here.
14761         if remote_mds; then
14762                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14763                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14764
14765                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14766                 [ "$res" ] && error "OST got STATFS"
14767         fi
14768
14769         return 0
14770 }
14771 run_test 133b "Verifying extra MDT stats =================================="
14772
14773 test_133c() {
14774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14775         remote_ost_nodsh && skip "remote OST with nodsh"
14776         remote_mds_nodsh && skip "remote MDS with nodsh"
14777
14778         local testdir=$DIR/$tdir/stats_testdir
14779
14780         test_mkdir -p $testdir
14781
14782         # verify obdfilter stats.
14783         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14784         sync
14785         cancel_lru_locks osc
14786         wait_delete_completed
14787
14788         # clear stats.
14789         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14790         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14791
14792         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14793                 error "dd failed"
14794         sync
14795         cancel_lru_locks osc
14796         check_stats ost1 "write" 1
14797
14798         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14799         check_stats ost1 "read" 1
14800
14801         > $testdir/$tfile || error "truncate failed"
14802         check_stats ost1 "punch" 1
14803
14804         rm -f $testdir/$tfile || error "file remove failed"
14805         wait_delete_completed
14806         check_stats ost1 "destroy" 1
14807
14808         rm -rf $DIR/$tdir
14809 }
14810 run_test 133c "Verifying OST stats ========================================"
14811
14812 order_2() {
14813         local value=$1
14814         local orig=$value
14815         local order=1
14816
14817         while [ $value -ge 2 ]; do
14818                 order=$((order*2))
14819                 value=$((value/2))
14820         done
14821
14822         if [ $orig -gt $order ]; then
14823                 order=$((order*2))
14824         fi
14825         echo $order
14826 }
14827
14828 size_in_KMGT() {
14829     local value=$1
14830     local size=('K' 'M' 'G' 'T');
14831     local i=0
14832     local size_string=$value
14833
14834     while [ $value -ge 1024 ]; do
14835         if [ $i -gt 3 ]; then
14836             #T is the biggest unit we get here, if that is bigger,
14837             #just return XXXT
14838             size_string=${value}T
14839             break
14840         fi
14841         value=$((value >> 10))
14842         if [ $value -lt 1024 ]; then
14843             size_string=${value}${size[$i]}
14844             break
14845         fi
14846         i=$((i + 1))
14847     done
14848
14849     echo $size_string
14850 }
14851
14852 get_rename_size() {
14853         local size=$1
14854         local context=${2:-.}
14855         local sample=$(do_facet $SINGLEMDS $LCTL \
14856                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14857                 grep -A1 $context |
14858                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14859         echo $sample
14860 }
14861
14862 test_133d() {
14863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14864         remote_ost_nodsh && skip "remote OST with nodsh"
14865         remote_mds_nodsh && skip "remote MDS with nodsh"
14866         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14867                 skip_env "MDS doesn't support rename stats"
14868
14869         local testdir1=$DIR/${tdir}/stats_testdir1
14870         local testdir2=$DIR/${tdir}/stats_testdir2
14871         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14872
14873         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14874
14875         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14876         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14877
14878         createmany -o $testdir1/test 512 || error "createmany failed"
14879
14880         # check samedir rename size
14881         mv ${testdir1}/test0 ${testdir1}/test_0
14882
14883         local testdir1_size=$(ls -l $DIR/${tdir} |
14884                 awk '/stats_testdir1/ {print $5}')
14885         local testdir2_size=$(ls -l $DIR/${tdir} |
14886                 awk '/stats_testdir2/ {print $5}')
14887
14888         testdir1_size=$(order_2 $testdir1_size)
14889         testdir2_size=$(order_2 $testdir2_size)
14890
14891         testdir1_size=$(size_in_KMGT $testdir1_size)
14892         testdir2_size=$(size_in_KMGT $testdir2_size)
14893
14894         echo "source rename dir size: ${testdir1_size}"
14895         echo "target rename dir size: ${testdir2_size}"
14896
14897         local cmd="do_facet $SINGLEMDS $LCTL "
14898         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14899
14900         eval $cmd || error "$cmd failed"
14901         local samedir=$($cmd | grep 'same_dir')
14902         local same_sample=$(get_rename_size $testdir1_size)
14903         [ -z "$samedir" ] && error "samedir_rename_size count error"
14904         [[ $same_sample -eq 1 ]] ||
14905                 error "samedir_rename_size error $same_sample"
14906         echo "Check same dir rename stats success"
14907
14908         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14909
14910         # check crossdir rename size
14911         mv ${testdir1}/test_0 ${testdir2}/test_0
14912
14913         testdir1_size=$(ls -l $DIR/${tdir} |
14914                 awk '/stats_testdir1/ {print $5}')
14915         testdir2_size=$(ls -l $DIR/${tdir} |
14916                 awk '/stats_testdir2/ {print $5}')
14917
14918         testdir1_size=$(order_2 $testdir1_size)
14919         testdir2_size=$(order_2 $testdir2_size)
14920
14921         testdir1_size=$(size_in_KMGT $testdir1_size)
14922         testdir2_size=$(size_in_KMGT $testdir2_size)
14923
14924         echo "source rename dir size: ${testdir1_size}"
14925         echo "target rename dir size: ${testdir2_size}"
14926
14927         eval $cmd || error "$cmd failed"
14928         local crossdir=$($cmd | grep 'crossdir')
14929         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14930         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14931         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14932         [[ $src_sample -eq 1 ]] ||
14933                 error "crossdir_rename_size error $src_sample"
14934         [[ $tgt_sample -eq 1 ]] ||
14935                 error "crossdir_rename_size error $tgt_sample"
14936         echo "Check cross dir rename stats success"
14937         rm -rf $DIR/${tdir}
14938 }
14939 run_test 133d "Verifying rename_stats ========================================"
14940
14941 test_133e() {
14942         remote_mds_nodsh && skip "remote MDS with nodsh"
14943         remote_ost_nodsh && skip "remote OST with nodsh"
14944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14945
14946         local testdir=$DIR/${tdir}/stats_testdir
14947         local ctr f0 f1 bs=32768 count=42 sum
14948
14949         mkdir -p ${testdir} || error "mkdir failed"
14950
14951         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14952
14953         for ctr in {write,read}_bytes; do
14954                 sync
14955                 cancel_lru_locks osc
14956
14957                 do_facet ost1 $LCTL set_param -n \
14958                         "obdfilter.*.exports.clear=clear"
14959
14960                 if [ $ctr = write_bytes ]; then
14961                         f0=/dev/zero
14962                         f1=${testdir}/${tfile}
14963                 else
14964                         f0=${testdir}/${tfile}
14965                         f1=/dev/null
14966                 fi
14967
14968                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14969                         error "dd failed"
14970                 sync
14971                 cancel_lru_locks osc
14972
14973                 sum=$(do_facet ost1 $LCTL get_param \
14974                         "obdfilter.*.exports.*.stats" |
14975                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14976                                 $1 == ctr { sum += $7 }
14977                                 END { printf("%0.0f", sum) }')
14978
14979                 if ((sum != bs * count)); then
14980                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14981                 fi
14982         done
14983
14984         rm -rf $DIR/${tdir}
14985 }
14986 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14987
14988 test_133f() {
14989         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14990                 skip "too old lustre for get_param -R ($facet_ver)"
14991
14992         # verifying readability.
14993         $LCTL get_param -R '*' &> /dev/null
14994
14995         # Verifing writability with badarea_io.
14996         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14997         local skipped_params='force_lbug|changelog_mask|daemon_file'
14998         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14999                 egrep -v "$skipped_params" |
15000                 xargs -n 1 find $proc_dirs -name |
15001                 xargs -n 1 badarea_io ||
15002                 error "client badarea_io failed"
15003
15004         # remount the FS in case writes/reads /proc break the FS
15005         cleanup || error "failed to unmount"
15006         setup || error "failed to setup"
15007 }
15008 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15009
15010 test_133g() {
15011         remote_mds_nodsh && skip "remote MDS with nodsh"
15012         remote_ost_nodsh && skip "remote OST with nodsh"
15013
15014         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15015         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15016         local facet
15017         for facet in mds1 ost1; do
15018                 local facet_ver=$(lustre_version_code $facet)
15019                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15020                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15021                 else
15022                         log "$facet: too old lustre for get_param -R"
15023                 fi
15024                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15025                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15026                                 tr -d = | egrep -v $skipped_params |
15027                                 xargs -n 1 find $proc_dirs -name |
15028                                 xargs -n 1 badarea_io" ||
15029                                         error "$facet badarea_io failed"
15030                 else
15031                         skip_noexit "$facet: too old lustre for get_param -R"
15032                 fi
15033         done
15034
15035         # remount the FS in case writes/reads /proc break the FS
15036         cleanup || error "failed to unmount"
15037         setup || error "failed to setup"
15038 }
15039 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15040
15041 test_133h() {
15042         remote_mds_nodsh && skip "remote MDS with nodsh"
15043         remote_ost_nodsh && skip "remote OST with nodsh"
15044         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15045                 skip "Need MDS version at least 2.9.54"
15046
15047         local facet
15048         for facet in client mds1 ost1; do
15049                 # Get the list of files that are missing the terminating newline
15050                 local plist=$(do_facet $facet
15051                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15052                 local ent
15053                 for ent in $plist; do
15054                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15055                                 awk -v FS='\v' -v RS='\v\v' \
15056                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15057                                         print FILENAME}'" 2>/dev/null)
15058                         [ -z $missing ] || {
15059                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15060                                 error "file does not end with newline: $facet-$ent"
15061                         }
15062                 done
15063         done
15064 }
15065 run_test 133h "Proc files should end with newlines"
15066
15067 test_134a() {
15068         remote_mds_nodsh && skip "remote MDS with nodsh"
15069         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15070                 skip "Need MDS version at least 2.7.54"
15071
15072         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15073         cancel_lru_locks mdc
15074
15075         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15076         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15077         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15078
15079         local nr=1000
15080         createmany -o $DIR/$tdir/f $nr ||
15081                 error "failed to create $nr files in $DIR/$tdir"
15082         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15083
15084         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15085         do_facet mds1 $LCTL set_param fail_loc=0x327
15086         do_facet mds1 $LCTL set_param fail_val=500
15087         touch $DIR/$tdir/m
15088
15089         echo "sleep 10 seconds ..."
15090         sleep 10
15091         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15092
15093         do_facet mds1 $LCTL set_param fail_loc=0
15094         do_facet mds1 $LCTL set_param fail_val=0
15095         [ $lck_cnt -lt $unused ] ||
15096                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15097
15098         rm $DIR/$tdir/m
15099         unlinkmany $DIR/$tdir/f $nr
15100 }
15101 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15102
15103 test_134b() {
15104         remote_mds_nodsh && skip "remote MDS with nodsh"
15105         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15106                 skip "Need MDS version at least 2.7.54"
15107
15108         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15109         cancel_lru_locks mdc
15110
15111         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15112                         ldlm.lock_reclaim_threshold_mb)
15113         # disable reclaim temporarily
15114         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15115
15116         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15117         do_facet mds1 $LCTL set_param fail_loc=0x328
15118         do_facet mds1 $LCTL set_param fail_val=500
15119
15120         $LCTL set_param debug=+trace
15121
15122         local nr=600
15123         createmany -o $DIR/$tdir/f $nr &
15124         local create_pid=$!
15125
15126         echo "Sleep $TIMEOUT seconds ..."
15127         sleep $TIMEOUT
15128         if ! ps -p $create_pid  > /dev/null 2>&1; then
15129                 do_facet mds1 $LCTL set_param fail_loc=0
15130                 do_facet mds1 $LCTL set_param fail_val=0
15131                 do_facet mds1 $LCTL set_param \
15132                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15133                 error "createmany finished incorrectly!"
15134         fi
15135         do_facet mds1 $LCTL set_param fail_loc=0
15136         do_facet mds1 $LCTL set_param fail_val=0
15137         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15138         wait $create_pid || return 1
15139
15140         unlinkmany $DIR/$tdir/f $nr
15141 }
15142 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15143
15144 test_135() {
15145         remote_mds_nodsh && skip "remote MDS with nodsh"
15146         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15147                 skip "Need MDS version at least 2.13.50"
15148         local fname
15149
15150         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15151
15152 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15153         #set only one record at plain llog
15154         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15155
15156         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15157
15158         #fill already existed plain llog each 64767
15159         #wrapping whole catalog
15160         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15161
15162         createmany -o $DIR/$tdir/$tfile_ 64700
15163         for (( i = 0; i < 64700; i = i + 2 ))
15164         do
15165                 rm $DIR/$tdir/$tfile_$i &
15166                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15167                 local pid=$!
15168                 wait $pid
15169         done
15170
15171         #waiting osp synchronization
15172         wait_delete_completed
15173 }
15174 run_test 135 "Race catalog processing"
15175
15176 test_136() {
15177         remote_mds_nodsh && skip "remote MDS with nodsh"
15178         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15179                 skip "Need MDS version at least 2.13.50"
15180         local fname
15181
15182         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15183         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15184         #set only one record at plain llog
15185 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15186         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15187
15188         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15189
15190         #fill already existed 2 plain llogs each 64767
15191         #wrapping whole catalog
15192         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15193         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15194         wait_delete_completed
15195
15196         createmany -o $DIR/$tdir/$tfile_ 10
15197         sleep 25
15198
15199         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15200         for (( i = 0; i < 10; i = i + 3 ))
15201         do
15202                 rm $DIR/$tdir/$tfile_$i &
15203                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15204                 local pid=$!
15205                 wait $pid
15206                 sleep 7
15207                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15208         done
15209
15210         #waiting osp synchronization
15211         wait_delete_completed
15212 }
15213 run_test 136 "Race catalog processing 2"
15214
15215 test_140() { #bug-17379
15216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15217
15218         test_mkdir $DIR/$tdir
15219         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15220         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15221
15222         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15223         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15224         local i=0
15225         while i=$((i + 1)); do
15226                 test_mkdir $i
15227                 cd $i || error "Changing to $i"
15228                 ln -s ../stat stat || error "Creating stat symlink"
15229                 # Read the symlink until ELOOP present,
15230                 # not LBUGing the system is considered success,
15231                 # we didn't overrun the stack.
15232                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15233                 if [ $ret -ne 0 ]; then
15234                         if [ $ret -eq 40 ]; then
15235                                 break  # -ELOOP
15236                         else
15237                                 error "Open stat symlink"
15238                                         return
15239                         fi
15240                 fi
15241         done
15242         i=$((i - 1))
15243         echo "The symlink depth = $i"
15244         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15245                 error "Invalid symlink depth"
15246
15247         # Test recursive symlink
15248         ln -s symlink_self symlink_self
15249         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15250         echo "open symlink_self returns $ret"
15251         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15252 }
15253 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15254
15255 test_150a() {
15256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15257
15258         local TF="$TMP/$tfile"
15259
15260         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15261         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15262         cp $TF $DIR/$tfile
15263         cancel_lru_locks $OSC
15264         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15265         remount_client $MOUNT
15266         df -P $MOUNT
15267         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15268
15269         $TRUNCATE $TF 6000
15270         $TRUNCATE $DIR/$tfile 6000
15271         cancel_lru_locks $OSC
15272         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15273
15274         echo "12345" >>$TF
15275         echo "12345" >>$DIR/$tfile
15276         cancel_lru_locks $OSC
15277         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15278
15279         echo "12345" >>$TF
15280         echo "12345" >>$DIR/$tfile
15281         cancel_lru_locks $OSC
15282         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15283 }
15284 run_test 150a "truncate/append tests"
15285
15286 test_150b() {
15287         check_set_fallocate_or_skip
15288         local out
15289
15290         touch $DIR/$tfile
15291         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15292         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15293                 skip_eopnotsupp "$out|check_fallocate failed"
15294 }
15295 run_test 150b "Verify fallocate (prealloc) functionality"
15296
15297 test_150bb() {
15298         check_set_fallocate_or_skip
15299
15300         touch $DIR/$tfile
15301         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15302         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15303         > $DIR/$tfile
15304         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15305         # precomputed md5sum for 20MB of zeroes
15306         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15307         local sum=($(md5sum $DIR/$tfile))
15308
15309         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15310
15311         check_set_fallocate 1
15312
15313         > $DIR/$tfile
15314         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15315         sum=($(md5sum $DIR/$tfile))
15316
15317         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15318 }
15319 run_test 150bb "Verify fallocate modes both zero space"
15320
15321 test_150c() {
15322         check_set_fallocate_or_skip
15323         local striping="-c2"
15324
15325         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15326         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15327         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15328         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15329         local want=$((OSTCOUNT * 1048576))
15330
15331         # Must allocate all requested space, not more than 5% extra
15332         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15333                 error "bytes $bytes is not $want"
15334
15335         rm -f $DIR/$tfile
15336
15337         echo "verify fallocate on PFL file"
15338
15339         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15340
15341         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15342                 error "Create $DIR/$tfile failed"
15343         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15344         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15345         want=$((512 * 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 150c "Verify fallocate Size and Blocks"
15352
15353 test_150d() {
15354         check_set_fallocate_or_skip
15355         local striping="-c2"
15356
15357         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15358
15359         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15360         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15361                 error "setstripe failed"
15362         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15363         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15364         local want=$((OSTCOUNT * 1048576))
15365
15366         # Must allocate all requested space, not more than 5% extra
15367         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15368                 error "bytes $bytes is not $want"
15369 }
15370 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15371
15372 test_150e() {
15373         check_set_fallocate_or_skip
15374
15375         echo "df before:"
15376         $LFS df
15377         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15378         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15379                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15380
15381         # Find OST with Minimum Size
15382         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15383                        sort -un | head -1)
15384
15385         # Get 100MB per OST of the available space to reduce run time
15386         # else 60% of the available space if we are running SLOW tests
15387         if [ $SLOW == "no" ]; then
15388                 local space=$((1024 * 100 * OSTCOUNT))
15389         else
15390                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15391         fi
15392
15393         fallocate -l${space}k $DIR/$tfile ||
15394                 error "fallocate ${space}k $DIR/$tfile failed"
15395         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15396
15397         # get size immediately after fallocate. This should be correctly
15398         # updated
15399         local size=$(stat -c '%s' $DIR/$tfile)
15400         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15401
15402         # Sleep for a while for statfs to get updated. And not pull from cache.
15403         sleep 2
15404
15405         echo "df after fallocate:"
15406         $LFS df
15407
15408         (( size / 1024 == space )) || error "size $size != requested $space"
15409         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15410                 error "used $used < space $space"
15411
15412         rm $DIR/$tfile || error "rm failed"
15413         sync
15414         wait_delete_completed
15415
15416         echo "df after unlink:"
15417         $LFS df
15418 }
15419 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15420
15421 test_150f() {
15422         local size
15423         local blocks
15424         local want_size_before=20480 # in bytes
15425         local want_blocks_before=40 # 512 sized blocks
15426         local want_blocks_after=24  # 512 sized blocks
15427         local length=$(((want_blocks_before - want_blocks_after) * 512))
15428
15429         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15430                 skip "need at least 2.14.0 for fallocate punch"
15431
15432         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15433                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15434         fi
15435
15436         check_set_fallocate_or_skip
15437         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15438
15439         [[ "x$DOM" == "xyes" ]] &&
15440                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15441
15442         echo "Verify fallocate punch: Range within the file range"
15443         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15444                 error "dd failed for bs 4096 and count 5"
15445
15446         # Call fallocate with punch range which is within the file range
15447         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15448                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15449         # client must see changes immediately after fallocate
15450         size=$(stat -c '%s' $DIR/$tfile)
15451         blocks=$(stat -c '%b' $DIR/$tfile)
15452
15453         # Verify punch worked.
15454         (( blocks == want_blocks_after )) ||
15455                 error "punch failed: blocks $blocks != $want_blocks_after"
15456
15457         (( size == want_size_before )) ||
15458                 error "punch failed: size $size != $want_size_before"
15459
15460         # Verify there is hole in file
15461         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15462         # precomputed md5sum
15463         local expect="4a9a834a2db02452929c0a348273b4aa"
15464
15465         cksum=($(md5sum $DIR/$tfile))
15466         [[ "${cksum[0]}" == "$expect" ]] ||
15467                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15468
15469         # Start second sub-case for fallocate punch.
15470         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15471         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15472                 error "dd failed for bs 4096 and count 5"
15473
15474         # Punch range less than block size will have no change in block count
15475         want_blocks_after=40  # 512 sized blocks
15476
15477         # Punch overlaps two blocks and less than blocksize
15478         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15479                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15480         size=$(stat -c '%s' $DIR/$tfile)
15481         blocks=$(stat -c '%b' $DIR/$tfile)
15482
15483         # Verify punch worked.
15484         (( blocks == want_blocks_after )) ||
15485                 error "punch failed: blocks $blocks != $want_blocks_after"
15486
15487         (( size == want_size_before )) ||
15488                 error "punch failed: size $size != $want_size_before"
15489
15490         # Verify if range is really zero'ed out. We expect Zeros.
15491         # precomputed md5sum
15492         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15493         cksum=($(md5sum $DIR/$tfile))
15494         [[ "${cksum[0]}" == "$expect" ]] ||
15495                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15496 }
15497 run_test 150f "Verify fallocate punch functionality"
15498
15499 test_150g() {
15500         local space
15501         local size
15502         local blocks
15503         local blocks_after
15504         local size_after
15505         local BS=4096 # Block size in bytes
15506
15507         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15508                 skip "need at least 2.14.0 for fallocate punch"
15509
15510         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15511                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15512         fi
15513
15514         check_set_fallocate_or_skip
15515         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15516
15517         if [[ "x$DOM" == "xyes" ]]; then
15518                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15519                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15520         else
15521                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15522                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15523         fi
15524
15525         # Get 100MB per OST of the available space to reduce run time
15526         # else 60% of the available space if we are running SLOW tests
15527         if [ $SLOW == "no" ]; then
15528                 space=$((1024 * 100 * OSTCOUNT))
15529         else
15530                 # Find OST with Minimum Size
15531                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15532                         sort -un | head -1)
15533                 echo "min size OST: $space"
15534                 space=$(((space * 60)/100 * OSTCOUNT))
15535         fi
15536         # space in 1k units, round to 4k blocks
15537         local blkcount=$((space * 1024 / $BS))
15538
15539         echo "Verify fallocate punch: Very large Range"
15540         fallocate -l${space}k $DIR/$tfile ||
15541                 error "fallocate ${space}k $DIR/$tfile failed"
15542         # write 1M at the end, start and in the middle
15543         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15544                 error "dd failed: bs $BS count 256"
15545         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15546                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15547         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15548                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15549
15550         # Gather stats.
15551         size=$(stat -c '%s' $DIR/$tfile)
15552
15553         # gather punch length.
15554         local punch_size=$((size - (BS * 2)))
15555
15556         echo "punch_size = $punch_size"
15557         echo "size - punch_size: $((size - punch_size))"
15558         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15559
15560         # Call fallocate to punch all except 2 blocks. We leave the
15561         # first and the last block
15562         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15563         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15564                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15565
15566         size_after=$(stat -c '%s' $DIR/$tfile)
15567         blocks_after=$(stat -c '%b' $DIR/$tfile)
15568
15569         # Verify punch worked.
15570         # Size should be kept
15571         (( size == size_after )) ||
15572                 error "punch failed: size $size != $size_after"
15573
15574         # two 4k data blocks to remain plus possible 1 extra extent block
15575         (( blocks_after <= ((BS / 512) * 3) )) ||
15576                 error "too many blocks remains: $blocks_after"
15577
15578         # Verify that file has hole between the first and the last blocks
15579         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15580         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15581
15582         echo "Hole at [$hole_start, $hole_end)"
15583         (( hole_start == BS )) ||
15584                 error "no hole at offset $BS after punch"
15585
15586         (( hole_end == BS + punch_size )) ||
15587                 error "data at offset $hole_end < $((BS + punch_size))"
15588 }
15589 run_test 150g "Verify fallocate punch on large range"
15590
15591 test_150h() {
15592         local file=$DIR/$tfile
15593         local size
15594
15595         check_set_fallocate_or_skip
15596         statx_supported || skip_env "Test must be statx() syscall supported"
15597
15598         # fallocate() does not update the size information on the MDT
15599         fallocate -l 16K $file || error "failed to fallocate $file"
15600         cancel_lru_locks $OSC
15601         # STATX with cached-always mode will not send glimpse RPCs to OST,
15602         # it uses the caching attrs on the client side as much as possible.
15603         size=$($STATX --cached=always -c %s $file)
15604         [ $size == 16384 ] ||
15605                 error "size after fallocate() is $size, expected 16384"
15606 }
15607 run_test 150h "Verify extend fallocate updates the file size"
15608
15609 #LU-2902 roc_hit was not able to read all values from lproc
15610 function roc_hit_init() {
15611         local list=$(comma_list $(osts_nodes))
15612         local dir=$DIR/$tdir-check
15613         local file=$dir/$tfile
15614         local BEFORE
15615         local AFTER
15616         local idx
15617
15618         test_mkdir $dir
15619         #use setstripe to do a write to every ost
15620         for i in $(seq 0 $((OSTCOUNT-1))); do
15621                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15622                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15623                 idx=$(printf %04x $i)
15624                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15625                         awk '$1 == "cache_access" {sum += $7}
15626                                 END { printf("%0.0f", sum) }')
15627
15628                 cancel_lru_locks osc
15629                 cat $file >/dev/null
15630
15631                 AFTER=$(get_osd_param $list *OST*$idx stats |
15632                         awk '$1 == "cache_access" {sum += $7}
15633                                 END { printf("%0.0f", sum) }')
15634
15635                 echo BEFORE:$BEFORE AFTER:$AFTER
15636                 if ! let "AFTER - BEFORE == 4"; then
15637                         rm -rf $dir
15638                         error "roc_hit is not safe to use"
15639                 fi
15640                 rm $file
15641         done
15642
15643         rm -rf $dir
15644 }
15645
15646 function roc_hit() {
15647         local list=$(comma_list $(osts_nodes))
15648         echo $(get_osd_param $list '' stats |
15649                 awk '$1 == "cache_hit" {sum += $7}
15650                         END { printf("%0.0f", sum) }')
15651 }
15652
15653 function set_cache() {
15654         local on=1
15655
15656         if [ "$2" == "off" ]; then
15657                 on=0;
15658         fi
15659         local list=$(comma_list $(osts_nodes))
15660         set_osd_param $list '' $1_cache_enable $on
15661
15662         cancel_lru_locks osc
15663 }
15664
15665 test_151() {
15666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15667         remote_ost_nodsh && skip "remote OST with nodsh"
15668
15669         local CPAGES=3
15670         local list=$(comma_list $(osts_nodes))
15671
15672         # check whether obdfilter is cache capable at all
15673         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15674                 skip "not cache-capable obdfilter"
15675         fi
15676
15677         # check cache is enabled on all obdfilters
15678         if get_osd_param $list '' read_cache_enable | grep 0; then
15679                 skip "oss cache is disabled"
15680         fi
15681
15682         set_osd_param $list '' writethrough_cache_enable 1
15683
15684         # check write cache is enabled on all obdfilters
15685         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15686                 skip "oss write cache is NOT enabled"
15687         fi
15688
15689         roc_hit_init
15690
15691         #define OBD_FAIL_OBD_NO_LRU  0x609
15692         do_nodes $list $LCTL set_param fail_loc=0x609
15693
15694         # pages should be in the case right after write
15695         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15696                 error "dd failed"
15697
15698         local BEFORE=$(roc_hit)
15699         cancel_lru_locks osc
15700         cat $DIR/$tfile >/dev/null
15701         local AFTER=$(roc_hit)
15702
15703         do_nodes $list $LCTL set_param fail_loc=0
15704
15705         if ! let "AFTER - BEFORE == CPAGES"; then
15706                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15707         fi
15708
15709         cancel_lru_locks osc
15710         # invalidates OST cache
15711         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15712         set_osd_param $list '' read_cache_enable 0
15713         cat $DIR/$tfile >/dev/null
15714
15715         # now data shouldn't be found in the cache
15716         BEFORE=$(roc_hit)
15717         cancel_lru_locks osc
15718         cat $DIR/$tfile >/dev/null
15719         AFTER=$(roc_hit)
15720         if let "AFTER - BEFORE != 0"; then
15721                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15722         fi
15723
15724         set_osd_param $list '' read_cache_enable 1
15725         rm -f $DIR/$tfile
15726 }
15727 run_test 151 "test cache on oss and controls ==============================="
15728
15729 test_152() {
15730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15731
15732         local TF="$TMP/$tfile"
15733
15734         # simulate ENOMEM during write
15735 #define OBD_FAIL_OST_NOMEM      0x226
15736         lctl set_param fail_loc=0x80000226
15737         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15738         cp $TF $DIR/$tfile
15739         sync || error "sync failed"
15740         lctl set_param fail_loc=0
15741
15742         # discard client's cache
15743         cancel_lru_locks osc
15744
15745         # simulate ENOMEM during read
15746         lctl set_param fail_loc=0x80000226
15747         cmp $TF $DIR/$tfile || error "cmp failed"
15748         lctl set_param fail_loc=0
15749
15750         rm -f $TF
15751 }
15752 run_test 152 "test read/write with enomem ============================"
15753
15754 test_153() {
15755         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15756 }
15757 run_test 153 "test if fdatasync does not crash ======================="
15758
15759 dot_lustre_fid_permission_check() {
15760         local fid=$1
15761         local ffid=$MOUNT/.lustre/fid/$fid
15762         local test_dir=$2
15763
15764         echo "stat fid $fid"
15765         stat $ffid || error "stat $ffid failed."
15766         echo "touch fid $fid"
15767         touch $ffid || error "touch $ffid failed."
15768         echo "write to fid $fid"
15769         cat /etc/hosts > $ffid || error "write $ffid failed."
15770         echo "read fid $fid"
15771         diff /etc/hosts $ffid || error "read $ffid failed."
15772         echo "append write to fid $fid"
15773         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15774         echo "rename fid $fid"
15775         mv $ffid $test_dir/$tfile.1 &&
15776                 error "rename $ffid to $tfile.1 should fail."
15777         touch $test_dir/$tfile.1
15778         mv $test_dir/$tfile.1 $ffid &&
15779                 error "rename $tfile.1 to $ffid should fail."
15780         rm -f $test_dir/$tfile.1
15781         echo "truncate fid $fid"
15782         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15783         echo "link fid $fid"
15784         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15785         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15786                 echo "setfacl fid $fid"
15787                 setfacl -R -m u:$USER0:rwx $ffid ||
15788                         error "setfacl $ffid failed"
15789                 echo "getfacl fid $fid"
15790                 getfacl $ffid || error "getfacl $ffid failed."
15791         fi
15792         echo "unlink fid $fid"
15793         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15794         echo "mknod fid $fid"
15795         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15796
15797         fid=[0xf00000400:0x1:0x0]
15798         ffid=$MOUNT/.lustre/fid/$fid
15799
15800         echo "stat non-exist fid $fid"
15801         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15802         echo "write to non-exist fid $fid"
15803         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15804         echo "link new fid $fid"
15805         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15806
15807         mkdir -p $test_dir/$tdir
15808         touch $test_dir/$tdir/$tfile
15809         fid=$($LFS path2fid $test_dir/$tdir)
15810         rc=$?
15811         [ $rc -ne 0 ] &&
15812                 error "error: could not get fid for $test_dir/$dir/$tfile."
15813
15814         ffid=$MOUNT/.lustre/fid/$fid
15815
15816         echo "ls $fid"
15817         ls $ffid || error "ls $ffid failed."
15818         echo "touch $fid/$tfile.1"
15819         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15820
15821         echo "touch $MOUNT/.lustre/fid/$tfile"
15822         touch $MOUNT/.lustre/fid/$tfile && \
15823                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15824
15825         echo "setxattr to $MOUNT/.lustre/fid"
15826         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15827
15828         echo "listxattr for $MOUNT/.lustre/fid"
15829         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15830
15831         echo "delxattr from $MOUNT/.lustre/fid"
15832         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15833
15834         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15835         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15836                 error "touch invalid fid should fail."
15837
15838         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15839         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15840                 error "touch non-normal fid should fail."
15841
15842         echo "rename $tdir to $MOUNT/.lustre/fid"
15843         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15844                 error "rename to $MOUNT/.lustre/fid should fail."
15845
15846         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15847         then            # LU-3547
15848                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15849                 local new_obf_mode=777
15850
15851                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15852                 chmod $new_obf_mode $DIR/.lustre/fid ||
15853                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15854
15855                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15856                 [ $obf_mode -eq $new_obf_mode ] ||
15857                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15858
15859                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15860                 chmod $old_obf_mode $DIR/.lustre/fid ||
15861                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15862         fi
15863
15864         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15865         fid=$($LFS path2fid $test_dir/$tfile-2)
15866
15867         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15868         then # LU-5424
15869                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15870                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15871                         error "create lov data thru .lustre failed"
15872         fi
15873         echo "cp /etc/passwd $test_dir/$tfile-2"
15874         cp /etc/passwd $test_dir/$tfile-2 ||
15875                 error "copy to $test_dir/$tfile-2 failed."
15876         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15877         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15878                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15879
15880         rm -rf $test_dir/tfile.lnk
15881         rm -rf $test_dir/$tfile-2
15882 }
15883
15884 test_154A() {
15885         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15886                 skip "Need MDS version at least 2.4.1"
15887
15888         local tf=$DIR/$tfile
15889         touch $tf
15890
15891         local fid=$($LFS path2fid $tf)
15892         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15893
15894         # check that we get the same pathname back
15895         local rootpath
15896         local found
15897         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15898                 echo "$rootpath $fid"
15899                 found=$($LFS fid2path $rootpath "$fid")
15900                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15901                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15902         done
15903
15904         # check wrong root path format
15905         rootpath=$MOUNT"_wrong"
15906         found=$($LFS fid2path $rootpath "$fid")
15907         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15908 }
15909 run_test 154A "lfs path2fid and fid2path basic checks"
15910
15911 test_154B() {
15912         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15913                 skip "Need MDS version at least 2.4.1"
15914
15915         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15916         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15917         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15918         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15919
15920         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15921         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15922
15923         # check that we get the same pathname
15924         echo "PFID: $PFID, name: $name"
15925         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15926         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15927         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15928                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15929
15930         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15931 }
15932 run_test 154B "verify the ll_decode_linkea tool"
15933
15934 test_154a() {
15935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15936         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15937         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15938                 skip "Need MDS version at least 2.2.51"
15939         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15940
15941         cp /etc/hosts $DIR/$tfile
15942
15943         fid=$($LFS path2fid $DIR/$tfile)
15944         rc=$?
15945         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15946
15947         dot_lustre_fid_permission_check "$fid" $DIR ||
15948                 error "dot lustre permission check $fid failed"
15949
15950         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15951
15952         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15953
15954         touch $MOUNT/.lustre/file &&
15955                 error "creation is not allowed under .lustre"
15956
15957         mkdir $MOUNT/.lustre/dir &&
15958                 error "mkdir is not allowed under .lustre"
15959
15960         rm -rf $DIR/$tfile
15961 }
15962 run_test 154a "Open-by-FID"
15963
15964 test_154b() {
15965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15966         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15967         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15968         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15969                 skip "Need MDS version at least 2.2.51"
15970
15971         local remote_dir=$DIR/$tdir/remote_dir
15972         local MDTIDX=1
15973         local rc=0
15974
15975         mkdir -p $DIR/$tdir
15976         $LFS mkdir -i $MDTIDX $remote_dir ||
15977                 error "create remote directory failed"
15978
15979         cp /etc/hosts $remote_dir/$tfile
15980
15981         fid=$($LFS path2fid $remote_dir/$tfile)
15982         rc=$?
15983         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15984
15985         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15986                 error "dot lustre permission check $fid failed"
15987         rm -rf $DIR/$tdir
15988 }
15989 run_test 154b "Open-by-FID for remote directory"
15990
15991 test_154c() {
15992         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15993                 skip "Need MDS version at least 2.4.1"
15994
15995         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15996         local FID1=$($LFS path2fid $DIR/$tfile.1)
15997         local FID2=$($LFS path2fid $DIR/$tfile.2)
15998         local FID3=$($LFS path2fid $DIR/$tfile.3)
15999
16000         local N=1
16001         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16002                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16003                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16004                 local want=FID$N
16005                 [ "$FID" = "${!want}" ] ||
16006                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16007                 N=$((N + 1))
16008         done
16009
16010         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16011         do
16012                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16013                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16014                 N=$((N + 1))
16015         done
16016 }
16017 run_test 154c "lfs path2fid and fid2path multiple arguments"
16018
16019 test_154d() {
16020         remote_mds_nodsh && skip "remote MDS with nodsh"
16021         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16022                 skip "Need MDS version at least 2.5.53"
16023
16024         if remote_mds; then
16025                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16026         else
16027                 nid="0@lo"
16028         fi
16029         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16030         local fd
16031         local cmd
16032
16033         rm -f $DIR/$tfile
16034         touch $DIR/$tfile
16035
16036         local fid=$($LFS path2fid $DIR/$tfile)
16037         # Open the file
16038         fd=$(free_fd)
16039         cmd="exec $fd<$DIR/$tfile"
16040         eval $cmd
16041         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16042         echo "$fid_list" | grep "$fid"
16043         rc=$?
16044
16045         cmd="exec $fd>/dev/null"
16046         eval $cmd
16047         if [ $rc -ne 0 ]; then
16048                 error "FID $fid not found in open files list $fid_list"
16049         fi
16050 }
16051 run_test 154d "Verify open file fid"
16052
16053 test_154e()
16054 {
16055         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16056                 skip "Need MDS version at least 2.6.50"
16057
16058         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16059                 error ".lustre returned by readdir"
16060         fi
16061 }
16062 run_test 154e ".lustre is not returned by readdir"
16063
16064 test_154f() {
16065         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16066
16067         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16068         mkdir_on_mdt0 $DIR/$tdir
16069         # test dirs inherit from its stripe
16070         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16071         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16072         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16073         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16074         touch $DIR/f
16075
16076         # get fid of parents
16077         local FID0=$($LFS path2fid $DIR/$tdir)
16078         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16079         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16080         local FID3=$($LFS path2fid $DIR)
16081
16082         # check that path2fid --parents returns expected <parent_fid>/name
16083         # 1) test for a directory (single parent)
16084         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16085         [ "$parent" == "$FID0/foo1" ] ||
16086                 error "expected parent: $FID0/foo1, got: $parent"
16087
16088         # 2) test for a file with nlink > 1 (multiple parents)
16089         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16090         echo "$parent" | grep -F "$FID1/$tfile" ||
16091                 error "$FID1/$tfile not returned in parent list"
16092         echo "$parent" | grep -F "$FID2/link" ||
16093                 error "$FID2/link not returned in parent list"
16094
16095         # 3) get parent by fid
16096         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16097         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16098         echo "$parent" | grep -F "$FID1/$tfile" ||
16099                 error "$FID1/$tfile not returned in parent list (by fid)"
16100         echo "$parent" | grep -F "$FID2/link" ||
16101                 error "$FID2/link not returned in parent list (by fid)"
16102
16103         # 4) test for entry in root directory
16104         parent=$($LFS path2fid --parents $DIR/f)
16105         echo "$parent" | grep -F "$FID3/f" ||
16106                 error "$FID3/f not returned in parent list"
16107
16108         # 5) test it on root directory
16109         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16110                 error "$MOUNT should not have parents"
16111
16112         # enable xattr caching and check that linkea is correctly updated
16113         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16114         save_lustre_params client "llite.*.xattr_cache" > $save
16115         lctl set_param llite.*.xattr_cache 1
16116
16117         # 6.1) linkea update on rename
16118         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16119
16120         # get parents by fid
16121         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16122         # foo1 should no longer be returned in parent list
16123         echo "$parent" | grep -F "$FID1" &&
16124                 error "$FID1 should no longer be in parent list"
16125         # the new path should appear
16126         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16127                 error "$FID2/$tfile.moved is not in parent list"
16128
16129         # 6.2) linkea update on unlink
16130         rm -f $DIR/$tdir/foo2/link
16131         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16132         # foo2/link should no longer be returned in parent list
16133         echo "$parent" | grep -F "$FID2/link" &&
16134                 error "$FID2/link should no longer be in parent list"
16135         true
16136
16137         rm -f $DIR/f
16138         restore_lustre_params < $save
16139         rm -f $save
16140 }
16141 run_test 154f "get parent fids by reading link ea"
16142
16143 test_154g()
16144 {
16145         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16146            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16147                 skip "Need MDS version at least 2.6.92"
16148
16149         mkdir_on_mdt0 $DIR/$tdir
16150         llapi_fid_test -d $DIR/$tdir
16151 }
16152 run_test 154g "various llapi FID tests"
16153
16154 test_155_small_load() {
16155     local temp=$TMP/$tfile
16156     local file=$DIR/$tfile
16157
16158     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16159         error "dd of=$temp bs=6096 count=1 failed"
16160     cp $temp $file
16161     cancel_lru_locks $OSC
16162     cmp $temp $file || error "$temp $file differ"
16163
16164     $TRUNCATE $temp 6000
16165     $TRUNCATE $file 6000
16166     cmp $temp $file || error "$temp $file differ (truncate1)"
16167
16168     echo "12345" >>$temp
16169     echo "12345" >>$file
16170     cmp $temp $file || error "$temp $file differ (append1)"
16171
16172     echo "12345" >>$temp
16173     echo "12345" >>$file
16174     cmp $temp $file || error "$temp $file differ (append2)"
16175
16176     rm -f $temp $file
16177     true
16178 }
16179
16180 test_155_big_load() {
16181         remote_ost_nodsh && skip "remote OST with nodsh"
16182
16183         local temp=$TMP/$tfile
16184         local file=$DIR/$tfile
16185
16186         free_min_max
16187         local cache_size=$(do_facet ost$((MAXI+1)) \
16188                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16189
16190         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16191         # pre-set value
16192         if [ -z "$cache_size" ]; then
16193                 cache_size=256
16194         fi
16195         local large_file_size=$((cache_size * 2))
16196
16197         echo "OSS cache size: $cache_size KB"
16198         echo "Large file size: $large_file_size KB"
16199
16200         [ $MAXV -le $large_file_size ] &&
16201                 skip_env "max available OST size needs > $large_file_size KB"
16202
16203         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16204
16205         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16206                 error "dd of=$temp bs=$large_file_size count=1k failed"
16207         cp $temp $file
16208         ls -lh $temp $file
16209         cancel_lru_locks osc
16210         cmp $temp $file || error "$temp $file differ"
16211
16212         rm -f $temp $file
16213         true
16214 }
16215
16216 save_writethrough() {
16217         local facets=$(get_facets OST)
16218
16219         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16220 }
16221
16222 test_155a() {
16223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16224
16225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16226
16227         save_writethrough $p
16228
16229         set_cache read on
16230         set_cache writethrough on
16231         test_155_small_load
16232         restore_lustre_params < $p
16233         rm -f $p
16234 }
16235 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16236
16237 test_155b() {
16238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16239
16240         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16241
16242         save_writethrough $p
16243
16244         set_cache read on
16245         set_cache writethrough off
16246         test_155_small_load
16247         restore_lustre_params < $p
16248         rm -f $p
16249 }
16250 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16251
16252 test_155c() {
16253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16254
16255         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16256
16257         save_writethrough $p
16258
16259         set_cache read off
16260         set_cache writethrough on
16261         test_155_small_load
16262         restore_lustre_params < $p
16263         rm -f $p
16264 }
16265 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16266
16267 test_155d() {
16268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16269
16270         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16271
16272         save_writethrough $p
16273
16274         set_cache read off
16275         set_cache writethrough off
16276         test_155_small_load
16277         restore_lustre_params < $p
16278         rm -f $p
16279 }
16280 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16281
16282 test_155e() {
16283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16284
16285         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16286
16287         save_writethrough $p
16288
16289         set_cache read on
16290         set_cache writethrough on
16291         test_155_big_load
16292         restore_lustre_params < $p
16293         rm -f $p
16294 }
16295 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16296
16297 test_155f() {
16298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16299
16300         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16301
16302         save_writethrough $p
16303
16304         set_cache read on
16305         set_cache writethrough off
16306         test_155_big_load
16307         restore_lustre_params < $p
16308         rm -f $p
16309 }
16310 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16311
16312 test_155g() {
16313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16314
16315         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16316
16317         save_writethrough $p
16318
16319         set_cache read off
16320         set_cache writethrough on
16321         test_155_big_load
16322         restore_lustre_params < $p
16323         rm -f $p
16324 }
16325 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16326
16327 test_155h() {
16328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16329
16330         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16331
16332         save_writethrough $p
16333
16334         set_cache read off
16335         set_cache writethrough off
16336         test_155_big_load
16337         restore_lustre_params < $p
16338         rm -f $p
16339 }
16340 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16341
16342 test_156() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344         remote_ost_nodsh && skip "remote OST with nodsh"
16345         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16346                 skip "stats not implemented on old servers"
16347         [ "$ost1_FSTYPE" = "zfs" ] &&
16348                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16349
16350         local CPAGES=3
16351         local BEFORE
16352         local AFTER
16353         local file="$DIR/$tfile"
16354         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16355
16356         save_writethrough $p
16357         roc_hit_init
16358
16359         log "Turn on read and write cache"
16360         set_cache read on
16361         set_cache writethrough on
16362
16363         log "Write data and read it back."
16364         log "Read should be satisfied from the cache."
16365         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16366         BEFORE=$(roc_hit)
16367         cancel_lru_locks osc
16368         cat $file >/dev/null
16369         AFTER=$(roc_hit)
16370         if ! let "AFTER - BEFORE == CPAGES"; then
16371                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16372         else
16373                 log "cache hits: before: $BEFORE, after: $AFTER"
16374         fi
16375
16376         log "Read again; it should be satisfied from the cache."
16377         BEFORE=$AFTER
16378         cancel_lru_locks osc
16379         cat $file >/dev/null
16380         AFTER=$(roc_hit)
16381         if ! let "AFTER - BEFORE == CPAGES"; then
16382                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16383         else
16384                 log "cache hits:: before: $BEFORE, after: $AFTER"
16385         fi
16386
16387         log "Turn off the read cache and turn on the write cache"
16388         set_cache read off
16389         set_cache writethrough on
16390
16391         log "Read again; it should be satisfied from the cache."
16392         BEFORE=$(roc_hit)
16393         cancel_lru_locks osc
16394         cat $file >/dev/null
16395         AFTER=$(roc_hit)
16396         if ! let "AFTER - BEFORE == CPAGES"; then
16397                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16398         else
16399                 log "cache hits:: before: $BEFORE, after: $AFTER"
16400         fi
16401
16402         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16403                 # > 2.12.56 uses pagecache if cached
16404                 log "Read again; it should not be satisfied from the cache."
16405                 BEFORE=$AFTER
16406                 cancel_lru_locks osc
16407                 cat $file >/dev/null
16408                 AFTER=$(roc_hit)
16409                 if ! let "AFTER - BEFORE == 0"; then
16410                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16411                 else
16412                         log "cache hits:: before: $BEFORE, after: $AFTER"
16413                 fi
16414         fi
16415
16416         log "Write data and read it back."
16417         log "Read should be satisfied from the cache."
16418         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16419         BEFORE=$(roc_hit)
16420         cancel_lru_locks osc
16421         cat $file >/dev/null
16422         AFTER=$(roc_hit)
16423         if ! let "AFTER - BEFORE == CPAGES"; then
16424                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16425         else
16426                 log "cache hits:: before: $BEFORE, after: $AFTER"
16427         fi
16428
16429         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16430                 # > 2.12.56 uses pagecache if cached
16431                 log "Read again; it should not be satisfied from the cache."
16432                 BEFORE=$AFTER
16433                 cancel_lru_locks osc
16434                 cat $file >/dev/null
16435                 AFTER=$(roc_hit)
16436                 if ! let "AFTER - BEFORE == 0"; then
16437                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16438                 else
16439                         log "cache hits:: before: $BEFORE, after: $AFTER"
16440                 fi
16441         fi
16442
16443         log "Turn off read and write cache"
16444         set_cache read off
16445         set_cache writethrough off
16446
16447         log "Write data and read it back"
16448         log "It should not be satisfied from the cache."
16449         rm -f $file
16450         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16451         cancel_lru_locks osc
16452         BEFORE=$(roc_hit)
16453         cat $file >/dev/null
16454         AFTER=$(roc_hit)
16455         if ! let "AFTER - BEFORE == 0"; then
16456                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16457         else
16458                 log "cache hits:: before: $BEFORE, after: $AFTER"
16459         fi
16460
16461         log "Turn on the read cache and turn off the write cache"
16462         set_cache read on
16463         set_cache writethrough off
16464
16465         log "Write data and read it back"
16466         log "It should not be satisfied from the cache."
16467         rm -f $file
16468         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16469         BEFORE=$(roc_hit)
16470         cancel_lru_locks osc
16471         cat $file >/dev/null
16472         AFTER=$(roc_hit)
16473         if ! let "AFTER - BEFORE == 0"; then
16474                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16475         else
16476                 log "cache hits:: before: $BEFORE, after: $AFTER"
16477         fi
16478
16479         log "Read again; it should be satisfied from the cache."
16480         BEFORE=$(roc_hit)
16481         cancel_lru_locks osc
16482         cat $file >/dev/null
16483         AFTER=$(roc_hit)
16484         if ! let "AFTER - BEFORE == CPAGES"; then
16485                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16486         else
16487                 log "cache hits:: before: $BEFORE, after: $AFTER"
16488         fi
16489
16490         restore_lustre_params < $p
16491         rm -f $p $file
16492 }
16493 run_test 156 "Verification of tunables"
16494
16495 test_160a() {
16496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16497         remote_mds_nodsh && skip "remote MDS with nodsh"
16498         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16499                 skip "Need MDS version at least 2.2.0"
16500
16501         changelog_register || error "changelog_register failed"
16502         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16503         changelog_users $SINGLEMDS | grep -q $cl_user ||
16504                 error "User $cl_user not found in changelog_users"
16505
16506         mkdir_on_mdt0 $DIR/$tdir
16507
16508         # change something
16509         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16510         changelog_clear 0 || error "changelog_clear failed"
16511         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16512         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16513         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16514         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16515         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16516         rm $DIR/$tdir/pics/desktop.jpg
16517
16518         echo "verifying changelog mask"
16519         changelog_chmask "-MKDIR"
16520         changelog_chmask "-CLOSE"
16521
16522         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16523         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16524
16525         changelog_chmask "+MKDIR"
16526         changelog_chmask "+CLOSE"
16527
16528         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16529         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16530
16531         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16532         CLOSES=$(changelog_dump | grep -c "CLOSE")
16533         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16534         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16535
16536         # verify contents
16537         echo "verifying target fid"
16538         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16539         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16540         [ "$fidc" == "$fidf" ] ||
16541                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16542         echo "verifying parent fid"
16543         # The FID returned from the Changelog may be the directory shard on
16544         # a different MDT, and not the FID returned by path2fid on the parent.
16545         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16546         # since this is what will matter when recreating this file in the tree.
16547         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16548         local pathp=$($LFS fid2path $MOUNT "$fidp")
16549         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16550                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16551
16552         echo "getting records for $cl_user"
16553         changelog_users $SINGLEMDS
16554         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16555         local nclr=3
16556         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16557                 error "changelog_clear failed"
16558         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16559         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16560         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16561                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16562
16563         local min0_rec=$(changelog_users $SINGLEMDS |
16564                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16565         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16566                           awk '{ print $1; exit; }')
16567
16568         changelog_dump | tail -n 5
16569         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16570         [ $first_rec == $((min0_rec + 1)) ] ||
16571                 error "first index should be $min0_rec + 1 not $first_rec"
16572
16573         # LU-3446 changelog index reset on MDT restart
16574         local cur_rec1=$(changelog_users $SINGLEMDS |
16575                          awk '/^current.index:/ { print $NF }')
16576         changelog_clear 0 ||
16577                 error "clear all changelog records for $cl_user failed"
16578         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16579         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16580                 error "Fail to start $SINGLEMDS"
16581         local cur_rec2=$(changelog_users $SINGLEMDS |
16582                          awk '/^current.index:/ { print $NF }')
16583         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16584         [ $cur_rec1 == $cur_rec2 ] ||
16585                 error "current index should be $cur_rec1 not $cur_rec2"
16586
16587         echo "verifying users from this test are deregistered"
16588         changelog_deregister || error "changelog_deregister failed"
16589         changelog_users $SINGLEMDS | grep -q $cl_user &&
16590                 error "User '$cl_user' still in changelog_users"
16591
16592         # lctl get_param -n mdd.*.changelog_users
16593         # current_index: 144
16594         # ID    index (idle seconds)
16595         # cl3   144   (2) mask=<list>
16596         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16597                 # this is the normal case where all users were deregistered
16598                 # make sure no new records are added when no users are present
16599                 local last_rec1=$(changelog_users $SINGLEMDS |
16600                                   awk '/^current.index:/ { print $NF }')
16601                 touch $DIR/$tdir/chloe
16602                 local last_rec2=$(changelog_users $SINGLEMDS |
16603                                   awk '/^current.index:/ { print $NF }')
16604                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16605                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16606         else
16607                 # any changelog users must be leftovers from a previous test
16608                 changelog_users $SINGLEMDS
16609                 echo "other changelog users; can't verify off"
16610         fi
16611 }
16612 run_test 160a "changelog sanity"
16613
16614 test_160b() { # LU-3587
16615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16616         remote_mds_nodsh && skip "remote MDS with nodsh"
16617         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16618                 skip "Need MDS version at least 2.2.0"
16619
16620         changelog_register || error "changelog_register failed"
16621         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16622         changelog_users $SINGLEMDS | grep -q $cl_user ||
16623                 error "User '$cl_user' not found in changelog_users"
16624
16625         local longname1=$(str_repeat a 255)
16626         local longname2=$(str_repeat b 255)
16627
16628         cd $DIR
16629         echo "creating very long named file"
16630         touch $longname1 || error "create of '$longname1' failed"
16631         echo "renaming very long named file"
16632         mv $longname1 $longname2
16633
16634         changelog_dump | grep RENME | tail -n 5
16635         rm -f $longname2
16636 }
16637 run_test 160b "Verify that very long rename doesn't crash in changelog"
16638
16639 test_160c() {
16640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16641         remote_mds_nodsh && skip "remote MDS with nodsh"
16642
16643         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16644                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16645                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16646                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16647
16648         local rc=0
16649
16650         # Registration step
16651         changelog_register || error "changelog_register failed"
16652
16653         rm -rf $DIR/$tdir
16654         mkdir -p $DIR/$tdir
16655         $MCREATE $DIR/$tdir/foo_160c
16656         changelog_chmask "-TRUNC"
16657         $TRUNCATE $DIR/$tdir/foo_160c 200
16658         changelog_chmask "+TRUNC"
16659         $TRUNCATE $DIR/$tdir/foo_160c 199
16660         changelog_dump | tail -n 5
16661         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16662         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16663 }
16664 run_test 160c "verify that changelog log catch the truncate event"
16665
16666 test_160d() {
16667         remote_mds_nodsh && skip "remote MDS with nodsh"
16668         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16670         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16671                 skip "Need MDS version at least 2.7.60"
16672
16673         # Registration step
16674         changelog_register || error "changelog_register failed"
16675
16676         mkdir -p $DIR/$tdir/migrate_dir
16677         changelog_clear 0 || error "changelog_clear failed"
16678
16679         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16680         changelog_dump | tail -n 5
16681         local migrates=$(changelog_dump | grep -c "MIGRT")
16682         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16683 }
16684 run_test 160d "verify that changelog log catch the migrate event"
16685
16686 test_160e() {
16687         remote_mds_nodsh && skip "remote MDS with nodsh"
16688
16689         # Create a user
16690         changelog_register || error "changelog_register failed"
16691
16692         local MDT0=$(facet_svc $SINGLEMDS)
16693         local rc
16694
16695         # No user (expect fail)
16696         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16697         rc=$?
16698         if [ $rc -eq 0 ]; then
16699                 error "Should fail without user"
16700         elif [ $rc -ne 4 ]; then
16701                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16702         fi
16703
16704         # Delete a future user (expect fail)
16705         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16706         rc=$?
16707         if [ $rc -eq 0 ]; then
16708                 error "Deleted non-existant user cl77"
16709         elif [ $rc -ne 2 ]; then
16710                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16711         fi
16712
16713         # Clear to a bad index (1 billion should be safe)
16714         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16715         rc=$?
16716
16717         if [ $rc -eq 0 ]; then
16718                 error "Successfully cleared to invalid CL index"
16719         elif [ $rc -ne 22 ]; then
16720                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16721         fi
16722 }
16723 run_test 160e "changelog negative testing (should return errors)"
16724
16725 test_160f() {
16726         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16727         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16728                 skip "Need MDS version at least 2.10.56"
16729
16730         local mdts=$(comma_list $(mdts_nodes))
16731
16732         # Create a user
16733         changelog_register || error "first changelog_register failed"
16734         changelog_register || error "second changelog_register failed"
16735         local cl_users
16736         declare -A cl_user1
16737         declare -A cl_user2
16738         local user_rec1
16739         local user_rec2
16740         local i
16741
16742         # generate some changelog records to accumulate on each MDT
16743         # use all_char because created files should be evenly distributed
16744         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16745                 error "test_mkdir $tdir failed"
16746         log "$(date +%s): creating first files"
16747         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16748                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16749                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16750         done
16751
16752         # check changelogs have been generated
16753         local start=$SECONDS
16754         local idle_time=$((MDSCOUNT * 5 + 5))
16755         local nbcl=$(changelog_dump | wc -l)
16756         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16757
16758         for param in "changelog_max_idle_time=$idle_time" \
16759                      "changelog_gc=1" \
16760                      "changelog_min_gc_interval=2" \
16761                      "changelog_min_free_cat_entries=3"; do
16762                 local MDT0=$(facet_svc $SINGLEMDS)
16763                 local var="${param%=*}"
16764                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16765
16766                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16767                 do_nodes $mdts $LCTL set_param mdd.*.$param
16768         done
16769
16770         # force cl_user2 to be idle (1st part), but also cancel the
16771         # cl_user1 records so that it is not evicted later in the test.
16772         local sleep1=$((idle_time / 2))
16773         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16774         sleep $sleep1
16775
16776         # simulate changelog catalog almost full
16777         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16778         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16779
16780         for i in $(seq $MDSCOUNT); do
16781                 cl_users=(${CL_USERS[mds$i]})
16782                 cl_user1[mds$i]="${cl_users[0]}"
16783                 cl_user2[mds$i]="${cl_users[1]}"
16784
16785                 [ -n "${cl_user1[mds$i]}" ] ||
16786                         error "mds$i: no user registered"
16787                 [ -n "${cl_user2[mds$i]}" ] ||
16788                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16789
16790                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16791                 [ -n "$user_rec1" ] ||
16792                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16793                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16794                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16795                 [ -n "$user_rec2" ] ||
16796                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16797                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16798                      "$user_rec1 + 2 == $user_rec2"
16799                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16800                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16801                               "$user_rec1 + 2, but is $user_rec2"
16802                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16803                 [ -n "$user_rec2" ] ||
16804                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16805                 [ $user_rec1 == $user_rec2 ] ||
16806                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16807                               "$user_rec1, but is $user_rec2"
16808         done
16809
16810         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16811         local sleep2=$((idle_time - (SECONDS - start) + 1))
16812         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16813         sleep $sleep2
16814
16815         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16816         # cl_user1 should be OK because it recently processed records.
16817         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16818         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16819                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16820                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16821         done
16822
16823         # ensure gc thread is done
16824         for i in $(mdts_nodes); do
16825                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16826                         error "$i: GC-thread not done"
16827         done
16828
16829         local first_rec
16830         for (( i = 1; i <= MDSCOUNT; i++ )); do
16831                 # check cl_user1 still registered
16832                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16833                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16834                 # check cl_user2 unregistered
16835                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16836                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16837
16838                 # check changelogs are present and starting at $user_rec1 + 1
16839                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16840                 [ -n "$user_rec1" ] ||
16841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16842                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16843                             awk '{ print $1; exit; }')
16844
16845                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16846                 [ $((user_rec1 + 1)) == $first_rec ] ||
16847                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16848         done
16849 }
16850 run_test 160f "changelog garbage collect (timestamped users)"
16851
16852 test_160g() {
16853         remote_mds_nodsh && skip "remote MDS with nodsh"
16854         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16855                 skip "Need MDS version at least 2.14.55"
16856
16857         local mdts=$(comma_list $(mdts_nodes))
16858
16859         # Create a user
16860         changelog_register || error "first changelog_register failed"
16861         changelog_register || error "second changelog_register failed"
16862         local cl_users
16863         declare -A cl_user1
16864         declare -A cl_user2
16865         local user_rec1
16866         local user_rec2
16867         local i
16868
16869         # generate some changelog records to accumulate on each MDT
16870         # use all_char because created files should be evenly distributed
16871         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16872                 error "test_mkdir $tdir failed"
16873         for ((i = 0; i < MDSCOUNT; i++)); do
16874                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16875                         error "create $DIR/$tdir/d$i.1 failed"
16876         done
16877
16878         # check changelogs have been generated
16879         local nbcl=$(changelog_dump | wc -l)
16880         (( $nbcl > 0 )) || error "no changelogs found"
16881
16882         # reduce the max_idle_indexes value to make sure we exceed it
16883         for param in "changelog_max_idle_indexes=2" \
16884                      "changelog_gc=1" \
16885                      "changelog_min_gc_interval=2"; do
16886                 local MDT0=$(facet_svc $SINGLEMDS)
16887                 local var="${param%=*}"
16888                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16889
16890                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16891                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16892                         error "unable to set mdd.*.$param"
16893         done
16894
16895         local start=$SECONDS
16896         for i in $(seq $MDSCOUNT); do
16897                 cl_users=(${CL_USERS[mds$i]})
16898                 cl_user1[mds$i]="${cl_users[0]}"
16899                 cl_user2[mds$i]="${cl_users[1]}"
16900
16901                 [ -n "${cl_user1[mds$i]}" ] ||
16902                         error "mds$i: user1 is not registered"
16903                 [ -n "${cl_user2[mds$i]}" ] ||
16904                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16905
16906                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16907                 [ -n "$user_rec1" ] ||
16908                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16909                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16910                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16911                 [ -n "$user_rec2" ] ||
16912                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16913                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16914                      "$user_rec1 + 2 == $user_rec2"
16915                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16916                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16917                               "expected $user_rec1 + 2, but is $user_rec2"
16918                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16919                 [ -n "$user_rec2" ] ||
16920                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16921                 [ $user_rec1 == $user_rec2 ] ||
16922                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16923                               "expected $user_rec1, but is $user_rec2"
16924         done
16925
16926         # ensure we are past the previous changelog_min_gc_interval set above
16927         local sleep2=$((start + 2 - SECONDS))
16928         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16929         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16930         # cl_user1 should be OK because it recently processed records.
16931         for ((i = 0; i < MDSCOUNT; i++)); do
16932                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16933                         error "create $DIR/$tdir/d$i.3 failed"
16934         done
16935
16936         # ensure gc thread is done
16937         for i in $(mdts_nodes); do
16938                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16939                         error "$i: GC-thread not done"
16940         done
16941
16942         local first_rec
16943         for (( i = 1; i <= MDSCOUNT; i++ )); do
16944                 # check cl_user1 still registered
16945                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16946                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16947                 # check cl_user2 unregistered
16948                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16949                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16950
16951                 # check changelogs are present and starting at $user_rec1 + 1
16952                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16953                 [ -n "$user_rec1" ] ||
16954                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16955                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16956                             awk '{ print $1; exit; }')
16957
16958                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16959                 [ $((user_rec1 + 1)) == $first_rec ] ||
16960                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16961         done
16962 }
16963 run_test 160g "changelog garbage collect on idle records"
16964
16965 test_160h() {
16966         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16967         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16968                 skip "Need MDS version at least 2.10.56"
16969
16970         local mdts=$(comma_list $(mdts_nodes))
16971
16972         # Create a user
16973         changelog_register || error "first changelog_register failed"
16974         changelog_register || error "second changelog_register failed"
16975         local cl_users
16976         declare -A cl_user1
16977         declare -A cl_user2
16978         local user_rec1
16979         local user_rec2
16980         local i
16981
16982         # generate some changelog records to accumulate on each MDT
16983         # use all_char because created files should be evenly distributed
16984         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16985                 error "test_mkdir $tdir failed"
16986         for ((i = 0; i < MDSCOUNT; i++)); do
16987                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16988                         error "create $DIR/$tdir/d$i.1 failed"
16989         done
16990
16991         # check changelogs have been generated
16992         local nbcl=$(changelog_dump | wc -l)
16993         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16994
16995         for param in "changelog_max_idle_time=10" \
16996                      "changelog_gc=1" \
16997                      "changelog_min_gc_interval=2"; do
16998                 local MDT0=$(facet_svc $SINGLEMDS)
16999                 local var="${param%=*}"
17000                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17001
17002                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17003                 do_nodes $mdts $LCTL set_param mdd.*.$param
17004         done
17005
17006         # force cl_user2 to be idle (1st part)
17007         sleep 9
17008
17009         for i in $(seq $MDSCOUNT); do
17010                 cl_users=(${CL_USERS[mds$i]})
17011                 cl_user1[mds$i]="${cl_users[0]}"
17012                 cl_user2[mds$i]="${cl_users[1]}"
17013
17014                 [ -n "${cl_user1[mds$i]}" ] ||
17015                         error "mds$i: no user registered"
17016                 [ -n "${cl_user2[mds$i]}" ] ||
17017                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17018
17019                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17020                 [ -n "$user_rec1" ] ||
17021                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17022                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17023                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17024                 [ -n "$user_rec2" ] ||
17025                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17026                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17027                      "$user_rec1 + 2 == $user_rec2"
17028                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17029                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17030                               "$user_rec1 + 2, but is $user_rec2"
17031                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17032                 [ -n "$user_rec2" ] ||
17033                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17034                 [ $user_rec1 == $user_rec2 ] ||
17035                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17036                               "$user_rec1, but is $user_rec2"
17037         done
17038
17039         # force cl_user2 to be idle (2nd part) and to reach
17040         # changelog_max_idle_time
17041         sleep 2
17042
17043         # force each GC-thread start and block then
17044         # one per MDT/MDD, set fail_val accordingly
17045         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17046         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17047
17048         # generate more changelogs to trigger fail_loc
17049         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17050                 error "create $DIR/$tdir/${tfile}bis failed"
17051
17052         # stop MDT to stop GC-thread, should be done in back-ground as it will
17053         # block waiting for the thread to be released and exit
17054         declare -A stop_pids
17055         for i in $(seq $MDSCOUNT); do
17056                 stop mds$i &
17057                 stop_pids[mds$i]=$!
17058         done
17059
17060         for i in $(mdts_nodes); do
17061                 local facet
17062                 local nb=0
17063                 local facets=$(facets_up_on_host $i)
17064
17065                 for facet in ${facets//,/ }; do
17066                         if [[ $facet == mds* ]]; then
17067                                 nb=$((nb + 1))
17068                         fi
17069                 done
17070                 # ensure each MDS's gc threads are still present and all in "R"
17071                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17072                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17073                         error "$i: expected $nb GC-thread"
17074                 wait_update $i \
17075                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17076                         "R" 20 ||
17077                         error "$i: GC-thread not found in R-state"
17078                 # check umounts of each MDT on MDS have reached kthread_stop()
17079                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17080                         error "$i: expected $nb umount"
17081                 wait_update $i \
17082                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17083                         error "$i: umount not found in D-state"
17084         done
17085
17086         # release all GC-threads
17087         do_nodes $mdts $LCTL set_param fail_loc=0
17088
17089         # wait for MDT stop to complete
17090         for i in $(seq $MDSCOUNT); do
17091                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17092         done
17093
17094         # XXX
17095         # may try to check if any orphan changelog records are present
17096         # via ldiskfs/zfs and llog_reader...
17097
17098         # re-start/mount MDTs
17099         for i in $(seq $MDSCOUNT); do
17100                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17101                         error "Fail to start mds$i"
17102         done
17103
17104         local first_rec
17105         for i in $(seq $MDSCOUNT); do
17106                 # check cl_user1 still registered
17107                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17108                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17109                 # check cl_user2 unregistered
17110                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17111                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17112
17113                 # check changelogs are present and starting at $user_rec1 + 1
17114                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17115                 [ -n "$user_rec1" ] ||
17116                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17117                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17118                             awk '{ print $1; exit; }')
17119
17120                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17121                 [ $((user_rec1 + 1)) == $first_rec ] ||
17122                         error "mds$i: first index should be $user_rec1 + 1, " \
17123                               "but is $first_rec"
17124         done
17125 }
17126 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17127               "during mount"
17128
17129 test_160i() {
17130
17131         local mdts=$(comma_list $(mdts_nodes))
17132
17133         changelog_register || error "first changelog_register failed"
17134
17135         # generate some changelog records to accumulate on each MDT
17136         # use all_char because created files should be evenly distributed
17137         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17138                 error "test_mkdir $tdir failed"
17139         for ((i = 0; i < MDSCOUNT; i++)); do
17140                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17141                         error "create $DIR/$tdir/d$i.1 failed"
17142         done
17143
17144         # check changelogs have been generated
17145         local nbcl=$(changelog_dump | wc -l)
17146         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17147
17148         # simulate race between register and unregister
17149         # XXX as fail_loc is set per-MDS, with DNE configs the race
17150         # simulation will only occur for one MDT per MDS and for the
17151         # others the normal race scenario will take place
17152         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17153         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17154         do_nodes $mdts $LCTL set_param fail_val=1
17155
17156         # unregister 1st user
17157         changelog_deregister &
17158         local pid1=$!
17159         # wait some time for deregister work to reach race rdv
17160         sleep 2
17161         # register 2nd user
17162         changelog_register || error "2nd user register failed"
17163
17164         wait $pid1 || error "1st user deregister failed"
17165
17166         local i
17167         local last_rec
17168         declare -A LAST_REC
17169         for i in $(seq $MDSCOUNT); do
17170                 if changelog_users mds$i | grep "^cl"; then
17171                         # make sure new records are added with one user present
17172                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17173                                           awk '/^current.index:/ { print $NF }')
17174                 else
17175                         error "mds$i has no user registered"
17176                 fi
17177         done
17178
17179         # generate more changelog records to accumulate on each MDT
17180         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17181                 error "create $DIR/$tdir/${tfile}bis failed"
17182
17183         for i in $(seq $MDSCOUNT); do
17184                 last_rec=$(changelog_users $SINGLEMDS |
17185                            awk '/^current.index:/ { print $NF }')
17186                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17187                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17188                         error "changelogs are off on mds$i"
17189         done
17190 }
17191 run_test 160i "changelog user register/unregister race"
17192
17193 test_160j() {
17194         remote_mds_nodsh && skip "remote MDS with nodsh"
17195         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17196                 skip "Need MDS version at least 2.12.56"
17197
17198         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17199         stack_trap "umount $MOUNT2" EXIT
17200
17201         changelog_register || error "first changelog_register failed"
17202         stack_trap "changelog_deregister" EXIT
17203
17204         # generate some changelog
17205         # use all_char because created files should be evenly distributed
17206         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17207                 error "mkdir $tdir failed"
17208         for ((i = 0; i < MDSCOUNT; i++)); do
17209                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17210                         error "create $DIR/$tdir/d$i.1 failed"
17211         done
17212
17213         # open the changelog device
17214         exec 3>/dev/changelog-$FSNAME-MDT0000
17215         stack_trap "exec 3>&-" EXIT
17216         exec 4</dev/changelog-$FSNAME-MDT0000
17217         stack_trap "exec 4<&-" EXIT
17218
17219         # umount the first lustre mount
17220         umount $MOUNT
17221         stack_trap "mount_client $MOUNT" EXIT
17222
17223         # read changelog, which may or may not fail, but should not crash
17224         cat <&4 >/dev/null
17225
17226         # clear changelog
17227         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17228         changelog_users $SINGLEMDS | grep -q $cl_user ||
17229                 error "User $cl_user not found in changelog_users"
17230
17231         printf 'clear:'$cl_user':0' >&3
17232 }
17233 run_test 160j "client can be umounted while its chanangelog is being used"
17234
17235 test_160k() {
17236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17237         remote_mds_nodsh && skip "remote MDS with nodsh"
17238
17239         mkdir -p $DIR/$tdir/1/1
17240
17241         changelog_register || error "changelog_register failed"
17242         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17243
17244         changelog_users $SINGLEMDS | grep -q $cl_user ||
17245                 error "User '$cl_user' not found in changelog_users"
17246 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17247         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17248         rmdir $DIR/$tdir/1/1 & sleep 1
17249         mkdir $DIR/$tdir/2
17250         touch $DIR/$tdir/2/2
17251         rm -rf $DIR/$tdir/2
17252
17253         wait
17254         sleep 4
17255
17256         changelog_dump | grep rmdir || error "rmdir not recorded"
17257 }
17258 run_test 160k "Verify that changelog records are not lost"
17259
17260 # Verifies that a file passed as a parameter has recently had an operation
17261 # performed on it that has generated an MTIME changelog which contains the
17262 # correct parent FID. As files might reside on a different MDT from the
17263 # parent directory in DNE configurations, the FIDs are translated to paths
17264 # before being compared, which should be identical
17265 compare_mtime_changelog() {
17266         local file="${1}"
17267         local mdtidx
17268         local mtime
17269         local cl_fid
17270         local pdir
17271         local dir
17272
17273         mdtidx=$($LFS getstripe --mdt-index $file)
17274         mdtidx=$(printf "%04x" $mdtidx)
17275
17276         # Obtain the parent FID from the MTIME changelog
17277         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17278         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17279
17280         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17281         [ -z "$cl_fid" ] && error "parent FID not present"
17282
17283         # Verify that the path for the parent FID is the same as the path for
17284         # the test directory
17285         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17286
17287         dir=$(dirname $1)
17288
17289         [[ "${pdir%/}" == "$dir" ]] ||
17290                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17291 }
17292
17293 test_160l() {
17294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17295
17296         remote_mds_nodsh && skip "remote MDS with nodsh"
17297         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17298                 skip "Need MDS version at least 2.13.55"
17299
17300         local cl_user
17301
17302         changelog_register || error "changelog_register failed"
17303         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17304
17305         changelog_users $SINGLEMDS | grep -q $cl_user ||
17306                 error "User '$cl_user' not found in changelog_users"
17307
17308         # Clear some types so that MTIME changelogs are generated
17309         changelog_chmask "-CREAT"
17310         changelog_chmask "-CLOSE"
17311
17312         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17313
17314         # Test CL_MTIME during setattr
17315         touch $DIR/$tdir/$tfile
17316         compare_mtime_changelog $DIR/$tdir/$tfile
17317
17318         # Test CL_MTIME during close
17319         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17320         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17321 }
17322 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17323
17324 test_160m() {
17325         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17326         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17327                 skip "Need MDS version at least 2.14.51"
17328         local cl_users
17329         local cl_user1
17330         local cl_user2
17331         local pid1
17332
17333         # Create a user
17334         changelog_register || error "first changelog_register failed"
17335         changelog_register || error "second changelog_register failed"
17336
17337         cl_users=(${CL_USERS[mds1]})
17338         cl_user1="${cl_users[0]}"
17339         cl_user2="${cl_users[1]}"
17340         # generate some changelog records to accumulate on MDT0
17341         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17342         createmany -m $DIR/$tdir/$tfile 50 ||
17343                 error "create $DIR/$tdir/$tfile failed"
17344         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17345         rm -f $DIR/$tdir
17346
17347         # check changelogs have been generated
17348         local nbcl=$(changelog_dump | wc -l)
17349         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17350
17351 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17352         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17353
17354         __changelog_clear mds1 $cl_user1 +10
17355         __changelog_clear mds1 $cl_user2 0 &
17356         pid1=$!
17357         sleep 2
17358         __changelog_clear mds1 $cl_user1 0 ||
17359                 error "fail to cancel record for $cl_user1"
17360         wait $pid1
17361         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17362 }
17363 run_test 160m "Changelog clear race"
17364
17365 test_160n() {
17366         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17367         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17368                 skip "Need MDS version at least 2.14.51"
17369         local cl_users
17370         local cl_user1
17371         local cl_user2
17372         local pid1
17373         local first_rec
17374         local last_rec=0
17375
17376         # Create a user
17377         changelog_register || error "first changelog_register failed"
17378
17379         cl_users=(${CL_USERS[mds1]})
17380         cl_user1="${cl_users[0]}"
17381
17382         # generate some changelog records to accumulate on MDT0
17383         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17384         first_rec=$(changelog_users $SINGLEMDS |
17385                         awk '/^current.index:/ { print $NF }')
17386         while (( last_rec < (( first_rec + 65000)) )); do
17387                 createmany -m $DIR/$tdir/$tfile 10000 ||
17388                         error "create $DIR/$tdir/$tfile failed"
17389
17390                 for i in $(seq 0 10000); do
17391                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17392                                 > /dev/null
17393                 done
17394
17395                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17396                         error "unlinkmany failed unlink"
17397                 last_rec=$(changelog_users $SINGLEMDS |
17398                         awk '/^current.index:/ { print $NF }')
17399                 echo last record $last_rec
17400                 (( last_rec == 0 )) && error "no changelog found"
17401         done
17402
17403 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17404         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17405
17406         __changelog_clear mds1 $cl_user1 0 &
17407         pid1=$!
17408         sleep 2
17409         __changelog_clear mds1 $cl_user1 0 ||
17410                 error "fail to cancel record for $cl_user1"
17411         wait $pid1
17412         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17413 }
17414 run_test 160n "Changelog destroy race"
17415
17416 test_160o() {
17417         local mdt="$(facet_svc $SINGLEMDS)"
17418
17419         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17420         remote_mds_nodsh && skip "remote MDS with nodsh"
17421         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17422                 skip "Need MDS version at least 2.14.52"
17423
17424         changelog_register --user test_160o -m unlnk+close+open ||
17425                 error "changelog_register failed"
17426
17427         do_facet $SINGLEMDS $LCTL --device $mdt \
17428                                 changelog_register -u "Tt3_-#" &&
17429                 error "bad symbols in name should fail"
17430
17431         do_facet $SINGLEMDS $LCTL --device $mdt \
17432                                 changelog_register -u test_160o &&
17433                 error "the same name registration should fail"
17434
17435         do_facet $SINGLEMDS $LCTL --device $mdt \
17436                         changelog_register -u test_160toolongname &&
17437                 error "too long name registration should fail"
17438
17439         changelog_chmask "MARK+HSM"
17440         lctl get_param mdd.*.changelog*mask
17441         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17442         changelog_users $SINGLEMDS | grep -q $cl_user ||
17443                 error "User $cl_user not found in changelog_users"
17444         #verify username
17445         echo $cl_user | grep -q test_160o ||
17446                 error "User $cl_user has no specific name 'test160o'"
17447
17448         # change something
17449         changelog_clear 0 || error "changelog_clear failed"
17450         # generate some changelog records to accumulate on MDT0
17451         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17452         touch $DIR/$tdir/$tfile                 # open 1
17453
17454         OPENS=$(changelog_dump | grep -c "OPEN")
17455         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17456
17457         # must be no MKDIR it wasn't set as user mask
17458         MKDIR=$(changelog_dump | grep -c "MKDIR")
17459         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17460
17461         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17462                                 mdd.$mdt.changelog_current_mask -n)
17463         # register maskless user
17464         changelog_register || error "changelog_register failed"
17465         # effective mask should be not changed because it is not minimal
17466         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17467                                 mdd.$mdt.changelog_current_mask -n)
17468         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17469         # set server mask to minimal value
17470         changelog_chmask "MARK"
17471         # check effective mask again, should be treated as DEFMASK now
17472         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17473                                 mdd.$mdt.changelog_current_mask -n)
17474         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17475
17476         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17477                 # set server mask back to some value
17478                 changelog_chmask "CLOSE,UNLNK"
17479                 # check effective mask again, should not remain as DEFMASK
17480                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17481                                 mdd.$mdt.changelog_current_mask -n)
17482                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17483         fi
17484
17485         do_facet $SINGLEMDS $LCTL --device $mdt \
17486                                 changelog_deregister -u test_160o ||
17487                 error "cannot deregister by name"
17488 }
17489 run_test 160o "changelog user name and mask"
17490
17491 test_160p() {
17492         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17493         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17494                 skip "Need MDS version at least 2.14.51"
17495         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17496         local cl_users
17497         local cl_user1
17498         local entry_count
17499
17500         # Create a user
17501         changelog_register || error "first changelog_register failed"
17502
17503         cl_users=(${CL_USERS[mds1]})
17504         cl_user1="${cl_users[0]}"
17505
17506         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17507         createmany -m $DIR/$tdir/$tfile 50 ||
17508                 error "create $DIR/$tdir/$tfile failed"
17509         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17510         rm -rf $DIR/$tdir
17511
17512         # check changelogs have been generated
17513         entry_count=$(changelog_dump | wc -l)
17514         ((entry_count != 0)) || error "no changelog entries found"
17515
17516         # remove changelog_users and check that orphan entries are removed
17517         stop mds1
17518         local dev=$(mdsdevname 1)
17519         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17520         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17521         entry_count=$(changelog_dump | wc -l)
17522         ((entry_count == 0)) ||
17523                 error "found $entry_count changelog entries, expected none"
17524 }
17525 run_test 160p "Changelog orphan cleanup with no users"
17526
17527 test_160q() {
17528         local mdt="$(facet_svc $SINGLEMDS)"
17529         local clu
17530
17531         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17532         remote_mds_nodsh && skip "remote MDS with nodsh"
17533         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17534                 skip "Need MDS version at least 2.14.54"
17535
17536         # set server mask to minimal value like server init does
17537         changelog_chmask "MARK"
17538         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17539                 error "changelog_register failed"
17540         # check effective mask again, should be treated as DEFMASK now
17541         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17542                                 mdd.$mdt.changelog_current_mask -n)
17543         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17544                 error "changelog_deregister failed"
17545         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17546 }
17547 run_test 160q "changelog effective mask is DEFMASK if not set"
17548
17549 test_160s() {
17550         remote_mds_nodsh && skip "remote MDS with nodsh"
17551         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17552                 skip "Need MDS version at least 2.14.55"
17553
17554         local mdts=$(comma_list $(mdts_nodes))
17555
17556         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17557         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17558                                        fail_val=$((24 * 3600 * 10))
17559
17560         # Create a user which is 10 days old
17561         changelog_register || error "first changelog_register failed"
17562         local cl_users
17563         declare -A cl_user1
17564         local i
17565
17566         # generate some changelog records to accumulate on each MDT
17567         # use all_char because created files should be evenly distributed
17568         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17569                 error "test_mkdir $tdir failed"
17570         for ((i = 0; i < MDSCOUNT; i++)); do
17571                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17572                         error "create $DIR/$tdir/d$i.1 failed"
17573         done
17574
17575         # check changelogs have been generated
17576         local nbcl=$(changelog_dump | wc -l)
17577         (( nbcl > 0 )) || error "no changelogs found"
17578
17579         # reduce the max_idle_indexes value to make sure we exceed it
17580         for param in "changelog_max_idle_indexes=2097446912" \
17581                      "changelog_max_idle_time=2592000" \
17582                      "changelog_gc=1" \
17583                      "changelog_min_gc_interval=2"; do
17584                 local MDT0=$(facet_svc $SINGLEMDS)
17585                 local var="${param%=*}"
17586                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17587
17588                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17589                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17590                         error "unable to set mdd.*.$param"
17591         done
17592
17593         local start=$SECONDS
17594         for i in $(seq $MDSCOUNT); do
17595                 cl_users=(${CL_USERS[mds$i]})
17596                 cl_user1[mds$i]="${cl_users[0]}"
17597
17598                 [[ -n "${cl_user1[mds$i]}" ]] ||
17599                         error "mds$i: no user registered"
17600         done
17601
17602         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17603         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17604
17605         # ensure we are past the previous changelog_min_gc_interval set above
17606         local sleep2=$((start + 2 - SECONDS))
17607         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17608
17609         # Generate one more changelog to trigger GC
17610         for ((i = 0; i < MDSCOUNT; i++)); do
17611                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17612                         error "create $DIR/$tdir/d$i.3 failed"
17613         done
17614
17615         # ensure gc thread is done
17616         for node in $(mdts_nodes); do
17617                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17618                         error "$node: GC-thread not done"
17619         done
17620
17621         do_nodes $mdts $LCTL set_param fail_loc=0
17622
17623         for (( i = 1; i <= MDSCOUNT; i++ )); do
17624                 # check cl_user1 is purged
17625                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17626                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17627         done
17628         return 0
17629 }
17630 run_test 160s "changelog garbage collect on idle records * time"
17631
17632 test_160t() {
17633         remote_mds_nodsh && skip "remote MDS with nodsh"
17634         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17635                 skip "Need MDS version at least 2.15.50"
17636
17637         local MDT0=$(facet_svc $SINGLEMDS)
17638         local cl_users
17639         local cl_user1
17640         local cl_user2
17641         local start
17642
17643         changelog_register --user user1 -m all ||
17644                 error "user1 failed to register"
17645
17646         mkdir_on_mdt0 $DIR/$tdir
17647         # create default overstripe to maximize changelog size
17648         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17649         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17650         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17651
17652         # user2 consumes less records so less space
17653         changelog_register --user user2 || error "user2 failed to register"
17654         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17655         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17656
17657         # check changelogs have been generated
17658         local nbcl=$(changelog_dump | wc -l)
17659         (( nbcl > 0 )) || error "no changelogs found"
17660
17661         # reduce the changelog_min_gc_interval to force check
17662         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17663                 local var="${param%=*}"
17664                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17665
17666                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17667                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17668                         error "unable to set mdd.*.$param"
17669         done
17670
17671         start=$SECONDS
17672         cl_users=(${CL_USERS[mds1]})
17673         cl_user1="${cl_users[0]}"
17674         cl_user2="${cl_users[1]}"
17675
17676         [[ -n $cl_user1 ]] ||
17677                 error "mds1: user #1 isn't registered"
17678         [[ -n $cl_user2 ]] ||
17679                 error "mds1: user #2 isn't registered"
17680
17681         # ensure we are past the previous changelog_min_gc_interval set above
17682         local sleep2=$((start + 2 - SECONDS))
17683         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17684
17685         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17686         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17687                         fail_val=$(((llog_size1 + llog_size2) / 2))
17688
17689         # Generate more changelog to trigger GC
17690         createmany -o $DIR/$tdir/u3_ 4 ||
17691                 error "create failed for more files"
17692
17693         # ensure gc thread is done
17694         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17695                 error "mds1: GC-thread not done"
17696
17697         do_facet mds1 $LCTL set_param fail_loc=0
17698
17699         # check cl_user1 is purged
17700         changelog_users mds1 | grep -q "$cl_user1" &&
17701                 error "User $cl_user1 is registered"
17702         # check cl_user2 is not purged
17703         changelog_users mds1 | grep -q "$cl_user2" ||
17704                 error "User $cl_user2 is not registered"
17705 }
17706 run_test 160t "changelog garbage collect on lack of space"
17707
17708 test_161a() {
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710
17711         test_mkdir -c1 $DIR/$tdir
17712         cp /etc/hosts $DIR/$tdir/$tfile
17713         test_mkdir -c1 $DIR/$tdir/foo1
17714         test_mkdir -c1 $DIR/$tdir/foo2
17715         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17716         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17717         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17718         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17719         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17720         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17721                 $LFS fid2path $DIR $FID
17722                 error "bad link ea"
17723         fi
17724         # middle
17725         rm $DIR/$tdir/foo2/zachary
17726         # last
17727         rm $DIR/$tdir/foo2/thor
17728         # first
17729         rm $DIR/$tdir/$tfile
17730         # rename
17731         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17732         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17733                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17734         rm $DIR/$tdir/foo2/maggie
17735
17736         # overflow the EA
17737         local longname=$tfile.avg_len_is_thirty_two_
17738         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17739                 error_noexit 'failed to unlink many hardlinks'" EXIT
17740         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17741                 error "failed to hardlink many files"
17742         links=$($LFS fid2path $DIR $FID | wc -l)
17743         echo -n "${links}/1000 links in link EA"
17744         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17745 }
17746 run_test 161a "link ea sanity"
17747
17748 test_161b() {
17749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17750         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17751
17752         local MDTIDX=1
17753         local remote_dir=$DIR/$tdir/remote_dir
17754
17755         mkdir -p $DIR/$tdir
17756         $LFS mkdir -i $MDTIDX $remote_dir ||
17757                 error "create remote directory failed"
17758
17759         cp /etc/hosts $remote_dir/$tfile
17760         mkdir -p $remote_dir/foo1
17761         mkdir -p $remote_dir/foo2
17762         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17763         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17764         ln $remote_dir/$tfile $remote_dir/foo1/luna
17765         ln $remote_dir/$tfile $remote_dir/foo2/thor
17766
17767         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17768                      tr -d ']')
17769         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17770                 $LFS fid2path $DIR $FID
17771                 error "bad link ea"
17772         fi
17773         # middle
17774         rm $remote_dir/foo2/zachary
17775         # last
17776         rm $remote_dir/foo2/thor
17777         # first
17778         rm $remote_dir/$tfile
17779         # rename
17780         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17781         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17782         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17783                 $LFS fid2path $DIR $FID
17784                 error "bad link rename"
17785         fi
17786         rm $remote_dir/foo2/maggie
17787
17788         # overflow the EA
17789         local longname=filename_avg_len_is_thirty_two_
17790         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17791                 error "failed to hardlink many files"
17792         links=$($LFS fid2path $DIR $FID | wc -l)
17793         echo -n "${links}/1000 links in link EA"
17794         [[ ${links} -gt 60 ]] ||
17795                 error "expected at least 60 links in link EA"
17796         unlinkmany $remote_dir/foo2/$longname 1000 ||
17797         error "failed to unlink many hardlinks"
17798 }
17799 run_test 161b "link ea sanity under remote directory"
17800
17801 test_161c() {
17802         remote_mds_nodsh && skip "remote MDS with nodsh"
17803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17804         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17805                 skip "Need MDS version at least 2.1.5"
17806
17807         # define CLF_RENAME_LAST 0x0001
17808         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17809         changelog_register || error "changelog_register failed"
17810
17811         rm -rf $DIR/$tdir
17812         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17813         touch $DIR/$tdir/foo_161c
17814         touch $DIR/$tdir/bar_161c
17815         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17816         changelog_dump | grep RENME | tail -n 5
17817         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17818         changelog_clear 0 || error "changelog_clear failed"
17819         if [ x$flags != "x0x1" ]; then
17820                 error "flag $flags is not 0x1"
17821         fi
17822
17823         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17824         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17825         touch $DIR/$tdir/foo_161c
17826         touch $DIR/$tdir/bar_161c
17827         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17828         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17829         changelog_dump | grep RENME | tail -n 5
17830         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17831         changelog_clear 0 || error "changelog_clear failed"
17832         if [ x$flags != "x0x0" ]; then
17833                 error "flag $flags is not 0x0"
17834         fi
17835         echo "rename overwrite a target having nlink > 1," \
17836                 "changelog record has flags of $flags"
17837
17838         # rename doesn't overwrite a target (changelog flag 0x0)
17839         touch $DIR/$tdir/foo_161c
17840         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17841         changelog_dump | grep RENME | tail -n 5
17842         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17843         changelog_clear 0 || error "changelog_clear failed"
17844         if [ x$flags != "x0x0" ]; then
17845                 error "flag $flags is not 0x0"
17846         fi
17847         echo "rename doesn't overwrite a target," \
17848                 "changelog record has flags of $flags"
17849
17850         # define CLF_UNLINK_LAST 0x0001
17851         # unlink a file having nlink = 1 (changelog flag 0x1)
17852         rm -f $DIR/$tdir/foo2_161c
17853         changelog_dump | grep UNLNK | tail -n 5
17854         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17855         changelog_clear 0 || error "changelog_clear failed"
17856         if [ x$flags != "x0x1" ]; then
17857                 error "flag $flags is not 0x1"
17858         fi
17859         echo "unlink a file having nlink = 1," \
17860                 "changelog record has flags of $flags"
17861
17862         # unlink a file having nlink > 1 (changelog flag 0x0)
17863         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17864         rm -f $DIR/$tdir/foobar_161c
17865         changelog_dump | grep UNLNK | tail -n 5
17866         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17867         changelog_clear 0 || error "changelog_clear failed"
17868         if [ x$flags != "x0x0" ]; then
17869                 error "flag $flags is not 0x0"
17870         fi
17871         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17872 }
17873 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17874
17875 test_161d() {
17876         remote_mds_nodsh && skip "remote MDS with nodsh"
17877         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17878
17879         local pid
17880         local fid
17881
17882         changelog_register || error "changelog_register failed"
17883
17884         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17885         # interfer with $MOUNT/.lustre/fid/ access
17886         mkdir $DIR/$tdir
17887         [[ $? -eq 0 ]] || error "mkdir failed"
17888
17889         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17890         $LCTL set_param fail_loc=0x8000140c
17891         # 5s pause
17892         $LCTL set_param fail_val=5
17893
17894         # create file
17895         echo foofoo > $DIR/$tdir/$tfile &
17896         pid=$!
17897
17898         # wait for create to be delayed
17899         sleep 2
17900
17901         ps -p $pid
17902         [[ $? -eq 0 ]] || error "create should be blocked"
17903
17904         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17905         stack_trap "rm -f $tempfile"
17906         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17907         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17908         # some delay may occur during ChangeLog publishing and file read just
17909         # above, that could allow file write to happen finally
17910         [[ -s $tempfile ]] && echo "file should be empty"
17911
17912         $LCTL set_param fail_loc=0
17913
17914         wait $pid
17915         [[ $? -eq 0 ]] || error "create failed"
17916 }
17917 run_test 161d "create with concurrent .lustre/fid access"
17918
17919 check_path() {
17920         local expected="$1"
17921         shift
17922         local fid="$2"
17923
17924         local path
17925         path=$($LFS fid2path "$@")
17926         local rc=$?
17927
17928         if [ $rc -ne 0 ]; then
17929                 error "path looked up of '$expected' failed: rc=$rc"
17930         elif [ "$path" != "$expected" ]; then
17931                 error "path looked up '$path' instead of '$expected'"
17932         else
17933                 echo "FID '$fid' resolves to path '$path' as expected"
17934         fi
17935 }
17936
17937 test_162a() { # was test_162
17938         test_mkdir -p -c1 $DIR/$tdir/d2
17939         touch $DIR/$tdir/d2/$tfile
17940         touch $DIR/$tdir/d2/x1
17941         touch $DIR/$tdir/d2/x2
17942         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17943         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17944         # regular file
17945         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17946         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17947
17948         # softlink
17949         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17950         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17951         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17952
17953         # softlink to wrong file
17954         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17955         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17956         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17957
17958         # hardlink
17959         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17960         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17961         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17962         # fid2path dir/fsname should both work
17963         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17964         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17965
17966         # hardlink count: check that there are 2 links
17967         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17968         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17969
17970         # hardlink indexing: remove the first link
17971         rm $DIR/$tdir/d2/p/q/r/hlink
17972         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17973 }
17974 run_test 162a "path lookup sanity"
17975
17976 test_162b() {
17977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17979
17980         mkdir $DIR/$tdir
17981         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17982                                 error "create striped dir failed"
17983
17984         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17985                                         tail -n 1 | awk '{print $2}')
17986         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17987
17988         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17989         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17990
17991         # regular file
17992         for ((i=0;i<5;i++)); do
17993                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17994                         error "get fid for f$i failed"
17995                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17996
17997                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17998                         error "get fid for d$i failed"
17999                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18000         done
18001
18002         return 0
18003 }
18004 run_test 162b "striped directory path lookup sanity"
18005
18006 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18007 test_162c() {
18008         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18009                 skip "Need MDS version at least 2.7.51"
18010
18011         local lpath=$tdir.local
18012         local rpath=$tdir.remote
18013
18014         test_mkdir $DIR/$lpath
18015         test_mkdir $DIR/$rpath
18016
18017         for ((i = 0; i <= 101; i++)); do
18018                 lpath="$lpath/$i"
18019                 mkdir $DIR/$lpath
18020                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18021                         error "get fid for local directory $DIR/$lpath failed"
18022                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18023
18024                 rpath="$rpath/$i"
18025                 test_mkdir $DIR/$rpath
18026                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18027                         error "get fid for remote directory $DIR/$rpath failed"
18028                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18029         done
18030
18031         return 0
18032 }
18033 run_test 162c "fid2path works with paths 100 or more directories deep"
18034
18035 oalr_event_count() {
18036         local event="${1}"
18037         local trace="${2}"
18038
18039         awk -v name="${FSNAME}-OST0000" \
18040             -v event="${event}" \
18041             '$1 == "TRACE" && $2 == event && $3 == name' \
18042             "${trace}" |
18043         wc -l
18044 }
18045
18046 oalr_expect_event_count() {
18047         local event="${1}"
18048         local trace="${2}"
18049         local expect="${3}"
18050         local count
18051
18052         count=$(oalr_event_count "${event}" "${trace}")
18053         if ((count == expect)); then
18054                 return 0
18055         fi
18056
18057         error_noexit "${event} event count was '${count}', expected ${expect}"
18058         cat "${trace}" >&2
18059         exit 1
18060 }
18061
18062 cleanup_165() {
18063         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18064         stop ost1
18065         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18066 }
18067
18068 setup_165() {
18069         sync # Flush previous IOs so we can count log entries.
18070         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18071         stack_trap cleanup_165 EXIT
18072 }
18073
18074 test_165a() {
18075         local trace="/tmp/${tfile}.trace"
18076         local rc
18077         local count
18078
18079         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18080                 skip "OFD access log unsupported"
18081
18082         setup_165
18083         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18084         sleep 5
18085
18086         do_facet ost1 ofd_access_log_reader --list
18087         stop ost1
18088
18089         do_facet ost1 killall -TERM ofd_access_log_reader
18090         wait
18091         rc=$?
18092
18093         if ((rc != 0)); then
18094                 error "ofd_access_log_reader exited with rc = '${rc}'"
18095         fi
18096
18097         # Parse trace file for discovery events:
18098         oalr_expect_event_count alr_log_add "${trace}" 1
18099         oalr_expect_event_count alr_log_eof "${trace}" 1
18100         oalr_expect_event_count alr_log_free "${trace}" 1
18101 }
18102 run_test 165a "ofd access log discovery"
18103
18104 test_165b() {
18105         local trace="/tmp/${tfile}.trace"
18106         local file="${DIR}/${tfile}"
18107         local pfid1
18108         local pfid2
18109         local -a entry
18110         local rc
18111         local count
18112         local size
18113         local flags
18114
18115         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18116                 skip "OFD access log unsupported"
18117
18118         setup_165
18119         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18120         sleep 5
18121
18122         do_facet ost1 ofd_access_log_reader --list
18123
18124         lfs setstripe -c 1 -i 0 "${file}"
18125         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18126                 error "cannot create '${file}'"
18127
18128         sleep 5
18129         do_facet ost1 killall -TERM ofd_access_log_reader
18130         wait
18131         rc=$?
18132
18133         if ((rc != 0)); then
18134                 error "ofd_access_log_reader exited with rc = '${rc}'"
18135         fi
18136
18137         oalr_expect_event_count alr_log_entry "${trace}" 1
18138
18139         pfid1=$($LFS path2fid "${file}")
18140
18141         # 1     2             3   4    5     6   7    8    9     10
18142         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18143         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18144
18145         echo "entry = '${entry[*]}'" >&2
18146
18147         pfid2=${entry[4]}
18148         if [[ "${pfid1}" != "${pfid2}" ]]; then
18149                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18150         fi
18151
18152         size=${entry[8]}
18153         if ((size != 1048576)); then
18154                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18155         fi
18156
18157         flags=${entry[10]}
18158         if [[ "${flags}" != "w" ]]; then
18159                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18160         fi
18161
18162         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18163         sleep 5
18164
18165         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18166                 error "cannot read '${file}'"
18167         sleep 5
18168
18169         do_facet ost1 killall -TERM ofd_access_log_reader
18170         wait
18171         rc=$?
18172
18173         if ((rc != 0)); then
18174                 error "ofd_access_log_reader exited with rc = '${rc}'"
18175         fi
18176
18177         oalr_expect_event_count alr_log_entry "${trace}" 1
18178
18179         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18180         echo "entry = '${entry[*]}'" >&2
18181
18182         pfid2=${entry[4]}
18183         if [[ "${pfid1}" != "${pfid2}" ]]; then
18184                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18185         fi
18186
18187         size=${entry[8]}
18188         if ((size != 524288)); then
18189                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18190         fi
18191
18192         flags=${entry[10]}
18193         if [[ "${flags}" != "r" ]]; then
18194                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18195         fi
18196 }
18197 run_test 165b "ofd access log entries are produced and consumed"
18198
18199 test_165c() {
18200         local trace="/tmp/${tfile}.trace"
18201         local file="${DIR}/${tdir}/${tfile}"
18202
18203         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18204                 skip "OFD access log unsupported"
18205
18206         test_mkdir "${DIR}/${tdir}"
18207
18208         setup_165
18209         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18210         sleep 5
18211
18212         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18213
18214         # 4096 / 64 = 64. Create twice as many entries.
18215         for ((i = 0; i < 128; i++)); do
18216                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18217                         error "cannot create file"
18218         done
18219
18220         sync
18221
18222         do_facet ost1 killall -TERM ofd_access_log_reader
18223         wait
18224         rc=$?
18225         if ((rc != 0)); then
18226                 error "ofd_access_log_reader exited with rc = '${rc}'"
18227         fi
18228
18229         unlinkmany  "${file}-%d" 128
18230 }
18231 run_test 165c "full ofd access logs do not block IOs"
18232
18233 oal_get_read_count() {
18234         local stats="$1"
18235
18236         # STATS lustre-OST0001 alr_read_count 1
18237
18238         do_facet ost1 cat "${stats}" |
18239         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18240              END { print count; }'
18241 }
18242
18243 oal_expect_read_count() {
18244         local stats="$1"
18245         local count
18246         local expect="$2"
18247
18248         # Ask ofd_access_log_reader to write stats.
18249         do_facet ost1 killall -USR1 ofd_access_log_reader
18250
18251         # Allow some time for things to happen.
18252         sleep 1
18253
18254         count=$(oal_get_read_count "${stats}")
18255         if ((count == expect)); then
18256                 return 0
18257         fi
18258
18259         error_noexit "bad read count, got ${count}, expected ${expect}"
18260         do_facet ost1 cat "${stats}" >&2
18261         exit 1
18262 }
18263
18264 test_165d() {
18265         local stats="/tmp/${tfile}.stats"
18266         local file="${DIR}/${tdir}/${tfile}"
18267         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18268
18269         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18270                 skip "OFD access log unsupported"
18271
18272         test_mkdir "${DIR}/${tdir}"
18273
18274         setup_165
18275         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18276         sleep 5
18277
18278         lfs setstripe -c 1 -i 0 "${file}"
18279
18280         do_facet ost1 lctl set_param "${param}=rw"
18281         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18282                 error "cannot create '${file}'"
18283         oal_expect_read_count "${stats}" 1
18284
18285         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18286                 error "cannot read '${file}'"
18287         oal_expect_read_count "${stats}" 2
18288
18289         do_facet ost1 lctl set_param "${param}=r"
18290         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18291                 error "cannot create '${file}'"
18292         oal_expect_read_count "${stats}" 2
18293
18294         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18295                 error "cannot read '${file}'"
18296         oal_expect_read_count "${stats}" 3
18297
18298         do_facet ost1 lctl set_param "${param}=w"
18299         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18300                 error "cannot create '${file}'"
18301         oal_expect_read_count "${stats}" 4
18302
18303         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18304                 error "cannot read '${file}'"
18305         oal_expect_read_count "${stats}" 4
18306
18307         do_facet ost1 lctl set_param "${param}=0"
18308         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18309                 error "cannot create '${file}'"
18310         oal_expect_read_count "${stats}" 4
18311
18312         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18313                 error "cannot read '${file}'"
18314         oal_expect_read_count "${stats}" 4
18315
18316         do_facet ost1 killall -TERM ofd_access_log_reader
18317         wait
18318         rc=$?
18319         if ((rc != 0)); then
18320                 error "ofd_access_log_reader exited with rc = '${rc}'"
18321         fi
18322 }
18323 run_test 165d "ofd_access_log mask works"
18324
18325 test_165e() {
18326         local stats="/tmp/${tfile}.stats"
18327         local file0="${DIR}/${tdir}-0/${tfile}"
18328         local file1="${DIR}/${tdir}-1/${tfile}"
18329
18330         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18331                 skip "OFD access log unsupported"
18332
18333         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18334
18335         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18336         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18337
18338         lfs setstripe -c 1 -i 0 "${file0}"
18339         lfs setstripe -c 1 -i 0 "${file1}"
18340
18341         setup_165
18342         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18343         sleep 5
18344
18345         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18346                 error "cannot create '${file0}'"
18347         sync
18348         oal_expect_read_count "${stats}" 0
18349
18350         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18351                 error "cannot create '${file1}'"
18352         sync
18353         oal_expect_read_count "${stats}" 1
18354
18355         do_facet ost1 killall -TERM ofd_access_log_reader
18356         wait
18357         rc=$?
18358         if ((rc != 0)); then
18359                 error "ofd_access_log_reader exited with rc = '${rc}'"
18360         fi
18361 }
18362 run_test 165e "ofd_access_log MDT index filter works"
18363
18364 test_165f() {
18365         local trace="/tmp/${tfile}.trace"
18366         local rc
18367         local count
18368
18369         setup_165
18370         do_facet ost1 timeout 60 ofd_access_log_reader \
18371                 --exit-on-close --debug=- --trace=- > "${trace}" &
18372         sleep 5
18373         stop ost1
18374
18375         wait
18376         rc=$?
18377
18378         if ((rc != 0)); then
18379                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18380                 cat "${trace}"
18381                 exit 1
18382         fi
18383 }
18384 run_test 165f "ofd_access_log_reader --exit-on-close works"
18385
18386 test_169() {
18387         # do directio so as not to populate the page cache
18388         log "creating a 10 Mb file"
18389         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18390                 error "multiop failed while creating a file"
18391         log "starting reads"
18392         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18393         log "truncating the file"
18394         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18395                 error "multiop failed while truncating the file"
18396         log "killing dd"
18397         kill %+ || true # reads might have finished
18398         echo "wait until dd is finished"
18399         wait
18400         log "removing the temporary file"
18401         rm -rf $DIR/$tfile || error "tmp file removal failed"
18402 }
18403 run_test 169 "parallel read and truncate should not deadlock"
18404
18405 test_170() {
18406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18407
18408         $LCTL clear     # bug 18514
18409         $LCTL debug_daemon start $TMP/${tfile}_log_good
18410         touch $DIR/$tfile
18411         $LCTL debug_daemon stop
18412         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18413                 error "sed failed to read log_good"
18414
18415         $LCTL debug_daemon start $TMP/${tfile}_log_good
18416         rm -rf $DIR/$tfile
18417         $LCTL debug_daemon stop
18418
18419         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18420                error "lctl df log_bad failed"
18421
18422         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18423         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18424
18425         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18426         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18427
18428         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18429                 error "bad_line good_line1 good_line2 are empty"
18430
18431         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18432         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18433         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18434
18435         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18436         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18437         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18438
18439         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18440                 error "bad_line_new good_line_new are empty"
18441
18442         local expected_good=$((good_line1 + good_line2*2))
18443
18444         rm -f $TMP/${tfile}*
18445         # LU-231, short malformed line may not be counted into bad lines
18446         if [ $bad_line -ne $bad_line_new ] &&
18447                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18448                 error "expected $bad_line bad lines, but got $bad_line_new"
18449                 return 1
18450         fi
18451
18452         if [ $expected_good -ne $good_line_new ]; then
18453                 error "expected $expected_good good lines, but got $good_line_new"
18454                 return 2
18455         fi
18456         true
18457 }
18458 run_test 170 "test lctl df to handle corrupted log ====================="
18459
18460 test_171() { # bug20592
18461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18462
18463         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18464         $LCTL set_param fail_loc=0x50e
18465         $LCTL set_param fail_val=3000
18466         multiop_bg_pause $DIR/$tfile O_s || true
18467         local MULTIPID=$!
18468         kill -USR1 $MULTIPID
18469         # cause log dump
18470         sleep 3
18471         wait $MULTIPID
18472         if dmesg | grep "recursive fault"; then
18473                 error "caught a recursive fault"
18474         fi
18475         $LCTL set_param fail_loc=0
18476         true
18477 }
18478 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18479
18480 test_172() {
18481
18482         #define OBD_FAIL_OBD_CLEANUP  0x60e
18483         $LCTL set_param fail_loc=0x60e
18484         umount $MOUNT || error "umount $MOUNT failed"
18485         stack_trap "mount_client $MOUNT"
18486
18487         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18488                 error "no client OBDs are remained"
18489
18490         $LCTL dl | while read devno state type name foo; do
18491                 case $type in
18492                 lov|osc|lmv|mdc)
18493                         $LCTL --device $name cleanup
18494                         $LCTL --device $name detach
18495                         ;;
18496                 *)
18497                         # skip server devices
18498                         ;;
18499                 esac
18500         done
18501
18502         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18503                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18504                 error "some client OBDs are still remained"
18505         fi
18506
18507 }
18508 run_test 172 "manual device removal with lctl cleanup/detach ======"
18509
18510 # it would be good to share it with obdfilter-survey/iokit-libecho code
18511 setup_obdecho_osc () {
18512         local rc=0
18513         local ost_nid=$1
18514         local obdfilter_name=$2
18515         echo "Creating new osc for $obdfilter_name on $ost_nid"
18516         # make sure we can find loopback nid
18517         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18518
18519         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18520                            ${obdfilter_name}_osc_UUID || rc=2; }
18521         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18522                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18523         return $rc
18524 }
18525
18526 cleanup_obdecho_osc () {
18527         local obdfilter_name=$1
18528         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18529         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18530         return 0
18531 }
18532
18533 obdecho_test() {
18534         local OBD=$1
18535         local node=$2
18536         local pages=${3:-64}
18537         local rc=0
18538         local id
18539
18540         local count=10
18541         local obd_size=$(get_obd_size $node $OBD)
18542         local page_size=$(get_page_size $node)
18543         if [[ -n "$obd_size" ]]; then
18544                 local new_count=$((obd_size / (pages * page_size / 1024)))
18545                 [[ $new_count -ge $count ]] || count=$new_count
18546         fi
18547
18548         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18549         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18550                            rc=2; }
18551         if [ $rc -eq 0 ]; then
18552             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18553             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18554         fi
18555         echo "New object id is $id"
18556         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18557                            rc=4; }
18558         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18559                            "test_brw $count w v $pages $id" || rc=4; }
18560         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18561                            rc=4; }
18562         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18563                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18564         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18565                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18566         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18567         return $rc
18568 }
18569
18570 test_180a() {
18571         skip "obdecho on osc is no longer supported"
18572 }
18573 run_test 180a "test obdecho on osc"
18574
18575 test_180b() {
18576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18577         remote_ost_nodsh && skip "remote OST with nodsh"
18578
18579         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18580                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18581                 error "failed to load module obdecho"
18582
18583         local target=$(do_facet ost1 $LCTL dl |
18584                        awk '/obdfilter/ { print $4; exit; }')
18585
18586         if [ -n "$target" ]; then
18587                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18588         else
18589                 do_facet ost1 $LCTL dl
18590                 error "there is no obdfilter target on ost1"
18591         fi
18592 }
18593 run_test 180b "test obdecho directly on obdfilter"
18594
18595 test_180c() { # LU-2598
18596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18597         remote_ost_nodsh && skip "remote OST with nodsh"
18598         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18599                 skip "Need MDS version at least 2.4.0"
18600
18601         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18602                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18603                 error "failed to load module obdecho"
18604
18605         local target=$(do_facet ost1 $LCTL dl |
18606                        awk '/obdfilter/ { print $4; exit; }')
18607
18608         if [ -n "$target" ]; then
18609                 local pages=16384 # 64MB bulk I/O RPC size
18610
18611                 obdecho_test "$target" ost1 "$pages" ||
18612                         error "obdecho_test with pages=$pages failed with $?"
18613         else
18614                 do_facet ost1 $LCTL dl
18615                 error "there is no obdfilter target on ost1"
18616         fi
18617 }
18618 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18619
18620 test_181() { # bug 22177
18621         test_mkdir $DIR/$tdir
18622         # create enough files to index the directory
18623         createmany -o $DIR/$tdir/foobar 4000
18624         # print attributes for debug purpose
18625         lsattr -d .
18626         # open dir
18627         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18628         MULTIPID=$!
18629         # remove the files & current working dir
18630         unlinkmany $DIR/$tdir/foobar 4000
18631         rmdir $DIR/$tdir
18632         kill -USR1 $MULTIPID
18633         wait $MULTIPID
18634         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18635         return 0
18636 }
18637 run_test 181 "Test open-unlinked dir ========================"
18638
18639 test_182a() {
18640         local fcount=1000
18641         local tcount=10
18642
18643         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18644
18645         $LCTL set_param mdc.*.rpc_stats=clear
18646
18647         for (( i = 0; i < $tcount; i++ )) ; do
18648                 mkdir $DIR/$tdir/$i
18649         done
18650
18651         for (( i = 0; i < $tcount; i++ )) ; do
18652                 createmany -o $DIR/$tdir/$i/f- $fcount &
18653         done
18654         wait
18655
18656         for (( i = 0; i < $tcount; i++ )) ; do
18657                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18658         done
18659         wait
18660
18661         $LCTL get_param mdc.*.rpc_stats
18662
18663         rm -rf $DIR/$tdir
18664 }
18665 run_test 182a "Test parallel modify metadata operations from mdc"
18666
18667 test_182b() {
18668         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18669         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18670         local dcount=1000
18671         local tcount=10
18672         local stime
18673         local etime
18674         local delta
18675
18676         do_facet mds1 $LCTL list_param \
18677                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18678                 skip "MDS lacks parallel RPC handling"
18679
18680         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18681
18682         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18683                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18684
18685         stime=$(date +%s)
18686         createmany -i 0 -d $DIR/$tdir/t- $tcount
18687
18688         for (( i = 0; i < $tcount; i++ )) ; do
18689                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18690         done
18691         wait
18692         etime=$(date +%s)
18693         delta=$((etime - stime))
18694         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18695
18696         stime=$(date +%s)
18697         for (( i = 0; i < $tcount; i++ )) ; do
18698                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18699         done
18700         wait
18701         etime=$(date +%s)
18702         delta=$((etime - stime))
18703         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18704
18705         rm -rf $DIR/$tdir
18706
18707         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18708
18709         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18710
18711         stime=$(date +%s)
18712         createmany -i 0 -d $DIR/$tdir/t- $tcount
18713
18714         for (( i = 0; i < $tcount; i++ )) ; do
18715                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18716         done
18717         wait
18718         etime=$(date +%s)
18719         delta=$((etime - stime))
18720         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18721
18722         stime=$(date +%s)
18723         for (( i = 0; i < $tcount; i++ )) ; do
18724                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18725         done
18726         wait
18727         etime=$(date +%s)
18728         delta=$((etime - stime))
18729         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18730
18731         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18732 }
18733 run_test 182b "Test parallel modify metadata operations from osp"
18734
18735 test_183() { # LU-2275
18736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18737         remote_mds_nodsh && skip "remote MDS with nodsh"
18738         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18739                 skip "Need MDS version at least 2.3.56"
18740
18741         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18742         echo aaa > $DIR/$tdir/$tfile
18743
18744 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18745         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18746
18747         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18748         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18749
18750         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18751
18752         # Flush negative dentry cache
18753         touch $DIR/$tdir/$tfile
18754
18755         # We are not checking for any leaked references here, they'll
18756         # become evident next time we do cleanup with module unload.
18757         rm -rf $DIR/$tdir
18758 }
18759 run_test 183 "No crash or request leak in case of strange dispositions ========"
18760
18761 # test suite 184 is for LU-2016, LU-2017
18762 test_184a() {
18763         check_swap_layouts_support
18764
18765         dir0=$DIR/$tdir/$testnum
18766         test_mkdir -p -c1 $dir0
18767         ref1=/etc/passwd
18768         ref2=/etc/group
18769         file1=$dir0/f1
18770         file2=$dir0/f2
18771         $LFS setstripe -c1 $file1
18772         cp $ref1 $file1
18773         $LFS setstripe -c2 $file2
18774         cp $ref2 $file2
18775         gen1=$($LFS getstripe -g $file1)
18776         gen2=$($LFS getstripe -g $file2)
18777
18778         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18779         gen=$($LFS getstripe -g $file1)
18780         [[ $gen1 != $gen ]] ||
18781                 error "Layout generation on $file1 does not change"
18782         gen=$($LFS getstripe -g $file2)
18783         [[ $gen2 != $gen ]] ||
18784                 error "Layout generation on $file2 does not change"
18785
18786         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18787         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18788
18789         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18790 }
18791 run_test 184a "Basic layout swap"
18792
18793 test_184b() {
18794         check_swap_layouts_support
18795
18796         dir0=$DIR/$tdir/$testnum
18797         mkdir -p $dir0 || error "creating dir $dir0"
18798         file1=$dir0/f1
18799         file2=$dir0/f2
18800         file3=$dir0/f3
18801         dir1=$dir0/d1
18802         dir2=$dir0/d2
18803         mkdir $dir1 $dir2
18804         $LFS setstripe -c1 $file1
18805         $LFS setstripe -c2 $file2
18806         $LFS setstripe -c1 $file3
18807         chown $RUNAS_ID $file3
18808         gen1=$($LFS getstripe -g $file1)
18809         gen2=$($LFS getstripe -g $file2)
18810
18811         $LFS swap_layouts $dir1 $dir2 &&
18812                 error "swap of directories layouts should fail"
18813         $LFS swap_layouts $dir1 $file1 &&
18814                 error "swap of directory and file layouts should fail"
18815         $RUNAS $LFS swap_layouts $file1 $file2 &&
18816                 error "swap of file we cannot write should fail"
18817         $LFS swap_layouts $file1 $file3 &&
18818                 error "swap of file with different owner should fail"
18819         /bin/true # to clear error code
18820 }
18821 run_test 184b "Forbidden layout swap (will generate errors)"
18822
18823 test_184c() {
18824         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18825         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18826         check_swap_layouts_support
18827         check_swap_layout_no_dom $DIR
18828
18829         local dir0=$DIR/$tdir/$testnum
18830         mkdir -p $dir0 || error "creating dir $dir0"
18831
18832         local ref1=$dir0/ref1
18833         local ref2=$dir0/ref2
18834         local file1=$dir0/file1
18835         local file2=$dir0/file2
18836         # create a file large enough for the concurrent test
18837         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18838         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18839         echo "ref file size: ref1($(stat -c %s $ref1))," \
18840              "ref2($(stat -c %s $ref2))"
18841
18842         cp $ref2 $file2
18843         dd if=$ref1 of=$file1 bs=16k &
18844         local DD_PID=$!
18845
18846         # Make sure dd starts to copy file, but wait at most 5 seconds
18847         local loops=0
18848         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18849
18850         $LFS swap_layouts $file1 $file2
18851         local rc=$?
18852         wait $DD_PID
18853         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18854         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18855
18856         # how many bytes copied before swapping layout
18857         local copied=$(stat -c %s $file2)
18858         local remaining=$(stat -c %s $ref1)
18859         remaining=$((remaining - copied))
18860         echo "Copied $copied bytes before swapping layout..."
18861
18862         cmp -n $copied $file1 $ref2 | grep differ &&
18863                 error "Content mismatch [0, $copied) of ref2 and file1"
18864         cmp -n $copied $file2 $ref1 ||
18865                 error "Content mismatch [0, $copied) of ref1 and file2"
18866         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18867                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18868
18869         # clean up
18870         rm -f $ref1 $ref2 $file1 $file2
18871 }
18872 run_test 184c "Concurrent write and layout swap"
18873
18874 test_184d() {
18875         check_swap_layouts_support
18876         check_swap_layout_no_dom $DIR
18877         [ -z "$(which getfattr 2>/dev/null)" ] &&
18878                 skip_env "no getfattr command"
18879
18880         local file1=$DIR/$tdir/$tfile-1
18881         local file2=$DIR/$tdir/$tfile-2
18882         local file3=$DIR/$tdir/$tfile-3
18883         local lovea1
18884         local lovea2
18885
18886         mkdir -p $DIR/$tdir
18887         touch $file1 || error "create $file1 failed"
18888         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18889                 error "create $file2 failed"
18890         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18891                 error "create $file3 failed"
18892         lovea1=$(get_layout_param $file1)
18893
18894         $LFS swap_layouts $file2 $file3 ||
18895                 error "swap $file2 $file3 layouts failed"
18896         $LFS swap_layouts $file1 $file2 ||
18897                 error "swap $file1 $file2 layouts failed"
18898
18899         lovea2=$(get_layout_param $file2)
18900         echo "$lovea1"
18901         echo "$lovea2"
18902         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18903
18904         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18905         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18906 }
18907 run_test 184d "allow stripeless layouts swap"
18908
18909 test_184e() {
18910         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18911                 skip "Need MDS version at least 2.6.94"
18912         check_swap_layouts_support
18913         check_swap_layout_no_dom $DIR
18914         [ -z "$(which getfattr 2>/dev/null)" ] &&
18915                 skip_env "no getfattr command"
18916
18917         local file1=$DIR/$tdir/$tfile-1
18918         local file2=$DIR/$tdir/$tfile-2
18919         local file3=$DIR/$tdir/$tfile-3
18920         local lovea
18921
18922         mkdir -p $DIR/$tdir
18923         touch $file1 || error "create $file1 failed"
18924         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18925                 error "create $file2 failed"
18926         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18927                 error "create $file3 failed"
18928
18929         $LFS swap_layouts $file1 $file2 ||
18930                 error "swap $file1 $file2 layouts failed"
18931
18932         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18933         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18934
18935         echo 123 > $file1 || error "Should be able to write into $file1"
18936
18937         $LFS swap_layouts $file1 $file3 ||
18938                 error "swap $file1 $file3 layouts failed"
18939
18940         echo 123 > $file1 || error "Should be able to write into $file1"
18941
18942         rm -rf $file1 $file2 $file3
18943 }
18944 run_test 184e "Recreate layout after stripeless layout swaps"
18945
18946 test_184f() {
18947         # Create a file with name longer than sizeof(struct stat) ==
18948         # 144 to see if we can get chars from the file name to appear
18949         # in the returned striping. Note that 'f' == 0x66.
18950         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18951
18952         mkdir -p $DIR/$tdir
18953         mcreate $DIR/$tdir/$file
18954         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18955                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18956         fi
18957 }
18958 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18959
18960 test_185() { # LU-2441
18961         # LU-3553 - no volatile file support in old servers
18962         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18963                 skip "Need MDS version at least 2.3.60"
18964
18965         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18966         touch $DIR/$tdir/spoo
18967         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18968         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18969                 error "cannot create/write a volatile file"
18970         [ "$FILESET" == "" ] &&
18971         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18972                 error "FID is still valid after close"
18973
18974         multiop_bg_pause $DIR/$tdir vVw4096_c
18975         local multi_pid=$!
18976
18977         local OLD_IFS=$IFS
18978         IFS=":"
18979         local fidv=($fid)
18980         IFS=$OLD_IFS
18981         # assume that the next FID for this client is sequential, since stdout
18982         # is unfortunately eaten by multiop_bg_pause
18983         local n=$((${fidv[1]} + 1))
18984         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18985         if [ "$FILESET" == "" ]; then
18986                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18987                         error "FID is missing before close"
18988         fi
18989         kill -USR1 $multi_pid
18990         # 1 second delay, so if mtime change we will see it
18991         sleep 1
18992         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18993         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18994 }
18995 run_test 185 "Volatile file support"
18996
18997 function create_check_volatile() {
18998         local idx=$1
18999         local tgt
19000
19001         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19002         local PID=$!
19003         sleep 1
19004         local FID=$(cat /tmp/${tfile}.fid)
19005         [ "$FID" == "" ] && error "can't get FID for volatile"
19006         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19007         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19008         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19009         kill -USR1 $PID
19010         wait
19011         sleep 1
19012         cancel_lru_locks mdc # flush opencache
19013         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19014         return 0
19015 }
19016
19017 test_185a(){
19018         # LU-12516 - volatile creation via .lustre
19019         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19020                 skip "Need MDS version at least 2.3.55"
19021
19022         create_check_volatile 0
19023         [ $MDSCOUNT -lt 2 ] && return 0
19024
19025         # DNE case
19026         create_check_volatile 1
19027
19028         return 0
19029 }
19030 run_test 185a "Volatile file creation in .lustre/fid/"
19031
19032 test_187a() {
19033         remote_mds_nodsh && skip "remote MDS with nodsh"
19034         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19035                 skip "Need MDS version at least 2.3.0"
19036
19037         local dir0=$DIR/$tdir/$testnum
19038         mkdir -p $dir0 || error "creating dir $dir0"
19039
19040         local file=$dir0/file1
19041         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19042         local dv1=$($LFS data_version $file)
19043         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19044         local dv2=$($LFS data_version $file)
19045         [[ $dv1 != $dv2 ]] ||
19046                 error "data version did not change on write $dv1 == $dv2"
19047
19048         # clean up
19049         rm -f $file1
19050 }
19051 run_test 187a "Test data version change"
19052
19053 test_187b() {
19054         remote_mds_nodsh && skip "remote MDS with nodsh"
19055         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19056                 skip "Need MDS version at least 2.3.0"
19057
19058         local dir0=$DIR/$tdir/$testnum
19059         mkdir -p $dir0 || error "creating dir $dir0"
19060
19061         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19062         [[ ${DV[0]} != ${DV[1]} ]] ||
19063                 error "data version did not change on write"\
19064                       " ${DV[0]} == ${DV[1]}"
19065
19066         # clean up
19067         rm -f $file1
19068 }
19069 run_test 187b "Test data version change on volatile file"
19070
19071 test_200() {
19072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19073         remote_mgs_nodsh && skip "remote MGS with nodsh"
19074         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19075
19076         local POOL=${POOL:-cea1}
19077         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19078         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19079         # Pool OST targets
19080         local first_ost=0
19081         local last_ost=$(($OSTCOUNT - 1))
19082         local ost_step=2
19083         local ost_list=$(seq $first_ost $ost_step $last_ost)
19084         local ost_range="$first_ost $last_ost $ost_step"
19085         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19086         local file_dir=$POOL_ROOT/file_tst
19087         local subdir=$test_path/subdir
19088         local rc=0
19089
19090         while : ; do
19091                 # former test_200a test_200b
19092                 pool_add $POOL                          || { rc=$? ; break; }
19093                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19094                 # former test_200c test_200d
19095                 mkdir -p $test_path
19096                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19097                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19098                 mkdir -p $subdir
19099                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19100                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19101                                                         || { rc=$? ; break; }
19102                 # former test_200e test_200f
19103                 local files=$((OSTCOUNT*3))
19104                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19105                                                         || { rc=$? ; break; }
19106                 pool_create_files $POOL $file_dir $files "$ost_list" \
19107                                                         || { rc=$? ; break; }
19108                 # former test_200g test_200h
19109                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19110                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19111
19112                 # former test_201a test_201b test_201c
19113                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19114
19115                 local f=$test_path/$tfile
19116                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19117                 pool_remove $POOL $f                    || { rc=$? ; break; }
19118                 break
19119         done
19120
19121         destroy_test_pools
19122
19123         return $rc
19124 }
19125 run_test 200 "OST pools"
19126
19127 # usage: default_attr <count | size | offset>
19128 default_attr() {
19129         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19130 }
19131
19132 # usage: check_default_stripe_attr
19133 check_default_stripe_attr() {
19134         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19135         case $1 in
19136         --stripe-count|-c)
19137                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19138         --stripe-size|-S)
19139                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19140         --stripe-index|-i)
19141                 EXPECTED=-1;;
19142         *)
19143                 error "unknown getstripe attr '$1'"
19144         esac
19145
19146         [ $ACTUAL == $EXPECTED ] ||
19147                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19148 }
19149
19150 test_204a() {
19151         test_mkdir $DIR/$tdir
19152         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19153
19154         check_default_stripe_attr --stripe-count
19155         check_default_stripe_attr --stripe-size
19156         check_default_stripe_attr --stripe-index
19157 }
19158 run_test 204a "Print default stripe attributes"
19159
19160 test_204b() {
19161         test_mkdir $DIR/$tdir
19162         $LFS setstripe --stripe-count 1 $DIR/$tdir
19163
19164         check_default_stripe_attr --stripe-size
19165         check_default_stripe_attr --stripe-index
19166 }
19167 run_test 204b "Print default stripe size and offset"
19168
19169 test_204c() {
19170         test_mkdir $DIR/$tdir
19171         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19172
19173         check_default_stripe_attr --stripe-count
19174         check_default_stripe_attr --stripe-index
19175 }
19176 run_test 204c "Print default stripe count and offset"
19177
19178 test_204d() {
19179         test_mkdir $DIR/$tdir
19180         $LFS setstripe --stripe-index 0 $DIR/$tdir
19181
19182         check_default_stripe_attr --stripe-count
19183         check_default_stripe_attr --stripe-size
19184 }
19185 run_test 204d "Print default stripe count and size"
19186
19187 test_204e() {
19188         test_mkdir $DIR/$tdir
19189         $LFS setstripe -d $DIR/$tdir
19190
19191         check_default_stripe_attr --stripe-count --raw
19192         check_default_stripe_attr --stripe-size --raw
19193         check_default_stripe_attr --stripe-index --raw
19194 }
19195 run_test 204e "Print raw stripe attributes"
19196
19197 test_204f() {
19198         test_mkdir $DIR/$tdir
19199         $LFS setstripe --stripe-count 1 $DIR/$tdir
19200
19201         check_default_stripe_attr --stripe-size --raw
19202         check_default_stripe_attr --stripe-index --raw
19203 }
19204 run_test 204f "Print raw stripe size and offset"
19205
19206 test_204g() {
19207         test_mkdir $DIR/$tdir
19208         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19209
19210         check_default_stripe_attr --stripe-count --raw
19211         check_default_stripe_attr --stripe-index --raw
19212 }
19213 run_test 204g "Print raw stripe count and offset"
19214
19215 test_204h() {
19216         test_mkdir $DIR/$tdir
19217         $LFS setstripe --stripe-index 0 $DIR/$tdir
19218
19219         check_default_stripe_attr --stripe-count --raw
19220         check_default_stripe_attr --stripe-size --raw
19221 }
19222 run_test 204h "Print raw stripe count and size"
19223
19224 # Figure out which job scheduler is being used, if any,
19225 # or use a fake one
19226 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19227         JOBENV=SLURM_JOB_ID
19228 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19229         JOBENV=LSB_JOBID
19230 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19231         JOBENV=PBS_JOBID
19232 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19233         JOBENV=LOADL_STEP_ID
19234 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19235         JOBENV=JOB_ID
19236 else
19237         $LCTL list_param jobid_name > /dev/null 2>&1
19238         if [ $? -eq 0 ]; then
19239                 JOBENV=nodelocal
19240         else
19241                 JOBENV=FAKE_JOBID
19242         fi
19243 fi
19244 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19245
19246 verify_jobstats() {
19247         local cmd=($1)
19248         shift
19249         local facets="$@"
19250
19251 # we don't really need to clear the stats for this test to work, since each
19252 # command has a unique jobid, but it makes debugging easier if needed.
19253 #       for facet in $facets; do
19254 #               local dev=$(convert_facet2label $facet)
19255 #               # clear old jobstats
19256 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19257 #       done
19258
19259         # use a new JobID for each test, or we might see an old one
19260         [ "$JOBENV" = "FAKE_JOBID" ] &&
19261                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19262
19263         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19264
19265         [ "$JOBENV" = "nodelocal" ] && {
19266                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19267                 $LCTL set_param jobid_name=$FAKE_JOBID
19268                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19269         }
19270
19271         log "Test: ${cmd[*]}"
19272         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19273
19274         if [ $JOBENV = "FAKE_JOBID" ]; then
19275                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19276         else
19277                 ${cmd[*]}
19278         fi
19279
19280         # all files are created on OST0000
19281         for facet in $facets; do
19282                 local stats="*.$(convert_facet2label $facet).job_stats"
19283
19284                 # strip out libtool wrappers for in-tree executables
19285                 if (( $(do_facet $facet lctl get_param $stats |
19286                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19287                         do_facet $facet lctl get_param $stats
19288                         error "No jobstats for $JOBVAL found on $facet::$stats"
19289                 fi
19290         done
19291 }
19292
19293 jobstats_set() {
19294         local new_jobenv=$1
19295
19296         set_persistent_param_and_check client "jobid_var" \
19297                 "$FSNAME.sys.jobid_var" $new_jobenv
19298 }
19299
19300 test_205a() { # Job stats
19301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19302         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19303                 skip "Need MDS version with at least 2.7.1"
19304         remote_mgs_nodsh && skip "remote MGS with nodsh"
19305         remote_mds_nodsh && skip "remote MDS with nodsh"
19306         remote_ost_nodsh && skip "remote OST with nodsh"
19307         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19308                 skip "Server doesn't support jobstats"
19309         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19310
19311         local old_jobenv=$($LCTL get_param -n jobid_var)
19312         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19313
19314         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19315                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19316         else
19317                 stack_trap "do_facet mgs $PERM_CMD \
19318                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19319         fi
19320         changelog_register
19321
19322         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19323                                 mdt.*.job_cleanup_interval | head -n 1)
19324         local new_interval=5
19325         do_facet $SINGLEMDS \
19326                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19327         stack_trap "do_facet $SINGLEMDS \
19328                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19329         local start=$SECONDS
19330
19331         local cmd
19332         # mkdir
19333         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19334         verify_jobstats "$cmd" "$SINGLEMDS"
19335         # rmdir
19336         cmd="rmdir $DIR/$tdir"
19337         verify_jobstats "$cmd" "$SINGLEMDS"
19338         # mkdir on secondary MDT
19339         if [ $MDSCOUNT -gt 1 ]; then
19340                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19341                 verify_jobstats "$cmd" "mds2"
19342         fi
19343         # mknod
19344         cmd="mknod $DIR/$tfile c 1 3"
19345         verify_jobstats "$cmd" "$SINGLEMDS"
19346         # unlink
19347         cmd="rm -f $DIR/$tfile"
19348         verify_jobstats "$cmd" "$SINGLEMDS"
19349         # create all files on OST0000 so verify_jobstats can find OST stats
19350         # open & close
19351         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19352         verify_jobstats "$cmd" "$SINGLEMDS"
19353         # setattr
19354         cmd="touch $DIR/$tfile"
19355         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19356         # write
19357         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19358         verify_jobstats "$cmd" "ost1"
19359         # read
19360         cancel_lru_locks osc
19361         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19362         verify_jobstats "$cmd" "ost1"
19363         # truncate
19364         cmd="$TRUNCATE $DIR/$tfile 0"
19365         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19366         # rename
19367         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19368         verify_jobstats "$cmd" "$SINGLEMDS"
19369         # jobstats expiry - sleep until old stats should be expired
19370         local left=$((new_interval + 5 - (SECONDS - start)))
19371         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19372                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19373                         "0" $left
19374         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19375         verify_jobstats "$cmd" "$SINGLEMDS"
19376         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19377             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19378
19379         # Ensure that jobid are present in changelog (if supported by MDS)
19380         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19381                 changelog_dump | tail -10
19382                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19383                 [ $jobids -eq 9 ] ||
19384                         error "Wrong changelog jobid count $jobids != 9"
19385
19386                 # LU-5862
19387                 JOBENV="disable"
19388                 jobstats_set $JOBENV
19389                 touch $DIR/$tfile
19390                 changelog_dump | grep $tfile
19391                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19392                 [ $jobids -eq 0 ] ||
19393                         error "Unexpected jobids when jobid_var=$JOBENV"
19394         fi
19395
19396         # test '%j' access to environment variable - if supported
19397         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19398                 JOBENV="JOBCOMPLEX"
19399                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19400
19401                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19402         fi
19403
19404         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19405                 JOBENV="JOBCOMPLEX"
19406                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19407
19408                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19409         fi
19410
19411         # test '%j' access to per-session jobid - if supported
19412         if lctl list_param jobid_this_session > /dev/null 2>&1
19413         then
19414                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19415                 lctl set_param jobid_this_session=$USER
19416
19417                 JOBENV="JOBCOMPLEX"
19418                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19419
19420                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19421         fi
19422 }
19423 run_test 205a "Verify job stats"
19424
19425 # LU-13117, LU-13597
19426 test_205b() {
19427         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19428                 skip "Need MDS version at least 2.13.54.91"
19429
19430         local job_stats="mdt.*.job_stats"
19431         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19432
19433         do_facet mds1 $LCTL set_param $job_stats=clear
19434
19435         # Setting jobid_var to USER might not be supported
19436         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19437         $LCTL set_param jobid_var=USER || true
19438         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19439         $LCTL set_param jobid_name="%j.%e.%u"
19440
19441         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19442         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19443                 { do_facet mds1 $LCTL get_param $job_stats;
19444                   error "Unexpected jobid found"; }
19445         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19446                 { do_facet mds1 $LCTL get_param $job_stats;
19447                   error "wrong job_stats format found"; }
19448
19449         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19450                 echo "MDS does not yet escape jobid" && return 0
19451         $LCTL set_param jobid_var=TEST205b
19452         env -i TEST205b="has sp" touch $DIR/$tfile.2
19453         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19454                 { do_facet mds1 $LCTL get_param $job_stats;
19455                   error "jobid not escaped"; }
19456 }
19457 run_test 205b "Verify job stats jobid and output format"
19458
19459 # LU-13733
19460 test_205c() {
19461         $LCTL set_param llite.*.stats=0
19462         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19463         $LCTL get_param llite.*.stats
19464         $LCTL get_param llite.*.stats | grep \
19465                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19466                         error "wrong client stats format found"
19467 }
19468 run_test 205c "Verify client stats format"
19469
19470 test_205d() {
19471         local file=$DIR/$tdir/$tfile
19472
19473         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19474                 skip "need lustre >= 2.15.53 for lljobstat"
19475         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19476                 skip "need lustre >= 2.15.53 for lljobstat"
19477         verify_yaml_available || skip_env "YAML verification not installed"
19478
19479         test_mkdir -i 0 $DIR/$tdir
19480         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19481
19482         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19483                 error "failed to write data to $file"
19484         mv $file $file.2
19485
19486         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19487         echo -n 'verify rename_stats...'
19488         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19489                 verify_yaml || error "rename_stats is not valid YAML"
19490         echo " OK"
19491
19492         echo -n 'verify mdt job_stats...'
19493         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19494                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19495         echo " OK"
19496
19497         echo -n 'verify ost job_stats...'
19498         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19499                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19500         echo " OK"
19501 }
19502 run_test 205d "verify the format of some stats files"
19503
19504 test_205e() {
19505         local ops_comma
19506         local file=$DIR/$tdir/$tfile
19507
19508         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19509                 skip "need lustre >= 2.15.53 for lljobstat"
19510         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19511                 skip "need lustre >= 2.15.53 for lljobstat"
19512         verify_yaml_available || skip_env "YAML verification not installed"
19513
19514         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19515
19516         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19517                 error "failed to create $file on ost1"
19518         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19519                 error "failed to write data to $file"
19520
19521         do_facet mds1 "$LCTL get_param *.*.job_stats"
19522         do_facet ost1 "$LCTL get_param *.*.job_stats"
19523
19524         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19525         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19526                 error "The output of lljobstat is not an valid YAML"
19527
19528         # verify that job dd.0 does exist and has some ops on ost1
19529         # typically this line is like:
19530         # - dd.0:            {ops: 20, ...}
19531         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19532                     awk '$2=="dd.0:" {print $4}')
19533
19534         (( ${ops_comma%,} >= 10 )) ||
19535                 error "cannot find job dd.0 with ops >= 10"
19536 }
19537 run_test 205e "verify the output of lljobstat"
19538
19539 test_205f() {
19540         verify_yaml_available || skip_env "YAML verification not installed"
19541
19542         # check both qos_ost_weights and qos_mdt_weights
19543         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19544         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19545                 error "qos_ost_weights is not valid YAML"
19546 }
19547 run_test 205f "verify qos_ost_weights YAML format "
19548
19549 # LU-1480, LU-1773 and LU-1657
19550 test_206() {
19551         mkdir -p $DIR/$tdir
19552         $LFS setstripe -c -1 $DIR/$tdir
19553 #define OBD_FAIL_LOV_INIT 0x1403
19554         $LCTL set_param fail_loc=0xa0001403
19555         $LCTL set_param fail_val=1
19556         touch $DIR/$tdir/$tfile || true
19557 }
19558 run_test 206 "fail lov_init_raid0() doesn't lbug"
19559
19560 test_207a() {
19561         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19562         local fsz=`stat -c %s $DIR/$tfile`
19563         cancel_lru_locks mdc
19564
19565         # do not return layout in getattr intent
19566 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19567         $LCTL set_param fail_loc=0x170
19568         local sz=`stat -c %s $DIR/$tfile`
19569
19570         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19571
19572         rm -rf $DIR/$tfile
19573 }
19574 run_test 207a "can refresh layout at glimpse"
19575
19576 test_207b() {
19577         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19578         local cksum=`md5sum $DIR/$tfile`
19579         local fsz=`stat -c %s $DIR/$tfile`
19580         cancel_lru_locks mdc
19581         cancel_lru_locks osc
19582
19583         # do not return layout in getattr intent
19584 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19585         $LCTL set_param fail_loc=0x171
19586
19587         # it will refresh layout after the file is opened but before read issues
19588         echo checksum is "$cksum"
19589         echo "$cksum" |md5sum -c --quiet || error "file differs"
19590
19591         rm -rf $DIR/$tfile
19592 }
19593 run_test 207b "can refresh layout at open"
19594
19595 test_208() {
19596         # FIXME: in this test suite, only RD lease is used. This is okay
19597         # for now as only exclusive open is supported. After generic lease
19598         # is done, this test suite should be revised. - Jinshan
19599
19600         remote_mds_nodsh && skip "remote MDS with nodsh"
19601         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19602                 skip "Need MDS version at least 2.4.52"
19603
19604         echo "==== test 1: verify get lease work"
19605         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19606
19607         echo "==== test 2: verify lease can be broken by upcoming open"
19608         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19609         local PID=$!
19610         sleep 2
19611
19612         $MULTIOP $DIR/$tfile oO_RDWR:c
19613         kill -USR1 $PID && wait $PID || error "break lease error"
19614
19615         echo "==== test 3: verify lease can't be granted if an open already exists"
19616         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19617         local PID=$!
19618         sleep 2
19619
19620         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19621         kill -USR1 $PID && wait $PID || error "open file error"
19622
19623         echo "==== test 4: lease can sustain over recovery"
19624         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19625         PID=$!
19626         sleep 2
19627
19628         fail mds1
19629
19630         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19631
19632         echo "==== test 5: lease broken can't be regained by replay"
19633         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19634         PID=$!
19635         sleep 2
19636
19637         # open file to break lease and then recovery
19638         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19639         fail mds1
19640
19641         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19642
19643         rm -f $DIR/$tfile
19644 }
19645 run_test 208 "Exclusive open"
19646
19647 test_209() {
19648         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19649                 skip_env "must have disp_stripe"
19650
19651         touch $DIR/$tfile
19652         sync; sleep 5; sync;
19653
19654         echo 3 > /proc/sys/vm/drop_caches
19655         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19656                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19657         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19658
19659         # open/close 500 times
19660         for i in $(seq 500); do
19661                 cat $DIR/$tfile
19662         done
19663
19664         echo 3 > /proc/sys/vm/drop_caches
19665         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19666                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19667         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19668
19669         echo "before: $req_before, after: $req_after"
19670         [ $((req_after - req_before)) -ge 300 ] &&
19671                 error "open/close requests are not freed"
19672         return 0
19673 }
19674 run_test 209 "read-only open/close requests should be freed promptly"
19675
19676 test_210() {
19677         local pid
19678
19679         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19680         pid=$!
19681         sleep 1
19682
19683         $LFS getstripe $DIR/$tfile
19684         kill -USR1 $pid
19685         wait $pid || error "multiop failed"
19686
19687         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19688         pid=$!
19689         sleep 1
19690
19691         $LFS getstripe $DIR/$tfile
19692         kill -USR1 $pid
19693         wait $pid || error "multiop failed"
19694 }
19695 run_test 210 "lfs getstripe does not break leases"
19696
19697 test_212() {
19698         size=`date +%s`
19699         size=$((size % 8192 + 1))
19700         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19701         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19702         rm -f $DIR/f212 $DIR/f212.xyz
19703 }
19704 run_test 212 "Sendfile test ============================================"
19705
19706 test_213() {
19707         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19708         cancel_lru_locks osc
19709         lctl set_param fail_loc=0x8000040f
19710         # generate a read lock
19711         cat $DIR/$tfile > /dev/null
19712         # write to the file, it will try to cancel the above read lock.
19713         cat /etc/hosts >> $DIR/$tfile
19714 }
19715 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19716
19717 test_214() { # for bug 20133
19718         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19719         for (( i=0; i < 340; i++ )) ; do
19720                 touch $DIR/$tdir/d214c/a$i
19721         done
19722
19723         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19724         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19725         ls $DIR/d214c || error "ls $DIR/d214c failed"
19726         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19727         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19728 }
19729 run_test 214 "hash-indexed directory test - bug 20133"
19730
19731 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19732 create_lnet_proc_files() {
19733         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19734 }
19735
19736 # counterpart of create_lnet_proc_files
19737 remove_lnet_proc_files() {
19738         rm -f $TMP/lnet_$1.sys
19739 }
19740
19741 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19742 # 3rd arg as regexp for body
19743 check_lnet_proc_stats() {
19744         local l=$(cat "$TMP/lnet_$1" |wc -l)
19745         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19746
19747         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19748 }
19749
19750 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19751 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19752 # optional and can be regexp for 2nd line (lnet.routes case)
19753 check_lnet_proc_entry() {
19754         local blp=2          # blp stands for 'position of 1st line of body'
19755         [ -z "$5" ] || blp=3 # lnet.routes case
19756
19757         local l=$(cat "$TMP/lnet_$1" |wc -l)
19758         # subtracting one from $blp because the body can be empty
19759         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19760
19761         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19762                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19763
19764         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19765                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19766
19767         # bail out if any unexpected line happened
19768         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19769         [ "$?" != 0 ] || error "$2 misformatted"
19770 }
19771
19772 test_215() { # for bugs 18102, 21079, 21517
19773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19774
19775         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19776         local P='[1-9][0-9]*'           # positive numeric
19777         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19778         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19779         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19780         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19781
19782         local L1 # regexp for 1st line
19783         local L2 # regexp for 2nd line (optional)
19784         local BR # regexp for the rest (body)
19785
19786         # lnet.stats should look as 11 space-separated non-negative numerics
19787         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19788         create_lnet_proc_files "stats"
19789         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19790         remove_lnet_proc_files "stats"
19791
19792         # lnet.routes should look like this:
19793         # Routing disabled/enabled
19794         # net hops priority state router
19795         # where net is a string like tcp0, hops > 0, priority >= 0,
19796         # state is up/down,
19797         # router is a string like 192.168.1.1@tcp2
19798         L1="^Routing (disabled|enabled)$"
19799         L2="^net +hops +priority +state +router$"
19800         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19801         create_lnet_proc_files "routes"
19802         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19803         remove_lnet_proc_files "routes"
19804
19805         # lnet.routers should look like this:
19806         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19807         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19808         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19809         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19810         L1="^ref +rtr_ref +alive +router$"
19811         BR="^$P +$P +(up|down) +$NID$"
19812         create_lnet_proc_files "routers"
19813         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19814         remove_lnet_proc_files "routers"
19815
19816         # lnet.peers should look like this:
19817         # nid refs state last max rtr min tx min queue
19818         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19819         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19820         # numeric (0 or >0 or <0), queue >= 0.
19821         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19822         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19823         create_lnet_proc_files "peers"
19824         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19825         remove_lnet_proc_files "peers"
19826
19827         # lnet.buffers  should look like this:
19828         # pages count credits min
19829         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19830         L1="^pages +count +credits +min$"
19831         BR="^ +$N +$N +$I +$I$"
19832         create_lnet_proc_files "buffers"
19833         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19834         remove_lnet_proc_files "buffers"
19835
19836         # lnet.nis should look like this:
19837         # nid status alive refs peer rtr max tx min
19838         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19839         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19840         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19841         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19842         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19843         create_lnet_proc_files "nis"
19844         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19845         remove_lnet_proc_files "nis"
19846
19847         # can we successfully write to lnet.stats?
19848         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19849 }
19850 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19851
19852 test_216() { # bug 20317
19853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19854         remote_ost_nodsh && skip "remote OST with nodsh"
19855
19856         local node
19857         local facets=$(get_facets OST)
19858         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19859
19860         save_lustre_params client "osc.*.contention_seconds" > $p
19861         save_lustre_params $facets \
19862                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19863         save_lustre_params $facets \
19864                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19865         save_lustre_params $facets \
19866                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19867         clear_stats osc.*.osc_stats
19868
19869         # agressive lockless i/o settings
19870         do_nodes $(comma_list $(osts_nodes)) \
19871                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19872                         ldlm.namespaces.filter-*.contended_locks=0 \
19873                         ldlm.namespaces.filter-*.contention_seconds=60"
19874         lctl set_param -n osc.*.contention_seconds=60
19875
19876         $DIRECTIO write $DIR/$tfile 0 10 4096
19877         $CHECKSTAT -s 40960 $DIR/$tfile
19878
19879         # disable lockless i/o
19880         do_nodes $(comma_list $(osts_nodes)) \
19881                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19882                         ldlm.namespaces.filter-*.contended_locks=32 \
19883                         ldlm.namespaces.filter-*.contention_seconds=0"
19884         lctl set_param -n osc.*.contention_seconds=0
19885         clear_stats osc.*.osc_stats
19886
19887         dd if=/dev/zero of=$DIR/$tfile count=0
19888         $CHECKSTAT -s 0 $DIR/$tfile
19889
19890         restore_lustre_params <$p
19891         rm -f $p
19892         rm $DIR/$tfile
19893 }
19894 run_test 216 "check lockless direct write updates file size and kms correctly"
19895
19896 test_217() { # bug 22430
19897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19898
19899         local node
19900         local nid
19901
19902         for node in $(nodes_list); do
19903                 nid=$(host_nids_address $node $NETTYPE)
19904                 if [[ $nid = *-* ]] ; then
19905                         echo "lctl ping $(h2nettype $nid)"
19906                         lctl ping $(h2nettype $nid)
19907                 else
19908                         echo "skipping $node (no hyphen detected)"
19909                 fi
19910         done
19911 }
19912 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19913
19914 test_218() {
19915        # do directio so as not to populate the page cache
19916        log "creating a 10 Mb file"
19917        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19918        log "starting reads"
19919        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19920        log "truncating the file"
19921        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19922        log "killing dd"
19923        kill %+ || true # reads might have finished
19924        echo "wait until dd is finished"
19925        wait
19926        log "removing the temporary file"
19927        rm -rf $DIR/$tfile || error "tmp file removal failed"
19928 }
19929 run_test 218 "parallel read and truncate should not deadlock"
19930
19931 test_219() {
19932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19933
19934         # write one partial page
19935         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19936         # set no grant so vvp_io_commit_write will do sync write
19937         $LCTL set_param fail_loc=0x411
19938         # write a full page at the end of file
19939         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19940
19941         $LCTL set_param fail_loc=0
19942         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19943         $LCTL set_param fail_loc=0x411
19944         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19945
19946         # LU-4201
19947         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19948         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19949 }
19950 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19951
19952 test_220() { #LU-325
19953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19954         remote_ost_nodsh && skip "remote OST with nodsh"
19955         remote_mds_nodsh && skip "remote MDS with nodsh"
19956         remote_mgs_nodsh && skip "remote MGS with nodsh"
19957
19958         local OSTIDX=0
19959
19960         # create on MDT0000 so the last_id and next_id are correct
19961         mkdir_on_mdt0 $DIR/$tdir
19962         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19963         OST=${OST%_UUID}
19964
19965         # on the mdt's osc
19966         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19967         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19968                         osp.$mdtosc_proc1.prealloc_last_id)
19969         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19970                         osp.$mdtosc_proc1.prealloc_next_id)
19971
19972         $LFS df -i
19973
19974         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19975         #define OBD_FAIL_OST_ENOINO              0x229
19976         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19977         create_pool $FSNAME.$TESTNAME || return 1
19978         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19979
19980         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19981
19982         MDSOBJS=$((last_id - next_id))
19983         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19984
19985         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19986         echo "OST still has $count kbytes free"
19987
19988         echo "create $MDSOBJS files @next_id..."
19989         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19990
19991         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19992                         osp.$mdtosc_proc1.prealloc_last_id)
19993         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19994                         osp.$mdtosc_proc1.prealloc_next_id)
19995
19996         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19997         $LFS df -i
19998
19999         echo "cleanup..."
20000
20001         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20002         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20003
20004         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20005                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20006         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20007                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20008         echo "unlink $MDSOBJS files @$next_id..."
20009         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20010 }
20011 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20012
20013 test_221() {
20014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20015
20016         dd if=`which date` of=$MOUNT/date oflag=sync
20017         chmod +x $MOUNT/date
20018
20019         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20020         $LCTL set_param fail_loc=0x80001401
20021
20022         $MOUNT/date > /dev/null
20023         rm -f $MOUNT/date
20024 }
20025 run_test 221 "make sure fault and truncate race to not cause OOM"
20026
20027 test_222a () {
20028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20029
20030         rm -rf $DIR/$tdir
20031         test_mkdir $DIR/$tdir
20032         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20033         createmany -o $DIR/$tdir/$tfile 10
20034         cancel_lru_locks mdc
20035         cancel_lru_locks osc
20036         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20037         $LCTL set_param fail_loc=0x31a
20038         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20039         $LCTL set_param fail_loc=0
20040         rm -r $DIR/$tdir
20041 }
20042 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20043
20044 test_222b () {
20045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20046
20047         rm -rf $DIR/$tdir
20048         test_mkdir $DIR/$tdir
20049         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20050         createmany -o $DIR/$tdir/$tfile 10
20051         cancel_lru_locks mdc
20052         cancel_lru_locks osc
20053         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20054         $LCTL set_param fail_loc=0x31a
20055         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20056         $LCTL set_param fail_loc=0
20057 }
20058 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20059
20060 test_223 () {
20061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20062
20063         rm -rf $DIR/$tdir
20064         test_mkdir $DIR/$tdir
20065         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20066         createmany -o $DIR/$tdir/$tfile 10
20067         cancel_lru_locks mdc
20068         cancel_lru_locks osc
20069         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20070         $LCTL set_param fail_loc=0x31b
20071         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20072         $LCTL set_param fail_loc=0
20073         rm -r $DIR/$tdir
20074 }
20075 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20076
20077 test_224a() { # LU-1039, MRP-303
20078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20079         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20080         $LCTL set_param fail_loc=0x508
20081         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20082         $LCTL set_param fail_loc=0
20083         df $DIR
20084 }
20085 run_test 224a "Don't panic on bulk IO failure"
20086
20087 test_224bd_sub() { # LU-1039, MRP-303
20088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20089         local timeout=$1
20090
20091         shift
20092         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20093
20094         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20095
20096         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20097         cancel_lru_locks osc
20098         set_checksums 0
20099         stack_trap "set_checksums $ORIG_CSUM" EXIT
20100         local at_max_saved=0
20101
20102         # adaptive timeouts may prevent seeing the issue
20103         if at_is_enabled; then
20104                 at_max_saved=$(at_max_get mds)
20105                 at_max_set 0 mds client
20106                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20107         fi
20108
20109         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20110         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20111         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20112
20113         do_facet ost1 $LCTL set_param fail_loc=0
20114         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20115         df $DIR
20116 }
20117
20118 test_224b() {
20119         test_224bd_sub 3 error "dd failed"
20120 }
20121 run_test 224b "Don't panic on bulk IO failure"
20122
20123 test_224c() { # LU-6441
20124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20125         remote_mds_nodsh && skip "remote MDS with nodsh"
20126
20127         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20128         save_writethrough $p
20129         set_cache writethrough on
20130
20131         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20132         local at_max=$($LCTL get_param -n at_max)
20133         local timeout=$($LCTL get_param -n timeout)
20134         local test_at="at_max"
20135         local param_at="$FSNAME.sys.at_max"
20136         local test_timeout="timeout"
20137         local param_timeout="$FSNAME.sys.timeout"
20138
20139         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20140
20141         set_persistent_param_and_check client "$test_at" "$param_at" 0
20142         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20143
20144         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20145         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20146         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20147         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20148         sync
20149         do_facet ost1 "$LCTL set_param fail_loc=0"
20150
20151         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20152         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20153                 $timeout
20154
20155         $LCTL set_param -n $pages_per_rpc
20156         restore_lustre_params < $p
20157         rm -f $p
20158 }
20159 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20160
20161 test_224d() { # LU-11169
20162         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20163 }
20164 run_test 224d "Don't corrupt data on bulk IO timeout"
20165
20166 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20167 test_225a () {
20168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20169         if [ -z ${MDSSURVEY} ]; then
20170                 skip_env "mds-survey not found"
20171         fi
20172         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20173                 skip "Need MDS version at least 2.2.51"
20174
20175         local mds=$(facet_host $SINGLEMDS)
20176         local target=$(do_nodes $mds 'lctl dl' |
20177                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20178
20179         local cmd1="file_count=1000 thrhi=4"
20180         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20181         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20182         local cmd="$cmd1 $cmd2 $cmd3"
20183
20184         rm -f ${TMP}/mds_survey*
20185         echo + $cmd
20186         eval $cmd || error "mds-survey with zero-stripe failed"
20187         cat ${TMP}/mds_survey*
20188         rm -f ${TMP}/mds_survey*
20189 }
20190 run_test 225a "Metadata survey sanity with zero-stripe"
20191
20192 test_225b () {
20193         if [ -z ${MDSSURVEY} ]; then
20194                 skip_env "mds-survey not found"
20195         fi
20196         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20197                 skip "Need MDS version at least 2.2.51"
20198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20199         remote_mds_nodsh && skip "remote MDS with nodsh"
20200         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20201                 skip_env "Need to mount OST to test"
20202         fi
20203
20204         local mds=$(facet_host $SINGLEMDS)
20205         local target=$(do_nodes $mds 'lctl dl' |
20206                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20207
20208         local cmd1="file_count=1000 thrhi=4"
20209         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20210         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20211         local cmd="$cmd1 $cmd2 $cmd3"
20212
20213         rm -f ${TMP}/mds_survey*
20214         echo + $cmd
20215         eval $cmd || error "mds-survey with stripe_count failed"
20216         cat ${TMP}/mds_survey*
20217         rm -f ${TMP}/mds_survey*
20218 }
20219 run_test 225b "Metadata survey sanity with stripe_count = 1"
20220
20221 mcreate_path2fid () {
20222         local mode=$1
20223         local major=$2
20224         local minor=$3
20225         local name=$4
20226         local desc=$5
20227         local path=$DIR/$tdir/$name
20228         local fid
20229         local rc
20230         local fid_path
20231
20232         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20233                 error "cannot create $desc"
20234
20235         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20236         rc=$?
20237         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20238
20239         fid_path=$($LFS fid2path $MOUNT $fid)
20240         rc=$?
20241         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20242
20243         [ "$path" == "$fid_path" ] ||
20244                 error "fid2path returned $fid_path, expected $path"
20245
20246         echo "pass with $path and $fid"
20247 }
20248
20249 test_226a () {
20250         rm -rf $DIR/$tdir
20251         mkdir -p $DIR/$tdir
20252
20253         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20254         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20255         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20256         mcreate_path2fid 0040666 0 0 dir "directory"
20257         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20258         mcreate_path2fid 0100666 0 0 file "regular file"
20259         mcreate_path2fid 0120666 0 0 link "symbolic link"
20260         mcreate_path2fid 0140666 0 0 sock "socket"
20261 }
20262 run_test 226a "call path2fid and fid2path on files of all type"
20263
20264 test_226b () {
20265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20266
20267         local MDTIDX=1
20268
20269         rm -rf $DIR/$tdir
20270         mkdir -p $DIR/$tdir
20271         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20272                 error "create remote directory failed"
20273         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20274         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20275                                 "character special file (null)"
20276         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20277                                 "character special file (no device)"
20278         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20279         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20280                                 "block special file (loop)"
20281         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20282         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20283         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20284 }
20285 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20286
20287 test_226c () {
20288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20289         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20290                 skip "Need MDS version at least 2.13.55"
20291
20292         local submnt=/mnt/submnt
20293         local srcfile=/etc/passwd
20294         local dstfile=$submnt/passwd
20295         local path
20296         local fid
20297
20298         rm -rf $DIR/$tdir
20299         rm -rf $submnt
20300         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20301                 error "create remote directory failed"
20302         mkdir -p $submnt || error "create $submnt failed"
20303         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20304                 error "mount $submnt failed"
20305         stack_trap "umount $submnt" EXIT
20306
20307         cp $srcfile $dstfile
20308         fid=$($LFS path2fid $dstfile)
20309         path=$($LFS fid2path $submnt "$fid")
20310         [ "$path" = "$dstfile" ] ||
20311                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20312 }
20313 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20314
20315 # LU-1299 Executing or running ldd on a truncated executable does not
20316 # cause an out-of-memory condition.
20317 test_227() {
20318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20319         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20320
20321         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20322         chmod +x $MOUNT/date
20323
20324         $MOUNT/date > /dev/null
20325         ldd $MOUNT/date > /dev/null
20326         rm -f $MOUNT/date
20327 }
20328 run_test 227 "running truncated executable does not cause OOM"
20329
20330 # LU-1512 try to reuse idle OI blocks
20331 test_228a() {
20332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20333         remote_mds_nodsh && skip "remote MDS with nodsh"
20334         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20335
20336         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20337         local myDIR=$DIR/$tdir
20338
20339         mkdir -p $myDIR
20340         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20341         $LCTL set_param fail_loc=0x80001002
20342         createmany -o $myDIR/t- 10000
20343         $LCTL set_param fail_loc=0
20344         # The guard is current the largest FID holder
20345         touch $myDIR/guard
20346         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20347                     tr -d '[')
20348         local IDX=$(($SEQ % 64))
20349
20350         do_facet $SINGLEMDS sync
20351         # Make sure journal flushed.
20352         sleep 6
20353         local blk1=$(do_facet $SINGLEMDS \
20354                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20355                      grep Blockcount | awk '{print $4}')
20356
20357         # Remove old files, some OI blocks will become idle.
20358         unlinkmany $myDIR/t- 10000
20359         # Create new files, idle OI blocks should be reused.
20360         createmany -o $myDIR/t- 2000
20361         do_facet $SINGLEMDS sync
20362         # Make sure journal flushed.
20363         sleep 6
20364         local blk2=$(do_facet $SINGLEMDS \
20365                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20366                      grep Blockcount | awk '{print $4}')
20367
20368         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20369 }
20370 run_test 228a "try to reuse idle OI blocks"
20371
20372 test_228b() {
20373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20374         remote_mds_nodsh && skip "remote MDS with nodsh"
20375         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20376
20377         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20378         local myDIR=$DIR/$tdir
20379
20380         mkdir -p $myDIR
20381         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20382         $LCTL set_param fail_loc=0x80001002
20383         createmany -o $myDIR/t- 10000
20384         $LCTL set_param fail_loc=0
20385         # The guard is current the largest FID holder
20386         touch $myDIR/guard
20387         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20388                     tr -d '[')
20389         local IDX=$(($SEQ % 64))
20390
20391         do_facet $SINGLEMDS sync
20392         # Make sure journal flushed.
20393         sleep 6
20394         local blk1=$(do_facet $SINGLEMDS \
20395                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20396                      grep Blockcount | awk '{print $4}')
20397
20398         # Remove old files, some OI blocks will become idle.
20399         unlinkmany $myDIR/t- 10000
20400
20401         # stop the MDT
20402         stop $SINGLEMDS || error "Fail to stop MDT."
20403         # remount the MDT
20404         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20405                 error "Fail to start MDT."
20406
20407         client_up || error "Fail to df."
20408         # Create new files, idle OI blocks should be reused.
20409         createmany -o $myDIR/t- 2000
20410         do_facet $SINGLEMDS sync
20411         # Make sure journal flushed.
20412         sleep 6
20413         local blk2=$(do_facet $SINGLEMDS \
20414                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20415                      grep Blockcount | awk '{print $4}')
20416
20417         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20418 }
20419 run_test 228b "idle OI blocks can be reused after MDT restart"
20420
20421 #LU-1881
20422 test_228c() {
20423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20424         remote_mds_nodsh && skip "remote MDS with nodsh"
20425         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20426
20427         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20428         local myDIR=$DIR/$tdir
20429
20430         mkdir -p $myDIR
20431         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20432         $LCTL set_param fail_loc=0x80001002
20433         # 20000 files can guarantee there are index nodes in the OI file
20434         createmany -o $myDIR/t- 20000
20435         $LCTL set_param fail_loc=0
20436         # The guard is current the largest FID holder
20437         touch $myDIR/guard
20438         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20439                     tr -d '[')
20440         local IDX=$(($SEQ % 64))
20441
20442         do_facet $SINGLEMDS sync
20443         # Make sure journal flushed.
20444         sleep 6
20445         local blk1=$(do_facet $SINGLEMDS \
20446                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20447                      grep Blockcount | awk '{print $4}')
20448
20449         # Remove old files, some OI blocks will become idle.
20450         unlinkmany $myDIR/t- 20000
20451         rm -f $myDIR/guard
20452         # The OI file should become empty now
20453
20454         # Create new files, idle OI blocks should be reused.
20455         createmany -o $myDIR/t- 2000
20456         do_facet $SINGLEMDS sync
20457         # Make sure journal flushed.
20458         sleep 6
20459         local blk2=$(do_facet $SINGLEMDS \
20460                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20461                      grep Blockcount | awk '{print $4}')
20462
20463         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20464 }
20465 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20466
20467 test_229() { # LU-2482, LU-3448
20468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20469         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20470         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20471                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20472
20473         rm -f $DIR/$tfile
20474
20475         # Create a file with a released layout and stripe count 2.
20476         $MULTIOP $DIR/$tfile H2c ||
20477                 error "failed to create file with released layout"
20478
20479         $LFS getstripe -v $DIR/$tfile
20480
20481         local pattern=$($LFS getstripe -L $DIR/$tfile)
20482         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20483
20484         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20485                 error "getstripe"
20486         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20487         stat $DIR/$tfile || error "failed to stat released file"
20488
20489         chown $RUNAS_ID $DIR/$tfile ||
20490                 error "chown $RUNAS_ID $DIR/$tfile failed"
20491
20492         chgrp $RUNAS_ID $DIR/$tfile ||
20493                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20494
20495         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20496         rm $DIR/$tfile || error "failed to remove released file"
20497 }
20498 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20499
20500 test_230a() {
20501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20503         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20504                 skip "Need MDS version at least 2.11.52"
20505
20506         local MDTIDX=1
20507
20508         test_mkdir $DIR/$tdir
20509         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20510         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20511         [ $mdt_idx -ne 0 ] &&
20512                 error "create local directory on wrong MDT $mdt_idx"
20513
20514         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20515                         error "create remote directory failed"
20516         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20517         [ $mdt_idx -ne $MDTIDX ] &&
20518                 error "create remote directory on wrong MDT $mdt_idx"
20519
20520         createmany -o $DIR/$tdir/test_230/t- 10 ||
20521                 error "create files on remote directory failed"
20522         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20523         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20524         rm -r $DIR/$tdir || error "unlink remote directory failed"
20525 }
20526 run_test 230a "Create remote directory and files under the remote directory"
20527
20528 test_230b() {
20529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20531         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20532                 skip "Need MDS version at least 2.11.52"
20533
20534         local MDTIDX=1
20535         local mdt_index
20536         local i
20537         local file
20538         local pid
20539         local stripe_count
20540         local migrate_dir=$DIR/$tdir/migrate_dir
20541         local other_dir=$DIR/$tdir/other_dir
20542
20543         test_mkdir $DIR/$tdir
20544         test_mkdir -i0 -c1 $migrate_dir
20545         test_mkdir -i0 -c1 $other_dir
20546         for ((i=0; i<10; i++)); do
20547                 mkdir -p $migrate_dir/dir_${i}
20548                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20549                         error "create files under remote dir failed $i"
20550         done
20551
20552         cp /etc/passwd $migrate_dir/$tfile
20553         cp /etc/passwd $other_dir/$tfile
20554         chattr +SAD $migrate_dir
20555         chattr +SAD $migrate_dir/$tfile
20556
20557         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20558         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20559         local old_dir_mode=$(stat -c%f $migrate_dir)
20560         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20561
20562         mkdir -p $migrate_dir/dir_default_stripe2
20563         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20564         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20565
20566         mkdir -p $other_dir
20567         ln $migrate_dir/$tfile $other_dir/luna
20568         ln $migrate_dir/$tfile $migrate_dir/sofia
20569         ln $other_dir/$tfile $migrate_dir/david
20570         ln -s $migrate_dir/$tfile $other_dir/zachary
20571         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20572         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20573
20574         local len
20575         local lnktgt
20576
20577         # inline symlink
20578         for len in 58 59 60; do
20579                 lnktgt=$(str_repeat 'l' $len)
20580                 touch $migrate_dir/$lnktgt
20581                 ln -s $lnktgt $migrate_dir/${len}char_ln
20582         done
20583
20584         # PATH_MAX
20585         for len in 4094 4095; do
20586                 lnktgt=$(str_repeat 'l' $len)
20587                 ln -s $lnktgt $migrate_dir/${len}char_ln
20588         done
20589
20590         # NAME_MAX
20591         for len in 254 255; do
20592                 touch $migrate_dir/$(str_repeat 'l' $len)
20593         done
20594
20595         $LFS migrate -m $MDTIDX $migrate_dir ||
20596                 error "fails on migrating remote dir to MDT1"
20597
20598         echo "migratate to MDT1, then checking.."
20599         for ((i = 0; i < 10; i++)); do
20600                 for file in $(find $migrate_dir/dir_${i}); do
20601                         mdt_index=$($LFS getstripe -m $file)
20602                         # broken symlink getstripe will fail
20603                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20604                                 error "$file is not on MDT${MDTIDX}"
20605                 done
20606         done
20607
20608         # the multiple link file should still in MDT0
20609         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20610         [ $mdt_index == 0 ] ||
20611                 error "$file is not on MDT${MDTIDX}"
20612
20613         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20614         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20615                 error " expect $old_dir_flag get $new_dir_flag"
20616
20617         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20618         [ "$old_file_flag" = "$new_file_flag" ] ||
20619                 error " expect $old_file_flag get $new_file_flag"
20620
20621         local new_dir_mode=$(stat -c%f $migrate_dir)
20622         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20623                 error "expect mode $old_dir_mode get $new_dir_mode"
20624
20625         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20626         [ "$old_file_mode" = "$new_file_mode" ] ||
20627                 error "expect mode $old_file_mode get $new_file_mode"
20628
20629         diff /etc/passwd $migrate_dir/$tfile ||
20630                 error "$tfile different after migration"
20631
20632         diff /etc/passwd $other_dir/luna ||
20633                 error "luna different after migration"
20634
20635         diff /etc/passwd $migrate_dir/sofia ||
20636                 error "sofia different after migration"
20637
20638         diff /etc/passwd $migrate_dir/david ||
20639                 error "david different after migration"
20640
20641         diff /etc/passwd $other_dir/zachary ||
20642                 error "zachary different after migration"
20643
20644         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20645                 error "${tfile}_ln different after migration"
20646
20647         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20648                 error "${tfile}_ln_other different after migration"
20649
20650         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20651         [ $stripe_count = 2 ] ||
20652                 error "dir strpe_count $d != 2 after migration."
20653
20654         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20655         [ $stripe_count = 2 ] ||
20656                 error "file strpe_count $d != 2 after migration."
20657
20658         #migrate back to MDT0
20659         MDTIDX=0
20660
20661         $LFS migrate -m $MDTIDX $migrate_dir ||
20662                 error "fails on migrating remote dir to MDT0"
20663
20664         echo "migrate back to MDT0, checking.."
20665         for file in $(find $migrate_dir); do
20666                 mdt_index=$($LFS getstripe -m $file)
20667                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20668                         error "$file is not on MDT${MDTIDX}"
20669         done
20670
20671         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20672         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20673                 error " expect $old_dir_flag get $new_dir_flag"
20674
20675         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20676         [ "$old_file_flag" = "$new_file_flag" ] ||
20677                 error " expect $old_file_flag get $new_file_flag"
20678
20679         local new_dir_mode=$(stat -c%f $migrate_dir)
20680         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20681                 error "expect mode $old_dir_mode get $new_dir_mode"
20682
20683         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20684         [ "$old_file_mode" = "$new_file_mode" ] ||
20685                 error "expect mode $old_file_mode get $new_file_mode"
20686
20687         diff /etc/passwd ${migrate_dir}/$tfile ||
20688                 error "$tfile different after migration"
20689
20690         diff /etc/passwd ${other_dir}/luna ||
20691                 error "luna different after migration"
20692
20693         diff /etc/passwd ${migrate_dir}/sofia ||
20694                 error "sofia different after migration"
20695
20696         diff /etc/passwd ${other_dir}/zachary ||
20697                 error "zachary different after migration"
20698
20699         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20700                 error "${tfile}_ln different after migration"
20701
20702         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20703                 error "${tfile}_ln_other different after migration"
20704
20705         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20706         [ $stripe_count = 2 ] ||
20707                 error "dir strpe_count $d != 2 after migration."
20708
20709         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20710         [ $stripe_count = 2 ] ||
20711                 error "file strpe_count $d != 2 after migration."
20712
20713         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20714 }
20715 run_test 230b "migrate directory"
20716
20717 test_230c() {
20718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20720         remote_mds_nodsh && skip "remote MDS with nodsh"
20721         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20722                 skip "Need MDS version at least 2.11.52"
20723
20724         local MDTIDX=1
20725         local total=3
20726         local mdt_index
20727         local file
20728         local migrate_dir=$DIR/$tdir/migrate_dir
20729
20730         #If migrating directory fails in the middle, all entries of
20731         #the directory is still accessiable.
20732         test_mkdir $DIR/$tdir
20733         test_mkdir -i0 -c1 $migrate_dir
20734         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20735         stat $migrate_dir
20736         createmany -o $migrate_dir/f $total ||
20737                 error "create files under ${migrate_dir} failed"
20738
20739         # fail after migrating top dir, and this will fail only once, so the
20740         # first sub file migration will fail (currently f3), others succeed.
20741         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20742         do_facet mds1 lctl set_param fail_loc=0x1801
20743         local t=$(ls $migrate_dir | wc -l)
20744         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20745                 error "migrate should fail"
20746         local u=$(ls $migrate_dir | wc -l)
20747         [ "$u" == "$t" ] || error "$u != $t during migration"
20748
20749         # add new dir/file should succeed
20750         mkdir $migrate_dir/dir ||
20751                 error "mkdir failed under migrating directory"
20752         touch $migrate_dir/file ||
20753                 error "create file failed under migrating directory"
20754
20755         # add file with existing name should fail
20756         for file in $migrate_dir/f*; do
20757                 stat $file > /dev/null || error "stat $file failed"
20758                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20759                         error "open(O_CREAT|O_EXCL) $file should fail"
20760                 $MULTIOP $file m && error "create $file should fail"
20761                 touch $DIR/$tdir/remote_dir/$tfile ||
20762                         error "touch $tfile failed"
20763                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20764                         error "link $file should fail"
20765                 mdt_index=$($LFS getstripe -m $file)
20766                 if [ $mdt_index == 0 ]; then
20767                         # file failed to migrate is not allowed to rename to
20768                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20769                                 error "rename to $file should fail"
20770                 else
20771                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20772                                 error "rename to $file failed"
20773                 fi
20774                 echo hello >> $file || error "write $file failed"
20775         done
20776
20777         # resume migration with different options should fail
20778         $LFS migrate -m 0 $migrate_dir &&
20779                 error "migrate -m 0 $migrate_dir should fail"
20780
20781         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20782                 error "migrate -c 2 $migrate_dir should fail"
20783
20784         # resume migration should succeed
20785         $LFS migrate -m $MDTIDX $migrate_dir ||
20786                 error "migrate $migrate_dir failed"
20787
20788         echo "Finish migration, then checking.."
20789         for file in $(find $migrate_dir); do
20790                 mdt_index=$($LFS getstripe -m $file)
20791                 [ $mdt_index == $MDTIDX ] ||
20792                         error "$file is not on MDT${MDTIDX}"
20793         done
20794
20795         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20796 }
20797 run_test 230c "check directory accessiblity if migration failed"
20798
20799 test_230d() {
20800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20802         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20803                 skip "Need MDS version at least 2.11.52"
20804         # LU-11235
20805         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20806
20807         local migrate_dir=$DIR/$tdir/migrate_dir
20808         local old_index
20809         local new_index
20810         local old_count
20811         local new_count
20812         local new_hash
20813         local mdt_index
20814         local i
20815         local j
20816
20817         old_index=$((RANDOM % MDSCOUNT))
20818         old_count=$((MDSCOUNT - old_index))
20819         new_index=$((RANDOM % MDSCOUNT))
20820         new_count=$((MDSCOUNT - new_index))
20821         new_hash=1 # for all_char
20822
20823         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20824         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20825
20826         test_mkdir $DIR/$tdir
20827         test_mkdir -i $old_index -c $old_count $migrate_dir
20828
20829         for ((i=0; i<100; i++)); do
20830                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20831                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20832                         error "create files under remote dir failed $i"
20833         done
20834
20835         echo -n "Migrate from MDT$old_index "
20836         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20837         echo -n "to MDT$new_index"
20838         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20839         echo
20840
20841         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20842         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20843                 error "migrate remote dir error"
20844
20845         echo "Finish migration, then checking.."
20846         for file in $(find $migrate_dir -maxdepth 1); do
20847                 mdt_index=$($LFS getstripe -m $file)
20848                 if [ $mdt_index -lt $new_index ] ||
20849                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20850                         error "$file is on MDT$mdt_index"
20851                 fi
20852         done
20853
20854         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20855 }
20856 run_test 230d "check migrate big directory"
20857
20858 test_230e() {
20859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20862                 skip "Need MDS version at least 2.11.52"
20863
20864         local i
20865         local j
20866         local a_fid
20867         local b_fid
20868
20869         mkdir_on_mdt0 $DIR/$tdir
20870         mkdir $DIR/$tdir/migrate_dir
20871         mkdir $DIR/$tdir/other_dir
20872         touch $DIR/$tdir/migrate_dir/a
20873         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20874         ls $DIR/$tdir/other_dir
20875
20876         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20877                 error "migrate dir fails"
20878
20879         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20880         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20881
20882         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20883         [ $mdt_index == 0 ] || error "a is not on MDT0"
20884
20885         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20886                 error "migrate dir fails"
20887
20888         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20889         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20890
20891         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20892         [ $mdt_index == 1 ] || error "a is not on MDT1"
20893
20894         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20895         [ $mdt_index == 1 ] || error "b is not on MDT1"
20896
20897         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20898         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20899
20900         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20901
20902         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20903 }
20904 run_test 230e "migrate mulitple local link files"
20905
20906 test_230f() {
20907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20909         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20910                 skip "Need MDS version at least 2.11.52"
20911
20912         local a_fid
20913         local ln_fid
20914
20915         mkdir -p $DIR/$tdir
20916         mkdir $DIR/$tdir/migrate_dir
20917         $LFS mkdir -i1 $DIR/$tdir/other_dir
20918         touch $DIR/$tdir/migrate_dir/a
20919         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20920         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20921         ls $DIR/$tdir/other_dir
20922
20923         # a should be migrated to MDT1, since no other links on MDT0
20924         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20925                 error "#1 migrate dir fails"
20926         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20927         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20928         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20929         [ $mdt_index == 1 ] || error "a is not on MDT1"
20930
20931         # a should stay on MDT1, because it is a mulitple link file
20932         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20933                 error "#2 migrate dir fails"
20934         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20935         [ $mdt_index == 1 ] || error "a is not on MDT1"
20936
20937         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20938                 error "#3 migrate dir fails"
20939
20940         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20941         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20942         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20943
20944         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20945         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20946
20947         # a should be migrated to MDT0, since no other links on MDT1
20948         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20949                 error "#4 migrate dir fails"
20950         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20951         [ $mdt_index == 0 ] || error "a is not on MDT0"
20952
20953         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20954 }
20955 run_test 230f "migrate mulitple remote link files"
20956
20957 test_230g() {
20958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20960         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20961                 skip "Need MDS version at least 2.11.52"
20962
20963         mkdir -p $DIR/$tdir/migrate_dir
20964
20965         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20966                 error "migrating dir to non-exist MDT succeeds"
20967         true
20968 }
20969 run_test 230g "migrate dir to non-exist MDT"
20970
20971 test_230h() {
20972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20973         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20974         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20975                 skip "Need MDS version at least 2.11.52"
20976
20977         local mdt_index
20978
20979         mkdir -p $DIR/$tdir/migrate_dir
20980
20981         $LFS migrate -m1 $DIR &&
20982                 error "migrating mountpoint1 should fail"
20983
20984         $LFS migrate -m1 $DIR/$tdir/.. &&
20985                 error "migrating mountpoint2 should fail"
20986
20987         # same as mv
20988         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20989                 error "migrating $tdir/migrate_dir/.. should fail"
20990
20991         true
20992 }
20993 run_test 230h "migrate .. and root"
20994
20995 test_230i() {
20996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20998         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20999                 skip "Need MDS version at least 2.11.52"
21000
21001         mkdir -p $DIR/$tdir/migrate_dir
21002
21003         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21004                 error "migration fails with a tailing slash"
21005
21006         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21007                 error "migration fails with two tailing slashes"
21008 }
21009 run_test 230i "lfs migrate -m tolerates trailing slashes"
21010
21011 test_230j() {
21012         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21013         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21014                 skip "Need MDS version at least 2.11.52"
21015
21016         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21017         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21018                 error "create $tfile failed"
21019         cat /etc/passwd > $DIR/$tdir/$tfile
21020
21021         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21022
21023         cmp /etc/passwd $DIR/$tdir/$tfile ||
21024                 error "DoM file mismatch after migration"
21025 }
21026 run_test 230j "DoM file data not changed after dir migration"
21027
21028 test_230k() {
21029         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21030         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21031                 skip "Need MDS version at least 2.11.56"
21032
21033         local total=20
21034         local files_on_starting_mdt=0
21035
21036         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21037         $LFS getdirstripe $DIR/$tdir
21038         for i in $(seq $total); do
21039                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21040                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21041                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21042         done
21043
21044         echo "$files_on_starting_mdt files on MDT0"
21045
21046         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21047         $LFS getdirstripe $DIR/$tdir
21048
21049         files_on_starting_mdt=0
21050         for i in $(seq $total); do
21051                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21052                         error "file $tfile.$i mismatch after migration"
21053                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21054                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21055         done
21056
21057         echo "$files_on_starting_mdt files on MDT1 after migration"
21058         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21059
21060         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21061         $LFS getdirstripe $DIR/$tdir
21062
21063         files_on_starting_mdt=0
21064         for i in $(seq $total); do
21065                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21066                         error "file $tfile.$i mismatch after 2nd migration"
21067                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21068                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21069         done
21070
21071         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21072         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21073
21074         true
21075 }
21076 run_test 230k "file data not changed after dir migration"
21077
21078 test_230l() {
21079         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21080         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21081                 skip "Need MDS version at least 2.11.56"
21082
21083         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21084         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21085                 error "create files under remote dir failed $i"
21086         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21087 }
21088 run_test 230l "readdir between MDTs won't crash"
21089
21090 test_230m() {
21091         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21092         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21093                 skip "Need MDS version at least 2.11.56"
21094
21095         local MDTIDX=1
21096         local mig_dir=$DIR/$tdir/migrate_dir
21097         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21098         local shortstr="b"
21099         local val
21100
21101         echo "Creating files and dirs with xattrs"
21102         test_mkdir $DIR/$tdir
21103         test_mkdir -i0 -c1 $mig_dir
21104         mkdir $mig_dir/dir
21105         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21106                 error "cannot set xattr attr1 on dir"
21107         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21108                 error "cannot set xattr attr2 on dir"
21109         touch $mig_dir/dir/f0
21110         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21111                 error "cannot set xattr attr1 on file"
21112         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21113                 error "cannot set xattr attr2 on file"
21114         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21115         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21116         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21117         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21118         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21119         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21120         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21121         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21122         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21123
21124         echo "Migrating to MDT1"
21125         $LFS migrate -m $MDTIDX $mig_dir ||
21126                 error "fails on migrating dir to MDT1"
21127
21128         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21129         echo "Checking xattrs"
21130         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21131         [ "$val" = $longstr ] ||
21132                 error "expecting xattr1 $longstr on dir, found $val"
21133         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21134         [ "$val" = $shortstr ] ||
21135                 error "expecting xattr2 $shortstr on dir, found $val"
21136         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21137         [ "$val" = $longstr ] ||
21138                 error "expecting xattr1 $longstr on file, found $val"
21139         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21140         [ "$val" = $shortstr ] ||
21141                 error "expecting xattr2 $shortstr on file, found $val"
21142 }
21143 run_test 230m "xattrs not changed after dir migration"
21144
21145 test_230n() {
21146         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21147         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21148                 skip "Need MDS version at least 2.13.53"
21149
21150         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21151         cat /etc/hosts > $DIR/$tdir/$tfile
21152         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21153         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21154
21155         cmp /etc/hosts $DIR/$tdir/$tfile ||
21156                 error "File data mismatch after migration"
21157 }
21158 run_test 230n "Dir migration with mirrored file"
21159
21160 test_230o() {
21161         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21162         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21163                 skip "Need MDS version at least 2.13.52"
21164
21165         local mdts=$(comma_list $(mdts_nodes))
21166         local timeout=100
21167         local restripe_status
21168         local delta
21169         local i
21170
21171         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21172
21173         # in case "crush" hash type is not set
21174         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21175
21176         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21177                            mdt.*MDT0000.enable_dir_restripe)
21178         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21179         stack_trap "do_nodes $mdts $LCTL set_param \
21180                     mdt.*.enable_dir_restripe=$restripe_status"
21181
21182         mkdir $DIR/$tdir
21183         createmany -m $DIR/$tdir/f 100 ||
21184                 error "create files under remote dir failed $i"
21185         createmany -d $DIR/$tdir/d 100 ||
21186                 error "create dirs under remote dir failed $i"
21187
21188         for i in $(seq 2 $MDSCOUNT); do
21189                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21190                 $LFS setdirstripe -c $i $DIR/$tdir ||
21191                         error "split -c $i $tdir failed"
21192                 wait_update $HOSTNAME \
21193                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21194                         error "dir split not finished"
21195                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21196                         awk '/migrate/ {sum += $2} END { print sum }')
21197                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21198                 # delta is around total_files/stripe_count
21199                 (( $delta < 200 / (i - 1) + 4 )) ||
21200                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21201         done
21202 }
21203 run_test 230o "dir split"
21204
21205 test_230p() {
21206         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21207         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21208                 skip "Need MDS version at least 2.13.52"
21209
21210         local mdts=$(comma_list $(mdts_nodes))
21211         local timeout=100
21212         local restripe_status
21213         local delta
21214         local c
21215
21216         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21217
21218         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21219
21220         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21221                            mdt.*MDT0000.enable_dir_restripe)
21222         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21223         stack_trap "do_nodes $mdts $LCTL set_param \
21224                     mdt.*.enable_dir_restripe=$restripe_status"
21225
21226         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21227         createmany -m $DIR/$tdir/f 100 ||
21228                 error "create files under remote dir failed"
21229         createmany -d $DIR/$tdir/d 100 ||
21230                 error "create dirs under remote dir failed"
21231
21232         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21233                 local mdt_hash="crush"
21234
21235                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21236                 $LFS setdirstripe -c $c $DIR/$tdir ||
21237                         error "split -c $c $tdir failed"
21238                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21239                         mdt_hash="$mdt_hash,fixed"
21240                 elif [ $c -eq 1 ]; then
21241                         mdt_hash="none"
21242                 fi
21243                 wait_update $HOSTNAME \
21244                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21245                         error "dir merge not finished"
21246                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21247                         awk '/migrate/ {sum += $2} END { print sum }')
21248                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21249                 # delta is around total_files/stripe_count
21250                 (( delta < 200 / c + 4 )) ||
21251                         error "$delta files migrated >= $((200 / c + 4))"
21252         done
21253 }
21254 run_test 230p "dir merge"
21255
21256 test_230q() {
21257         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21258         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21259                 skip "Need MDS version at least 2.13.52"
21260
21261         local mdts=$(comma_list $(mdts_nodes))
21262         local saved_threshold=$(do_facet mds1 \
21263                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21264         local saved_delta=$(do_facet mds1 \
21265                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21266         local threshold=100
21267         local delta=2
21268         local total=0
21269         local stripe_count=0
21270         local stripe_index
21271         local nr_files
21272         local create
21273
21274         # test with fewer files on ZFS
21275         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21276
21277         stack_trap "do_nodes $mdts $LCTL set_param \
21278                     mdt.*.dir_split_count=$saved_threshold"
21279         stack_trap "do_nodes $mdts $LCTL set_param \
21280                     mdt.*.dir_split_delta=$saved_delta"
21281         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21282         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21283         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21284         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21285         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21286         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21287
21288         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21289         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21290
21291         create=$((threshold * 3 / 2))
21292         while [ $stripe_count -lt $MDSCOUNT ]; do
21293                 createmany -m $DIR/$tdir/f $total $create ||
21294                         error "create sub files failed"
21295                 stat $DIR/$tdir > /dev/null
21296                 total=$((total + create))
21297                 stripe_count=$((stripe_count + delta))
21298                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21299
21300                 wait_update $HOSTNAME \
21301                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21302                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21303
21304                 wait_update $HOSTNAME \
21305                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21306                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21307
21308                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21309                 echo "$nr_files/$total files on MDT$stripe_index after split"
21310                 # allow 10% margin of imbalance with crush hash
21311                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21312                         error "$nr_files files on MDT$stripe_index after split"
21313
21314                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21315                 [ $nr_files -eq $total ] ||
21316                         error "total sub files $nr_files != $total"
21317         done
21318
21319         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21320
21321         echo "fixed layout directory won't auto split"
21322         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21323         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21324                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21325         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21326                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21327 }
21328 run_test 230q "dir auto split"
21329
21330 test_230r() {
21331         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21332         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21333         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21334                 skip "Need MDS version at least 2.13.54"
21335
21336         # maximum amount of local locks:
21337         # parent striped dir - 2 locks
21338         # new stripe in parent to migrate to - 1 lock
21339         # source and target - 2 locks
21340         # Total 5 locks for regular file
21341         mkdir -p $DIR/$tdir
21342         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21343         touch $DIR/$tdir/dir1/eee
21344
21345         # create 4 hardlink for 4 more locks
21346         # Total: 9 locks > RS_MAX_LOCKS (8)
21347         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21348         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21349         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21350         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21351         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21352         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21353         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21354         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21355
21356         cancel_lru_locks mdc
21357
21358         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21359                 error "migrate dir fails"
21360
21361         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21362 }
21363 run_test 230r "migrate with too many local locks"
21364
21365 test_230s() {
21366         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21367                 skip "Need MDS version at least 2.14.52"
21368
21369         local mdts=$(comma_list $(mdts_nodes))
21370         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21371                                 mdt.*MDT0000.enable_dir_restripe)
21372
21373         stack_trap "do_nodes $mdts $LCTL set_param \
21374                     mdt.*.enable_dir_restripe=$restripe_status"
21375
21376         local st
21377         for st in 0 1; do
21378                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21379                 test_mkdir $DIR/$tdir
21380                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21381                         error "$LFS mkdir should return EEXIST if target exists"
21382                 rmdir $DIR/$tdir
21383         done
21384 }
21385 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21386
21387 test_230t()
21388 {
21389         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21390         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21391                 skip "Need MDS version at least 2.14.50"
21392
21393         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21394         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21395         $LFS project -p 1 -s $DIR/$tdir ||
21396                 error "set $tdir project id failed"
21397         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21398                 error "set subdir project id failed"
21399         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21400 }
21401 run_test 230t "migrate directory with project ID set"
21402
21403 test_230u()
21404 {
21405         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21406         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21407                 skip "Need MDS version at least 2.14.53"
21408
21409         local count
21410
21411         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21412         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21413         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21414         for i in $(seq 0 $((MDSCOUNT - 1))); do
21415                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21416                 echo "$count dirs migrated to MDT$i"
21417         done
21418         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21419         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21420 }
21421 run_test 230u "migrate directory by QOS"
21422
21423 test_230v()
21424 {
21425         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21426         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21427                 skip "Need MDS version at least 2.14.53"
21428
21429         local count
21430
21431         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21432         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21433         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21434         for i in $(seq 0 $((MDSCOUNT - 1))); do
21435                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21436                 echo "$count subdirs migrated to MDT$i"
21437                 (( i == 3 )) && (( count > 0 )) &&
21438                         error "subdir shouldn't be migrated to MDT3"
21439         done
21440         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21441         (( count == 3 )) || error "dirs migrated to $count MDTs"
21442 }
21443 run_test 230v "subdir migrated to the MDT where its parent is located"
21444
21445 test_230w() {
21446         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21447         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21448                 skip "Need MDS version at least 2.15.0"
21449
21450         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21451         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21452         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21453
21454         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21455                 error "migrate failed"
21456
21457         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21458                 error "$tdir stripe count mismatch"
21459
21460         for i in $(seq 0 9); do
21461                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21462                         error "d$i is striped"
21463         done
21464 }
21465 run_test 230w "non-recursive mode dir migration"
21466
21467 test_230x() {
21468         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21469         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21470                 skip "Need MDS version at least 2.15.0"
21471
21472         mkdir -p $DIR/$tdir || error "mkdir failed"
21473         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21474
21475         local mdt_name=$(mdtname_from_index 0)
21476         local low=$(do_facet mds2 $LCTL get_param -n \
21477                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21478         local high=$(do_facet mds2 $LCTL get_param -n \
21479                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21480         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21481         local maxage=$(do_facet mds2 $LCTL get_param -n \
21482                 osp.*$mdt_name-osp-MDT0001.maxage)
21483
21484         stack_trap "do_facet mds2 $LCTL set_param -n \
21485                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21486                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21487         stack_trap "do_facet mds2 $LCTL set_param -n \
21488                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21489
21490         do_facet mds2 $LCTL set_param -n \
21491                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21492         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21493         sleep 4
21494         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21495                 error "migrate $tdir should fail"
21496
21497         do_facet mds2 $LCTL set_param -n \
21498                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21499         do_facet mds2 $LCTL set_param -n \
21500                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21501         sleep 4
21502         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21503                 error "migrate failed"
21504         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21505                 error "$tdir stripe count mismatch"
21506 }
21507 run_test 230x "dir migration check space"
21508
21509 test_231a()
21510 {
21511         # For simplicity this test assumes that max_pages_per_rpc
21512         # is the same across all OSCs
21513         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21514         local bulk_size=$((max_pages * PAGE_SIZE))
21515         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21516                                        head -n 1)
21517
21518         mkdir -p $DIR/$tdir
21519         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21520                 error "failed to set stripe with -S ${brw_size}M option"
21521
21522         # clear the OSC stats
21523         $LCTL set_param osc.*.stats=0 &>/dev/null
21524         stop_writeback
21525
21526         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21527         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21528                 oflag=direct &>/dev/null || error "dd failed"
21529
21530         sync; sleep 1; sync # just to be safe
21531         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21532         if [ x$nrpcs != "x1" ]; then
21533                 $LCTL get_param osc.*.stats
21534                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21535         fi
21536
21537         start_writeback
21538         # Drop the OSC cache, otherwise we will read from it
21539         cancel_lru_locks osc
21540
21541         # clear the OSC stats
21542         $LCTL set_param osc.*.stats=0 &>/dev/null
21543
21544         # Client reads $bulk_size.
21545         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21546                 iflag=direct &>/dev/null || error "dd failed"
21547
21548         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21549         if [ x$nrpcs != "x1" ]; then
21550                 $LCTL get_param osc.*.stats
21551                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21552         fi
21553 }
21554 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21555
21556 test_231b() {
21557         mkdir -p $DIR/$tdir
21558         local i
21559         for i in {0..1023}; do
21560                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21561                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21562                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21563         done
21564         sync
21565 }
21566 run_test 231b "must not assert on fully utilized OST request buffer"
21567
21568 test_232a() {
21569         mkdir -p $DIR/$tdir
21570         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21571
21572         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21573         do_facet ost1 $LCTL set_param fail_loc=0x31c
21574
21575         # ignore dd failure
21576         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21577
21578         do_facet ost1 $LCTL set_param fail_loc=0
21579         umount_client $MOUNT || error "umount failed"
21580         mount_client $MOUNT || error "mount failed"
21581         stop ost1 || error "cannot stop ost1"
21582         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21583 }
21584 run_test 232a "failed lock should not block umount"
21585
21586 test_232b() {
21587         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21588                 skip "Need MDS version at least 2.10.58"
21589
21590         mkdir -p $DIR/$tdir
21591         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21592         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21593         sync
21594         cancel_lru_locks osc
21595
21596         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21597         do_facet ost1 $LCTL set_param fail_loc=0x31c
21598
21599         # ignore failure
21600         $LFS data_version $DIR/$tdir/$tfile || true
21601
21602         do_facet ost1 $LCTL set_param fail_loc=0
21603         umount_client $MOUNT || error "umount failed"
21604         mount_client $MOUNT || error "mount failed"
21605         stop ost1 || error "cannot stop ost1"
21606         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21607 }
21608 run_test 232b "failed data version lock should not block umount"
21609
21610 test_233a() {
21611         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21612                 skip "Need MDS version at least 2.3.64"
21613         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21614
21615         local fid=$($LFS path2fid $MOUNT)
21616
21617         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21618                 error "cannot access $MOUNT using its FID '$fid'"
21619 }
21620 run_test 233a "checking that OBF of the FS root succeeds"
21621
21622 test_233b() {
21623         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21624                 skip "Need MDS version at least 2.5.90"
21625         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21626
21627         local fid=$($LFS path2fid $MOUNT/.lustre)
21628
21629         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21630                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21631
21632         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21633         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21634                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21635 }
21636 run_test 233b "checking that OBF of the FS .lustre succeeds"
21637
21638 test_234() {
21639         local p="$TMP/sanityN-$TESTNAME.parameters"
21640         save_lustre_params client "llite.*.xattr_cache" > $p
21641         lctl set_param llite.*.xattr_cache 1 ||
21642                 skip_env "xattr cache is not supported"
21643
21644         mkdir -p $DIR/$tdir || error "mkdir failed"
21645         touch $DIR/$tdir/$tfile || error "touch failed"
21646         # OBD_FAIL_LLITE_XATTR_ENOMEM
21647         $LCTL set_param fail_loc=0x1405
21648         getfattr -n user.attr $DIR/$tdir/$tfile &&
21649                 error "getfattr should have failed with ENOMEM"
21650         $LCTL set_param fail_loc=0x0
21651         rm -rf $DIR/$tdir
21652
21653         restore_lustre_params < $p
21654         rm -f $p
21655 }
21656 run_test 234 "xattr cache should not crash on ENOMEM"
21657
21658 test_235() {
21659         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21660                 skip "Need MDS version at least 2.4.52"
21661
21662         flock_deadlock $DIR/$tfile
21663         local RC=$?
21664         case $RC in
21665                 0)
21666                 ;;
21667                 124) error "process hangs on a deadlock"
21668                 ;;
21669                 *) error "error executing flock_deadlock $DIR/$tfile"
21670                 ;;
21671         esac
21672 }
21673 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21674
21675 #LU-2935
21676 test_236() {
21677         check_swap_layouts_support
21678
21679         local ref1=/etc/passwd
21680         local ref2=/etc/group
21681         local file1=$DIR/$tdir/f1
21682         local file2=$DIR/$tdir/f2
21683
21684         test_mkdir -c1 $DIR/$tdir
21685         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21686         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21687         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21688         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21689         local fd=$(free_fd)
21690         local cmd="exec $fd<>$file2"
21691         eval $cmd
21692         rm $file2
21693         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21694                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21695         cmd="exec $fd>&-"
21696         eval $cmd
21697         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21698
21699         #cleanup
21700         rm -rf $DIR/$tdir
21701 }
21702 run_test 236 "Layout swap on open unlinked file"
21703
21704 # LU-4659 linkea consistency
21705 test_238() {
21706         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21707                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21708                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21709                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21710
21711         touch $DIR/$tfile
21712         ln $DIR/$tfile $DIR/$tfile.lnk
21713         touch $DIR/$tfile.new
21714         mv $DIR/$tfile.new $DIR/$tfile
21715         local fid1=$($LFS path2fid $DIR/$tfile)
21716         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21717         local path1=$($LFS fid2path $FSNAME "$fid1")
21718         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21719         local path2=$($LFS fid2path $FSNAME "$fid2")
21720         [ $tfile.lnk == $path2 ] ||
21721                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21722         rm -f $DIR/$tfile*
21723 }
21724 run_test 238 "Verify linkea consistency"
21725
21726 test_239A() { # was test_239
21727         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21728                 skip "Need MDS version at least 2.5.60"
21729
21730         local list=$(comma_list $(mdts_nodes))
21731
21732         mkdir -p $DIR/$tdir
21733         createmany -o $DIR/$tdir/f- 5000
21734         unlinkmany $DIR/$tdir/f- 5000
21735         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21736                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21737         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21738                         osp.*MDT*.sync_in_flight" | calc_sum)
21739         [ "$changes" -eq 0 ] || error "$changes not synced"
21740 }
21741 run_test 239A "osp_sync test"
21742
21743 test_239a() { #LU-5297
21744         remote_mds_nodsh && skip "remote MDS with nodsh"
21745
21746         touch $DIR/$tfile
21747         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21748         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21749         chgrp $RUNAS_GID $DIR/$tfile
21750         wait_delete_completed
21751 }
21752 run_test 239a "process invalid osp sync record correctly"
21753
21754 test_239b() { #LU-5297
21755         remote_mds_nodsh && skip "remote MDS with nodsh"
21756
21757         touch $DIR/$tfile1
21758         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21759         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21760         chgrp $RUNAS_GID $DIR/$tfile1
21761         wait_delete_completed
21762         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21763         touch $DIR/$tfile2
21764         chgrp $RUNAS_GID $DIR/$tfile2
21765         wait_delete_completed
21766 }
21767 run_test 239b "process osp sync record with ENOMEM error correctly"
21768
21769 test_240() {
21770         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21771         remote_mds_nodsh && skip "remote MDS with nodsh"
21772
21773         mkdir -p $DIR/$tdir
21774
21775         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21776                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21777         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21778                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21779
21780         umount_client $MOUNT || error "umount failed"
21781         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21782         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21783         mount_client $MOUNT || error "failed to mount client"
21784
21785         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21786         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21787 }
21788 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21789
21790 test_241_bio() {
21791         local count=$1
21792         local bsize=$2
21793
21794         for LOOP in $(seq $count); do
21795                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21796                 cancel_lru_locks $OSC || true
21797         done
21798 }
21799
21800 test_241_dio() {
21801         local count=$1
21802         local bsize=$2
21803
21804         for LOOP in $(seq $1); do
21805                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21806                         2>/dev/null
21807         done
21808 }
21809
21810 test_241a() { # was test_241
21811         local bsize=$PAGE_SIZE
21812
21813         (( bsize < 40960 )) && bsize=40960
21814         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21815         ls -la $DIR/$tfile
21816         cancel_lru_locks $OSC
21817         test_241_bio 1000 $bsize &
21818         PID=$!
21819         test_241_dio 1000 $bsize
21820         wait $PID
21821 }
21822 run_test 241a "bio vs dio"
21823
21824 test_241b() {
21825         local bsize=$PAGE_SIZE
21826
21827         (( bsize < 40960 )) && bsize=40960
21828         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21829         ls -la $DIR/$tfile
21830         test_241_dio 1000 $bsize &
21831         PID=$!
21832         test_241_dio 1000 $bsize
21833         wait $PID
21834 }
21835 run_test 241b "dio vs dio"
21836
21837 test_242() {
21838         remote_mds_nodsh && skip "remote MDS with nodsh"
21839
21840         mkdir_on_mdt0 $DIR/$tdir
21841         touch $DIR/$tdir/$tfile
21842
21843         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21844         do_facet mds1 lctl set_param fail_loc=0x105
21845         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21846
21847         do_facet mds1 lctl set_param fail_loc=0
21848         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21849 }
21850 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21851
21852 test_243()
21853 {
21854         test_mkdir $DIR/$tdir
21855         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21856 }
21857 run_test 243 "various group lock tests"
21858
21859 test_244a()
21860 {
21861         test_mkdir $DIR/$tdir
21862         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21863         sendfile_grouplock $DIR/$tdir/$tfile || \
21864                 error "sendfile+grouplock failed"
21865         rm -rf $DIR/$tdir
21866 }
21867 run_test 244a "sendfile with group lock tests"
21868
21869 test_244b()
21870 {
21871         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21872
21873         local threads=50
21874         local size=$((1024*1024))
21875
21876         test_mkdir $DIR/$tdir
21877         for i in $(seq 1 $threads); do
21878                 local file=$DIR/$tdir/file_$((i / 10))
21879                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21880                 local pids[$i]=$!
21881         done
21882         for i in $(seq 1 $threads); do
21883                 wait ${pids[$i]}
21884         done
21885 }
21886 run_test 244b "multi-threaded write with group lock"
21887
21888 test_245a() {
21889         local flagname="multi_mod_rpcs"
21890         local connect_data_name="max_mod_rpcs"
21891         local out
21892
21893         # check if multiple modify RPCs flag is set
21894         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21895                 grep "connect_flags:")
21896         echo "$out"
21897
21898         echo "$out" | grep -qw $flagname
21899         if [ $? -ne 0 ]; then
21900                 echo "connect flag $flagname is not set"
21901                 return
21902         fi
21903
21904         # check if multiple modify RPCs data is set
21905         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21906         echo "$out"
21907
21908         echo "$out" | grep -qw $connect_data_name ||
21909                 error "import should have connect data $connect_data_name"
21910 }
21911 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21912
21913 test_245b() {
21914         local flagname="multi_mod_rpcs"
21915         local connect_data_name="max_mod_rpcs"
21916         local out
21917
21918         remote_mds_nodsh && skip "remote MDS with nodsh"
21919         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21920
21921         # check if multiple modify RPCs flag is set
21922         out=$(do_facet mds1 \
21923               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21924               grep "connect_flags:")
21925         echo "$out"
21926
21927         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21928
21929         # check if multiple modify RPCs data is set
21930         out=$(do_facet mds1 \
21931               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21932
21933         [[ "$out" =~ $connect_data_name ]] ||
21934                 {
21935                         echo "$out"
21936                         error "missing connect data $connect_data_name"
21937                 }
21938 }
21939 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21940
21941 cleanup_247() {
21942         local submount=$1
21943
21944         trap 0
21945         umount_client $submount
21946         rmdir $submount
21947 }
21948
21949 test_247a() {
21950         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21951                 grep -q subtree ||
21952                 skip_env "Fileset feature is not supported"
21953
21954         local submount=${MOUNT}_$tdir
21955
21956         mkdir $MOUNT/$tdir
21957         mkdir -p $submount || error "mkdir $submount failed"
21958         FILESET="$FILESET/$tdir" mount_client $submount ||
21959                 error "mount $submount failed"
21960         trap "cleanup_247 $submount" EXIT
21961         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21962         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21963                 error "read $MOUNT/$tdir/$tfile failed"
21964         cleanup_247 $submount
21965 }
21966 run_test 247a "mount subdir as fileset"
21967
21968 test_247b() {
21969         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21970                 skip_env "Fileset feature is not supported"
21971
21972         local submount=${MOUNT}_$tdir
21973
21974         rm -rf $MOUNT/$tdir
21975         mkdir -p $submount || error "mkdir $submount failed"
21976         SKIP_FILESET=1
21977         FILESET="$FILESET/$tdir" mount_client $submount &&
21978                 error "mount $submount should fail"
21979         rmdir $submount
21980 }
21981 run_test 247b "mount subdir that dose not exist"
21982
21983 test_247c() {
21984         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21985                 skip_env "Fileset feature is not supported"
21986
21987         local submount=${MOUNT}_$tdir
21988
21989         mkdir -p $MOUNT/$tdir/dir1
21990         mkdir -p $submount || error "mkdir $submount failed"
21991         trap "cleanup_247 $submount" EXIT
21992         FILESET="$FILESET/$tdir" mount_client $submount ||
21993                 error "mount $submount failed"
21994         local fid=$($LFS path2fid $MOUNT/)
21995         $LFS fid2path $submount $fid && error "fid2path should fail"
21996         cleanup_247 $submount
21997 }
21998 run_test 247c "running fid2path outside subdirectory root"
21999
22000 test_247d() {
22001         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22002                 skip "Fileset feature is not supported"
22003
22004         local submount=${MOUNT}_$tdir
22005
22006         mkdir -p $MOUNT/$tdir/dir1
22007         mkdir -p $submount || error "mkdir $submount failed"
22008         FILESET="$FILESET/$tdir" mount_client $submount ||
22009                 error "mount $submount failed"
22010         trap "cleanup_247 $submount" EXIT
22011
22012         local td=$submount/dir1
22013         local fid=$($LFS path2fid $td)
22014         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22015
22016         # check that we get the same pathname back
22017         local rootpath
22018         local found
22019         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22020                 echo "$rootpath $fid"
22021                 found=$($LFS fid2path $rootpath "$fid")
22022                 [ -n "$found" ] || error "fid2path should succeed"
22023                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22024         done
22025         # check wrong root path format
22026         rootpath=$submount"_wrong"
22027         found=$($LFS fid2path $rootpath "$fid")
22028         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22029
22030         cleanup_247 $submount
22031 }
22032 run_test 247d "running fid2path inside subdirectory root"
22033
22034 # LU-8037
22035 test_247e() {
22036         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22037                 grep -q subtree ||
22038                 skip "Fileset feature is not supported"
22039
22040         local submount=${MOUNT}_$tdir
22041
22042         mkdir $MOUNT/$tdir
22043         mkdir -p $submount || error "mkdir $submount failed"
22044         FILESET="$FILESET/.." mount_client $submount &&
22045                 error "mount $submount should fail"
22046         rmdir $submount
22047 }
22048 run_test 247e "mount .. as fileset"
22049
22050 test_247f() {
22051         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22052         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22053                 skip "Need at least version 2.14.50.162"
22054         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22055                 skip "Fileset feature is not supported"
22056
22057         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22058         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22059                 error "mkdir remote failed"
22060         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22061                 error "mkdir remote/subdir failed"
22062         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22063                 error "mkdir striped failed"
22064         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22065
22066         local submount=${MOUNT}_$tdir
22067
22068         mkdir -p $submount || error "mkdir $submount failed"
22069         stack_trap "rmdir $submount"
22070
22071         local dir
22072         local fileset=$FILESET
22073         local mdts=$(comma_list $(mdts_nodes))
22074
22075         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22076         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22077                 $tdir/striped/subdir $tdir/striped/.; do
22078                 FILESET="$fileset/$dir" mount_client $submount ||
22079                         error "mount $dir failed"
22080                 umount_client $submount
22081         done
22082 }
22083 run_test 247f "mount striped or remote directory as fileset"
22084
22085 test_subdir_mount_lock()
22086 {
22087         local testdir=$1
22088         local submount=${MOUNT}_$(basename $testdir)
22089
22090         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22091
22092         mkdir -p $submount || error "mkdir $submount failed"
22093         stack_trap "rmdir $submount"
22094
22095         FILESET="$fileset/$testdir" mount_client $submount ||
22096                 error "mount $FILESET failed"
22097         stack_trap "umount $submount"
22098
22099         local mdts=$(comma_list $(mdts_nodes))
22100
22101         local nrpcs
22102
22103         stat $submount > /dev/null || error "stat $submount failed"
22104         cancel_lru_locks $MDC
22105         stat $submount > /dev/null || error "stat $submount failed"
22106         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22107         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22108         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22109         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22110                 awk '/getattr/ {sum += $2} END {print sum}')
22111
22112         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22113 }
22114
22115 test_247g() {
22116         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22117
22118         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22119                 error "mkdir $tdir failed"
22120         test_subdir_mount_lock $tdir
22121 }
22122 run_test 247g "striped directory submount revalidate ROOT from cache"
22123
22124 test_247h() {
22125         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22126         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22127                 skip "Need MDS version at least 2.15.51"
22128
22129         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22130         test_subdir_mount_lock $tdir
22131         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22132         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22133                 error "mkdir $tdir.1 failed"
22134         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22135 }
22136 run_test 247h "remote directory submount revalidate ROOT from cache"
22137
22138 test_248a() {
22139         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22140         [ -z "$fast_read_sav" ] && skip "no fast read support"
22141
22142         # create a large file for fast read verification
22143         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22144
22145         # make sure the file is created correctly
22146         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22147                 { rm -f $DIR/$tfile; skip "file creation error"; }
22148
22149         echo "Test 1: verify that fast read is 4 times faster on cache read"
22150
22151         # small read with fast read enabled
22152         $LCTL set_param -n llite.*.fast_read=1
22153         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22154                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22155                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22156         # small read with fast read disabled
22157         $LCTL set_param -n llite.*.fast_read=0
22158         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22159                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22160                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22161
22162         # verify that fast read is 4 times faster for cache read
22163         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22164                 error_not_in_vm "fast read was not 4 times faster: " \
22165                            "$t_fast vs $t_slow"
22166
22167         echo "Test 2: verify the performance between big and small read"
22168         $LCTL set_param -n llite.*.fast_read=1
22169
22170         # 1k non-cache read
22171         cancel_lru_locks osc
22172         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22173                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22174                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22175
22176         # 1M non-cache read
22177         cancel_lru_locks osc
22178         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22179                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22180                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22181
22182         # verify that big IO is not 4 times faster than small IO
22183         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22184                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22185
22186         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22187         rm -f $DIR/$tfile
22188 }
22189 run_test 248a "fast read verification"
22190
22191 test_248b() {
22192         # Default short_io_bytes=16384, try both smaller and larger sizes.
22193         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22194         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22195         echo "bs=53248 count=113 normal buffered write"
22196         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22197                 error "dd of initial data file failed"
22198         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22199
22200         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22201         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22202                 error "dd with sync normal writes failed"
22203         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22204
22205         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22206         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22207                 error "dd with sync small writes failed"
22208         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22209
22210         cancel_lru_locks osc
22211
22212         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22213         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22214         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22215         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22216                 iflag=direct || error "dd with O_DIRECT small read failed"
22217         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22218         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22219                 error "compare $TMP/$tfile.1 failed"
22220
22221         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22222         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22223
22224         # just to see what the maximum tunable value is, and test parsing
22225         echo "test invalid parameter 2MB"
22226         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22227                 error "too-large short_io_bytes allowed"
22228         echo "test maximum parameter 512KB"
22229         # if we can set a larger short_io_bytes, run test regardless of version
22230         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22231                 # older clients may not allow setting it this large, that's OK
22232                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22233                         skip "Need at least client version 2.13.50"
22234                 error "medium short_io_bytes failed"
22235         fi
22236         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22237         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22238
22239         echo "test large parameter 64KB"
22240         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22241         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22242
22243         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22244         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22245                 error "dd with sync large writes failed"
22246         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22247
22248         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22249         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22250         num=$((113 * 4096 / PAGE_SIZE))
22251         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22252         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22253                 error "dd with O_DIRECT large writes failed"
22254         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22255                 error "compare $DIR/$tfile.3 failed"
22256
22257         cancel_lru_locks osc
22258
22259         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22260         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22261                 error "dd with O_DIRECT large read failed"
22262         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22263                 error "compare $TMP/$tfile.2 failed"
22264
22265         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22266         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22267                 error "dd with O_DIRECT large read failed"
22268         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22269                 error "compare $TMP/$tfile.3 failed"
22270 }
22271 run_test 248b "test short_io read and write for both small and large sizes"
22272
22273 test_249() { # LU-7890
22274         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22275                 skip "Need at least version 2.8.54"
22276
22277         rm -f $DIR/$tfile
22278         $LFS setstripe -c 1 $DIR/$tfile
22279         # Offset 2T == 4k * 512M
22280         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22281                 error "dd to 2T offset failed"
22282 }
22283 run_test 249 "Write above 2T file size"
22284
22285 test_250() {
22286         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22287          && skip "no 16TB file size limit on ZFS"
22288
22289         $LFS setstripe -c 1 $DIR/$tfile
22290         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22291         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22292         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22293         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22294                 conv=notrunc,fsync && error "append succeeded"
22295         return 0
22296 }
22297 run_test 250 "Write above 16T limit"
22298
22299 test_251() {
22300         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22301
22302         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22303         #Skip once - writing the first stripe will succeed
22304         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22305         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22306                 error "short write happened"
22307
22308         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22309         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22310                 error "short read happened"
22311
22312         rm -f $DIR/$tfile
22313 }
22314 run_test 251 "Handling short read and write correctly"
22315
22316 test_252() {
22317         remote_mds_nodsh && skip "remote MDS with nodsh"
22318         remote_ost_nodsh && skip "remote OST with nodsh"
22319         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22320                 skip_env "ldiskfs only test"
22321         fi
22322
22323         local tgt
22324         local dev
22325         local out
22326         local uuid
22327         local num
22328         local gen
22329
22330         # check lr_reader on OST0000
22331         tgt=ost1
22332         dev=$(facet_device $tgt)
22333         out=$(do_facet $tgt $LR_READER $dev)
22334         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22335         echo "$out"
22336         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22337         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22338                 error "Invalid uuid returned by $LR_READER on target $tgt"
22339         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22340
22341         # check lr_reader -c on MDT0000
22342         tgt=mds1
22343         dev=$(facet_device $tgt)
22344         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22345                 skip "$LR_READER does not support additional options"
22346         fi
22347         out=$(do_facet $tgt $LR_READER -c $dev)
22348         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22349         echo "$out"
22350         num=$(echo "$out" | grep -c "mdtlov")
22351         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22352                 error "Invalid number of mdtlov clients returned by $LR_READER"
22353         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22354
22355         # check lr_reader -cr on MDT0000
22356         out=$(do_facet $tgt $LR_READER -cr $dev)
22357         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22358         echo "$out"
22359         echo "$out" | grep -q "^reply_data:$" ||
22360                 error "$LR_READER should have returned 'reply_data' section"
22361         num=$(echo "$out" | grep -c "client_generation")
22362         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22363 }
22364 run_test 252 "check lr_reader tool"
22365
22366 test_253() {
22367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22368         remote_mds_nodsh && skip "remote MDS with nodsh"
22369         remote_mgs_nodsh && skip "remote MGS with nodsh"
22370
22371         local ostidx=0
22372         local rc=0
22373         local ost_name=$(ostname_from_index $ostidx)
22374
22375         # on the mdt's osc
22376         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22377         do_facet $SINGLEMDS $LCTL get_param -n \
22378                 osp.$mdtosc_proc1.reserved_mb_high ||
22379                 skip  "remote MDS does not support reserved_mb_high"
22380
22381         rm -rf $DIR/$tdir
22382         wait_mds_ost_sync
22383         wait_delete_completed
22384         mkdir $DIR/$tdir
22385
22386         pool_add $TESTNAME || error "Pool creation failed"
22387         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22388
22389         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22390                 error "Setstripe failed"
22391
22392         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22393
22394         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22395                     grep "watermarks")
22396         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22397
22398         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22399                         osp.$mdtosc_proc1.prealloc_status)
22400         echo "prealloc_status $oa_status"
22401
22402         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22403                 error "File creation should fail"
22404
22405         #object allocation was stopped, but we still able to append files
22406         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22407                 oflag=append || error "Append failed"
22408
22409         rm -f $DIR/$tdir/$tfile.0
22410
22411         # For this test, we want to delete the files we created to go out of
22412         # space but leave the watermark, so we remain nearly out of space
22413         ost_watermarks_enospc_delete_files $tfile $ostidx
22414
22415         wait_delete_completed
22416
22417         sleep_maxage
22418
22419         for i in $(seq 10 12); do
22420                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22421                         2>/dev/null || error "File creation failed after rm"
22422         done
22423
22424         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22425                         osp.$mdtosc_proc1.prealloc_status)
22426         echo "prealloc_status $oa_status"
22427
22428         if (( oa_status != 0 )); then
22429                 error "Object allocation still disable after rm"
22430         fi
22431 }
22432 run_test 253 "Check object allocation limit"
22433
22434 test_254() {
22435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22436         remote_mds_nodsh && skip "remote MDS with nodsh"
22437
22438         local mdt=$(facet_svc $SINGLEMDS)
22439
22440         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22441                 skip "MDS does not support changelog_size"
22442
22443         local cl_user
22444
22445         changelog_register || error "changelog_register failed"
22446
22447         changelog_clear 0 || error "changelog_clear failed"
22448
22449         local size1=$(do_facet $SINGLEMDS \
22450                       $LCTL get_param -n mdd.$mdt.changelog_size)
22451         echo "Changelog size $size1"
22452
22453         rm -rf $DIR/$tdir
22454         $LFS mkdir -i 0 $DIR/$tdir
22455         # change something
22456         mkdir -p $DIR/$tdir/pics/2008/zachy
22457         touch $DIR/$tdir/pics/2008/zachy/timestamp
22458         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22459         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22460         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22461         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22462         rm $DIR/$tdir/pics/desktop.jpg
22463
22464         local size2=$(do_facet $SINGLEMDS \
22465                       $LCTL get_param -n mdd.$mdt.changelog_size)
22466         echo "Changelog size after work $size2"
22467
22468         (( $size2 > $size1 )) ||
22469                 error "new Changelog size=$size2 less than old size=$size1"
22470 }
22471 run_test 254 "Check changelog size"
22472
22473 ladvise_no_type()
22474 {
22475         local type=$1
22476         local file=$2
22477
22478         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22479                 awk -F: '{print $2}' | grep $type > /dev/null
22480         if [ $? -ne 0 ]; then
22481                 return 0
22482         fi
22483         return 1
22484 }
22485
22486 ladvise_no_ioctl()
22487 {
22488         local file=$1
22489
22490         lfs ladvise -a willread $file > /dev/null 2>&1
22491         if [ $? -eq 0 ]; then
22492                 return 1
22493         fi
22494
22495         lfs ladvise -a willread $file 2>&1 |
22496                 grep "Inappropriate ioctl for device" > /dev/null
22497         if [ $? -eq 0 ]; then
22498                 return 0
22499         fi
22500         return 1
22501 }
22502
22503 percent() {
22504         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22505 }
22506
22507 # run a random read IO workload
22508 # usage: random_read_iops <filename> <filesize> <iosize>
22509 random_read_iops() {
22510         local file=$1
22511         local fsize=$2
22512         local iosize=${3:-4096}
22513
22514         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22515                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22516 }
22517
22518 drop_file_oss_cache() {
22519         local file="$1"
22520         local nodes="$2"
22521
22522         $LFS ladvise -a dontneed $file 2>/dev/null ||
22523                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22524 }
22525
22526 ladvise_willread_performance()
22527 {
22528         local repeat=10
22529         local average_origin=0
22530         local average_cache=0
22531         local average_ladvise=0
22532
22533         for ((i = 1; i <= $repeat; i++)); do
22534                 echo "Iter $i/$repeat: reading without willread hint"
22535                 cancel_lru_locks osc
22536                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22537                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22538                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22539                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22540
22541                 cancel_lru_locks osc
22542                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22543                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22544                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22545
22546                 cancel_lru_locks osc
22547                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22548                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22549                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22550                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22551                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22552         done
22553         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22554         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22555         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22556
22557         speedup_cache=$(percent $average_cache $average_origin)
22558         speedup_ladvise=$(percent $average_ladvise $average_origin)
22559
22560         echo "Average uncached read: $average_origin"
22561         echo "Average speedup with OSS cached read: " \
22562                 "$average_cache = +$speedup_cache%"
22563         echo "Average speedup with ladvise willread: " \
22564                 "$average_ladvise = +$speedup_ladvise%"
22565
22566         local lowest_speedup=20
22567         if (( ${average_cache%.*} < $lowest_speedup )); then
22568                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22569                      " got $average_cache%. Skipping ladvise willread check."
22570                 return 0
22571         fi
22572
22573         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22574         # it is still good to run until then to exercise 'ladvise willread'
22575         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22576                 [ "$ost1_FSTYPE" = "zfs" ] &&
22577                 echo "osd-zfs does not support dontneed or drop_caches" &&
22578                 return 0
22579
22580         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22581         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22582                 error_not_in_vm "Speedup with willread is less than " \
22583                         "$lowest_speedup%, got $average_ladvise%"
22584 }
22585
22586 test_255a() {
22587         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22588                 skip "lustre < 2.8.54 does not support ladvise "
22589         remote_ost_nodsh && skip "remote OST with nodsh"
22590
22591         stack_trap "rm -f $DIR/$tfile"
22592         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22593
22594         ladvise_no_type willread $DIR/$tfile &&
22595                 skip "willread ladvise is not supported"
22596
22597         ladvise_no_ioctl $DIR/$tfile &&
22598                 skip "ladvise ioctl is not supported"
22599
22600         local size_mb=100
22601         local size=$((size_mb * 1048576))
22602         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22603                 error "dd to $DIR/$tfile failed"
22604
22605         lfs ladvise -a willread $DIR/$tfile ||
22606                 error "Ladvise failed with no range argument"
22607
22608         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22609                 error "Ladvise failed with no -l or -e argument"
22610
22611         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22612                 error "Ladvise failed with only -e argument"
22613
22614         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22615                 error "Ladvise failed with only -l argument"
22616
22617         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22618                 error "End offset should not be smaller than start offset"
22619
22620         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22621                 error "End offset should not be equal to start offset"
22622
22623         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22624                 error "Ladvise failed with overflowing -s argument"
22625
22626         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22627                 error "Ladvise failed with overflowing -e argument"
22628
22629         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22630                 error "Ladvise failed with overflowing -l argument"
22631
22632         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22633                 error "Ladvise succeeded with conflicting -l and -e arguments"
22634
22635         echo "Synchronous ladvise should wait"
22636         local delay=4
22637 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22638         do_nodes $(comma_list $(osts_nodes)) \
22639                 $LCTL set_param fail_val=$delay fail_loc=0x237
22640
22641         local start_ts=$SECONDS
22642         lfs ladvise -a willread $DIR/$tfile ||
22643                 error "Ladvise failed with no range argument"
22644         local end_ts=$SECONDS
22645         local inteval_ts=$((end_ts - start_ts))
22646
22647         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22648                 error "Synchronous advice didn't wait reply"
22649         fi
22650
22651         echo "Asynchronous ladvise shouldn't wait"
22652         local start_ts=$SECONDS
22653         lfs ladvise -a willread -b $DIR/$tfile ||
22654                 error "Ladvise failed with no range argument"
22655         local end_ts=$SECONDS
22656         local inteval_ts=$((end_ts - start_ts))
22657
22658         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22659                 error "Asynchronous advice blocked"
22660         fi
22661
22662         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22663         ladvise_willread_performance
22664 }
22665 run_test 255a "check 'lfs ladvise -a willread'"
22666
22667 facet_meminfo() {
22668         local facet=$1
22669         local info=$2
22670
22671         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22672 }
22673
22674 test_255b() {
22675         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22676                 skip "lustre < 2.8.54 does not support ladvise "
22677         remote_ost_nodsh && skip "remote OST with nodsh"
22678
22679         stack_trap "rm -f $DIR/$tfile"
22680         lfs setstripe -c 1 -i 0 $DIR/$tfile
22681
22682         ladvise_no_type dontneed $DIR/$tfile &&
22683                 skip "dontneed ladvise is not supported"
22684
22685         ladvise_no_ioctl $DIR/$tfile &&
22686                 skip "ladvise ioctl is not supported"
22687
22688         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22689                 [ "$ost1_FSTYPE" = "zfs" ] &&
22690                 skip "zfs-osd does not support 'ladvise dontneed'"
22691
22692         local size_mb=100
22693         local size=$((size_mb * 1048576))
22694         # In order to prevent disturbance of other processes, only check 3/4
22695         # of the memory usage
22696         local kibibytes=$((size_mb * 1024 * 3 / 4))
22697
22698         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22699                 error "dd to $DIR/$tfile failed"
22700
22701         #force write to complete before dropping OST cache & checking memory
22702         sync
22703
22704         local total=$(facet_meminfo ost1 MemTotal)
22705         echo "Total memory: $total KiB"
22706
22707         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22708         local before_read=$(facet_meminfo ost1 Cached)
22709         echo "Cache used before read: $before_read KiB"
22710
22711         lfs ladvise -a willread $DIR/$tfile ||
22712                 error "Ladvise willread failed"
22713         local after_read=$(facet_meminfo ost1 Cached)
22714         echo "Cache used after read: $after_read KiB"
22715
22716         lfs ladvise -a dontneed $DIR/$tfile ||
22717                 error "Ladvise dontneed again failed"
22718         local no_read=$(facet_meminfo ost1 Cached)
22719         echo "Cache used after dontneed ladvise: $no_read KiB"
22720
22721         if [ $total -lt $((before_read + kibibytes)) ]; then
22722                 echo "Memory is too small, abort checking"
22723                 return 0
22724         fi
22725
22726         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22727                 error "Ladvise willread should use more memory" \
22728                         "than $kibibytes KiB"
22729         fi
22730
22731         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22732                 error "Ladvise dontneed should release more memory" \
22733                         "than $kibibytes KiB"
22734         fi
22735 }
22736 run_test 255b "check 'lfs ladvise -a dontneed'"
22737
22738 test_255c() {
22739         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22740                 skip "lustre < 2.10.50 does not support lockahead"
22741
22742         local ost1_imp=$(get_osc_import_name client ost1)
22743         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22744                          cut -d'.' -f2)
22745         local count
22746         local new_count
22747         local difference
22748         local i
22749         local rc
22750
22751         test_mkdir -p $DIR/$tdir
22752         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22753
22754         #test 10 returns only success/failure
22755         i=10
22756         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22757         rc=$?
22758         if [ $rc -eq 255 ]; then
22759                 error "Ladvise test${i} failed, ${rc}"
22760         fi
22761
22762         #test 11 counts lock enqueue requests, all others count new locks
22763         i=11
22764         count=$(do_facet ost1 \
22765                 $LCTL get_param -n ost.OSS.ost.stats)
22766         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22767
22768         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22769         rc=$?
22770         if [ $rc -eq 255 ]; then
22771                 error "Ladvise test${i} failed, ${rc}"
22772         fi
22773
22774         new_count=$(do_facet ost1 \
22775                 $LCTL get_param -n ost.OSS.ost.stats)
22776         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22777                    awk '{ print $2 }')
22778
22779         difference="$((new_count - count))"
22780         if [ $difference -ne $rc ]; then
22781                 error "Ladvise test${i}, bad enqueue count, returned " \
22782                       "${rc}, actual ${difference}"
22783         fi
22784
22785         for i in $(seq 12 21); do
22786                 # If we do not do this, we run the risk of having too many
22787                 # locks and starting lock cancellation while we are checking
22788                 # lock counts.
22789                 cancel_lru_locks osc
22790
22791                 count=$($LCTL get_param -n \
22792                        ldlm.namespaces.$imp_name.lock_unused_count)
22793
22794                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22795                 rc=$?
22796                 if [ $rc -eq 255 ]; then
22797                         error "Ladvise test ${i} failed, ${rc}"
22798                 fi
22799
22800                 new_count=$($LCTL get_param -n \
22801                        ldlm.namespaces.$imp_name.lock_unused_count)
22802                 difference="$((new_count - count))"
22803
22804                 # Test 15 output is divided by 100 to map down to valid return
22805                 if [ $i -eq 15 ]; then
22806                         rc="$((rc * 100))"
22807                 fi
22808
22809                 if [ $difference -ne $rc ]; then
22810                         error "Ladvise test ${i}, bad lock count, returned " \
22811                               "${rc}, actual ${difference}"
22812                 fi
22813         done
22814
22815         #test 22 returns only success/failure
22816         i=22
22817         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22818         rc=$?
22819         if [ $rc -eq 255 ]; then
22820                 error "Ladvise test${i} failed, ${rc}"
22821         fi
22822 }
22823 run_test 255c "suite of ladvise lockahead tests"
22824
22825 test_256() {
22826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22827         remote_mds_nodsh && skip "remote MDS with nodsh"
22828         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22829         changelog_users $SINGLEMDS | grep "^cl" &&
22830                 skip "active changelog user"
22831
22832         local cl_user
22833         local cat_sl
22834         local mdt_dev
22835
22836         mdt_dev=$(facet_device $SINGLEMDS)
22837         echo $mdt_dev
22838
22839         changelog_register || error "changelog_register failed"
22840
22841         rm -rf $DIR/$tdir
22842         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22843
22844         changelog_clear 0 || error "changelog_clear failed"
22845
22846         # change something
22847         touch $DIR/$tdir/{1..10}
22848
22849         # stop the MDT
22850         stop $SINGLEMDS || error "Fail to stop MDT"
22851
22852         # remount the MDT
22853         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22854                 error "Fail to start MDT"
22855
22856         #after mount new plainllog is used
22857         touch $DIR/$tdir/{11..19}
22858         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22859         stack_trap "rm -f $tmpfile"
22860         cat_sl=$(do_facet $SINGLEMDS "sync; \
22861                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22862                  llog_reader $tmpfile | grep -c type=1064553b")
22863         do_facet $SINGLEMDS llog_reader $tmpfile
22864
22865         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22866
22867         changelog_clear 0 || error "changelog_clear failed"
22868
22869         cat_sl=$(do_facet $SINGLEMDS "sync; \
22870                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22871                  llog_reader $tmpfile | grep -c type=1064553b")
22872
22873         if (( cat_sl == 2 )); then
22874                 error "Empty plain llog was not deleted from changelog catalog"
22875         elif (( cat_sl != 1 )); then
22876                 error "Active plain llog shouldn't be deleted from catalog"
22877         fi
22878 }
22879 run_test 256 "Check llog delete for empty and not full state"
22880
22881 test_257() {
22882         remote_mds_nodsh && skip "remote MDS with nodsh"
22883         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22884                 skip "Need MDS version at least 2.8.55"
22885
22886         test_mkdir $DIR/$tdir
22887
22888         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22889                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22890         stat $DIR/$tdir
22891
22892 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22893         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22894         local facet=mds$((mdtidx + 1))
22895         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22896         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22897
22898         stop $facet || error "stop MDS failed"
22899         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22900                 error "start MDS fail"
22901         wait_recovery_complete $facet
22902 }
22903 run_test 257 "xattr locks are not lost"
22904
22905 # Verify we take the i_mutex when security requires it
22906 test_258a() {
22907 #define OBD_FAIL_IMUTEX_SEC 0x141c
22908         $LCTL set_param fail_loc=0x141c
22909         touch $DIR/$tfile
22910         chmod u+s $DIR/$tfile
22911         chmod a+rwx $DIR/$tfile
22912         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22913         RC=$?
22914         if [ $RC -ne 0 ]; then
22915                 error "error, failed to take i_mutex, rc=$?"
22916         fi
22917         rm -f $DIR/$tfile
22918 }
22919 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22920
22921 # Verify we do NOT take the i_mutex in the normal case
22922 test_258b() {
22923 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22924         $LCTL set_param fail_loc=0x141d
22925         touch $DIR/$tfile
22926         chmod a+rwx $DIR
22927         chmod a+rw $DIR/$tfile
22928         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22929         RC=$?
22930         if [ $RC -ne 0 ]; then
22931                 error "error, took i_mutex unnecessarily, rc=$?"
22932         fi
22933         rm -f $DIR/$tfile
22934
22935 }
22936 run_test 258b "verify i_mutex security behavior"
22937
22938 test_259() {
22939         local file=$DIR/$tfile
22940         local before
22941         local after
22942
22943         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22944
22945         stack_trap "rm -f $file" EXIT
22946
22947         wait_delete_completed
22948         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22949         echo "before: $before"
22950
22951         $LFS setstripe -i 0 -c 1 $file
22952         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22953         sync_all_data
22954         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22955         echo "after write: $after"
22956
22957 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22958         do_facet ost1 $LCTL set_param fail_loc=0x2301
22959         $TRUNCATE $file 0
22960         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22961         echo "after truncate: $after"
22962
22963         stop ost1
22964         do_facet ost1 $LCTL set_param fail_loc=0
22965         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22966         sleep 2
22967         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22968         echo "after restart: $after"
22969         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22970                 error "missing truncate?"
22971
22972         return 0
22973 }
22974 run_test 259 "crash at delayed truncate"
22975
22976 test_260() {
22977 #define OBD_FAIL_MDC_CLOSE               0x806
22978         $LCTL set_param fail_loc=0x80000806
22979         touch $DIR/$tfile
22980
22981 }
22982 run_test 260 "Check mdc_close fail"
22983
22984 ### Data-on-MDT sanity tests ###
22985 test_270a() {
22986         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22987                 skip "Need MDS version at least 2.10.55 for DoM"
22988
22989         # create DoM file
22990         local dom=$DIR/$tdir/dom_file
22991         local tmp=$DIR/$tdir/tmp_file
22992
22993         mkdir_on_mdt0 $DIR/$tdir
22994
22995         # basic checks for DoM component creation
22996         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22997                 error "Can set MDT layout to non-first entry"
22998
22999         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23000                 error "Can define multiple entries as MDT layout"
23001
23002         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23003
23004         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23005         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23006         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23007
23008         local mdtidx=$($LFS getstripe -m $dom)
23009         local mdtname=MDT$(printf %04x $mdtidx)
23010         local facet=mds$((mdtidx + 1))
23011         local space_check=1
23012
23013         # Skip free space checks with ZFS
23014         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23015
23016         # write
23017         sync
23018         local size_tmp=$((65536 * 3))
23019         local mdtfree1=$(do_facet $facet \
23020                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23021
23022         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23023         # check also direct IO along write
23024         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23025         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23026         sync
23027         cmp $tmp $dom || error "file data is different"
23028         [ $(stat -c%s $dom) == $size_tmp ] ||
23029                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23030         if [ $space_check == 1 ]; then
23031                 local mdtfree2=$(do_facet $facet \
23032                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23033
23034                 # increase in usage from by $size_tmp
23035                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23036                         error "MDT free space wrong after write: " \
23037                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23038         fi
23039
23040         # truncate
23041         local size_dom=10000
23042
23043         $TRUNCATE $dom $size_dom
23044         [ $(stat -c%s $dom) == $size_dom ] ||
23045                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23046         if [ $space_check == 1 ]; then
23047                 mdtfree1=$(do_facet $facet \
23048                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23049                 # decrease in usage from $size_tmp to new $size_dom
23050                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23051                   $(((size_tmp - size_dom) / 1024)) ] ||
23052                         error "MDT free space is wrong after truncate: " \
23053                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23054         fi
23055
23056         # append
23057         cat $tmp >> $dom
23058         sync
23059         size_dom=$((size_dom + size_tmp))
23060         [ $(stat -c%s $dom) == $size_dom ] ||
23061                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23062         if [ $space_check == 1 ]; then
23063                 mdtfree2=$(do_facet $facet \
23064                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23065                 # increase in usage by $size_tmp from previous
23066                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23067                         error "MDT free space is wrong after append: " \
23068                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23069         fi
23070
23071         # delete
23072         rm $dom
23073         if [ $space_check == 1 ]; then
23074                 mdtfree1=$(do_facet $facet \
23075                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23076                 # decrease in usage by $size_dom from previous
23077                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23078                         error "MDT free space is wrong after removal: " \
23079                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23080         fi
23081
23082         # combined striping
23083         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23084                 error "Can't create DoM + OST striping"
23085
23086         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23087         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23088         # check also direct IO along write
23089         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23090         sync
23091         cmp $tmp $dom || error "file data is different"
23092         [ $(stat -c%s $dom) == $size_tmp ] ||
23093                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23094         rm $dom $tmp
23095
23096         return 0
23097 }
23098 run_test 270a "DoM: basic functionality tests"
23099
23100 test_270b() {
23101         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23102                 skip "Need MDS version at least 2.10.55"
23103
23104         local dom=$DIR/$tdir/dom_file
23105         local max_size=1048576
23106
23107         mkdir -p $DIR/$tdir
23108         $LFS setstripe -E $max_size -L mdt $dom
23109
23110         # truncate over the limit
23111         $TRUNCATE $dom $(($max_size + 1)) &&
23112                 error "successful truncate over the maximum size"
23113         # write over the limit
23114         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23115                 error "successful write over the maximum size"
23116         # append over the limit
23117         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23118         echo "12345" >> $dom && error "successful append over the maximum size"
23119         rm $dom
23120
23121         return 0
23122 }
23123 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23124
23125 test_270c() {
23126         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23127                 skip "Need MDS version at least 2.10.55"
23128
23129         mkdir -p $DIR/$tdir
23130         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23131
23132         # check files inherit DoM EA
23133         touch $DIR/$tdir/first
23134         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23135                 error "bad pattern"
23136         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23137                 error "bad stripe count"
23138         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23139                 error "bad stripe size"
23140
23141         # check directory inherits DoM EA and uses it as default
23142         mkdir $DIR/$tdir/subdir
23143         touch $DIR/$tdir/subdir/second
23144         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23145                 error "bad pattern in sub-directory"
23146         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23147                 error "bad stripe count in sub-directory"
23148         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23149                 error "bad stripe size in sub-directory"
23150         return 0
23151 }
23152 run_test 270c "DoM: DoM EA inheritance tests"
23153
23154 test_270d() {
23155         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23156                 skip "Need MDS version at least 2.10.55"
23157
23158         mkdir -p $DIR/$tdir
23159         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23160
23161         # inherit default DoM striping
23162         mkdir $DIR/$tdir/subdir
23163         touch $DIR/$tdir/subdir/f1
23164
23165         # change default directory striping
23166         $LFS setstripe -c 1 $DIR/$tdir/subdir
23167         touch $DIR/$tdir/subdir/f2
23168         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23169                 error "wrong default striping in file 2"
23170         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23171                 error "bad pattern in file 2"
23172         return 0
23173 }
23174 run_test 270d "DoM: change striping from DoM to RAID0"
23175
23176 test_270e() {
23177         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23178                 skip "Need MDS version at least 2.10.55"
23179
23180         mkdir -p $DIR/$tdir/dom
23181         mkdir -p $DIR/$tdir/norm
23182         DOMFILES=20
23183         NORMFILES=10
23184         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23185         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23186
23187         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23188         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23189
23190         # find DoM files by layout
23191         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23192         [ $NUM -eq  $DOMFILES ] ||
23193                 error "lfs find -L: found $NUM, expected $DOMFILES"
23194         echo "Test 1: lfs find 20 DOM files by layout: OK"
23195
23196         # there should be 1 dir with default DOM striping
23197         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23198         [ $NUM -eq  1 ] ||
23199                 error "lfs find -L: found $NUM, expected 1 dir"
23200         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23201
23202         # find DoM files by stripe size
23203         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23204         [ $NUM -eq  $DOMFILES ] ||
23205                 error "lfs find -S: found $NUM, expected $DOMFILES"
23206         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23207
23208         # find files by stripe offset except DoM files
23209         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23210         [ $NUM -eq  $NORMFILES ] ||
23211                 error "lfs find -i: found $NUM, expected $NORMFILES"
23212         echo "Test 5: lfs find no DOM files by stripe index: OK"
23213         return 0
23214 }
23215 run_test 270e "DoM: lfs find with DoM files test"
23216
23217 test_270f() {
23218         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23219                 skip "Need MDS version at least 2.10.55"
23220
23221         local mdtname=${FSNAME}-MDT0000-mdtlov
23222         local dom=$DIR/$tdir/dom_file
23223         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23224                                                 lod.$mdtname.dom_stripesize)
23225         local dom_limit=131072
23226
23227         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23228         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23229                                                 lod.$mdtname.dom_stripesize)
23230         [ ${dom_limit} -eq ${dom_current} ] ||
23231                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23232
23233         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23234         $LFS setstripe -d $DIR/$tdir
23235         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23236                 error "Can't set directory default striping"
23237
23238         # exceed maximum stripe size
23239         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23240                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23241         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23242                 error "Able to create DoM component size more than LOD limit"
23243
23244         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23245         dom_current=$(do_facet mds1 $LCTL get_param -n \
23246                                                 lod.$mdtname.dom_stripesize)
23247         [ 0 -eq ${dom_current} ] ||
23248                 error "Can't set zero DoM stripe limit"
23249         rm $dom
23250
23251         # attempt to create DoM file on server with disabled DoM should
23252         # remove DoM entry from layout and be succeed
23253         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23254                 error "Can't create DoM file (DoM is disabled)"
23255         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23256                 error "File has DoM component while DoM is disabled"
23257         rm $dom
23258
23259         # attempt to create DoM file with only DoM stripe should return error
23260         $LFS setstripe -E $dom_limit -L mdt $dom &&
23261                 error "Able to create DoM-only file while DoM is disabled"
23262
23263         # too low values to be aligned with smallest stripe size 64K
23264         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23265         dom_current=$(do_facet mds1 $LCTL get_param -n \
23266                                                 lod.$mdtname.dom_stripesize)
23267         [ 30000 -eq ${dom_current} ] &&
23268                 error "Can set too small DoM stripe limit"
23269
23270         # 64K is a minimal stripe size in Lustre, expect limit of that size
23271         [ 65536 -eq ${dom_current} ] ||
23272                 error "Limit is not set to 64K but ${dom_current}"
23273
23274         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23275         dom_current=$(do_facet mds1 $LCTL get_param -n \
23276                                                 lod.$mdtname.dom_stripesize)
23277         echo $dom_current
23278         [ 2147483648 -eq ${dom_current} ] &&
23279                 error "Can set too large DoM stripe limit"
23280
23281         do_facet mds1 $LCTL set_param -n \
23282                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23283         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23284                 error "Can't create DoM component size after limit change"
23285         do_facet mds1 $LCTL set_param -n \
23286                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23287         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23288                 error "Can't create DoM file after limit decrease"
23289         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23290                 error "Can create big DoM component after limit decrease"
23291         touch ${dom}_def ||
23292                 error "Can't create file with old default layout"
23293
23294         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23295         return 0
23296 }
23297 run_test 270f "DoM: maximum DoM stripe size checks"
23298
23299 test_270g() {
23300         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23301                 skip "Need MDS version at least 2.13.52"
23302         local dom=$DIR/$tdir/$tfile
23303
23304         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23305         local lodname=${FSNAME}-MDT0000-mdtlov
23306
23307         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23308         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23309         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23310         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23311
23312         local dom_limit=1024
23313         local dom_threshold="50%"
23314
23315         $LFS setstripe -d $DIR/$tdir
23316         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23317                 error "Can't set directory default striping"
23318
23319         do_facet mds1 $LCTL set_param -n \
23320                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23321         # set 0 threshold and create DOM file to change tunable stripesize
23322         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23323         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23324                 error "Failed to create $dom file"
23325         # now tunable dom_cur_stripesize should reach maximum
23326         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23327                                         lod.${lodname}.dom_stripesize_cur_kb)
23328         [[ $dom_current == $dom_limit ]] ||
23329                 error "Current DOM stripesize is not maximum"
23330         rm $dom
23331
23332         # set threshold for further tests
23333         do_facet mds1 $LCTL set_param -n \
23334                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23335         echo "DOM threshold is $dom_threshold free space"
23336         local dom_def
23337         local dom_set
23338         # Spoof bfree to exceed threshold
23339         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23340         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23341         for spfree in 40 20 0 15 30 55; do
23342                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23343                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23344                         error "Failed to create $dom file"
23345                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23346                                         lod.${lodname}.dom_stripesize_cur_kb)
23347                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23348                 [[ $dom_def != $dom_current ]] ||
23349                         error "Default stripe size was not changed"
23350                 if (( spfree > 0 )) ; then
23351                         dom_set=$($LFS getstripe -S $dom)
23352                         (( dom_set == dom_def * 1024 )) ||
23353                                 error "DOM component size is still old"
23354                 else
23355                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23356                                 error "DoM component is set with no free space"
23357                 fi
23358                 rm $dom
23359                 dom_current=$dom_def
23360         done
23361 }
23362 run_test 270g "DoM: default DoM stripe size depends on free space"
23363
23364 test_270h() {
23365         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23366                 skip "Need MDS version at least 2.13.53"
23367
23368         local mdtname=${FSNAME}-MDT0000-mdtlov
23369         local dom=$DIR/$tdir/$tfile
23370         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23371
23372         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23373         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23374
23375         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23376         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23377                 error "can't create OST file"
23378         # mirrored file with DOM entry in the second mirror
23379         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23380                 error "can't create mirror with DoM component"
23381
23382         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23383
23384         # DOM component in the middle and has other enries in the same mirror,
23385         # should succeed but lost DoM component
23386         $LFS setstripe --copy=${dom}_1 $dom ||
23387                 error "Can't create file from OST|DOM mirror layout"
23388         # check new file has no DoM layout after all
23389         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23390                 error "File has DoM component while DoM is disabled"
23391 }
23392 run_test 270h "DoM: DoM stripe removal when disabled on server"
23393
23394 test_270i() {
23395         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23396                 skip "Need MDS version at least 2.14.54"
23397
23398         mkdir $DIR/$tdir
23399         # DoM with plain layout
23400         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23401                 error "default plain layout with DoM must fail"
23402         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23403                 error "setstripe plain file layout with DoM must fail"
23404         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23405                 error "default DoM layout with bad striping must fail"
23406         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23407                 error "setstripe to DoM layout with bad striping must fail"
23408         return 0
23409 }
23410 run_test 270i "DoM: setting invalid DoM striping should fail"
23411
23412 test_271a() {
23413         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23414                 skip "Need MDS version at least 2.10.55"
23415
23416         local dom=$DIR/$tdir/dom
23417
23418         mkdir -p $DIR/$tdir
23419
23420         $LFS setstripe -E 1024K -L mdt $dom
23421
23422         lctl set_param -n mdc.*.stats=clear
23423         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23424         cat $dom > /dev/null
23425         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23426         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23427         ls $dom
23428         rm -f $dom
23429 }
23430 run_test 271a "DoM: data is cached for read after write"
23431
23432 test_271b() {
23433         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23434                 skip "Need MDS version at least 2.10.55"
23435
23436         local dom=$DIR/$tdir/dom
23437
23438         mkdir -p $DIR/$tdir
23439
23440         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23441
23442         lctl set_param -n mdc.*.stats=clear
23443         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23444         cancel_lru_locks mdc
23445         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23446         # second stat to check size is cached on client
23447         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23448         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23449         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23450         rm -f $dom
23451 }
23452 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23453
23454 test_271ba() {
23455         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23456                 skip "Need MDS version at least 2.10.55"
23457
23458         local dom=$DIR/$tdir/dom
23459
23460         mkdir -p $DIR/$tdir
23461
23462         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23463
23464         lctl set_param -n mdc.*.stats=clear
23465         lctl set_param -n osc.*.stats=clear
23466         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23467         cancel_lru_locks mdc
23468         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23469         # second stat to check size is cached on client
23470         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23471         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23472         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23473         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23474         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23475         rm -f $dom
23476 }
23477 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23478
23479
23480 get_mdc_stats() {
23481         local mdtidx=$1
23482         local param=$2
23483         local mdt=MDT$(printf %04x $mdtidx)
23484
23485         if [ -z $param ]; then
23486                 lctl get_param -n mdc.*$mdt*.stats
23487         else
23488                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23489         fi
23490 }
23491
23492 test_271c() {
23493         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23494                 skip "Need MDS version at least 2.10.55"
23495
23496         local dom=$DIR/$tdir/dom
23497
23498         mkdir -p $DIR/$tdir
23499
23500         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23501
23502         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23503         local facet=mds$((mdtidx + 1))
23504
23505         cancel_lru_locks mdc
23506         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23507         createmany -o $dom 1000
23508         lctl set_param -n mdc.*.stats=clear
23509         smalliomany -w $dom 1000 200
23510         get_mdc_stats $mdtidx
23511         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23512         # Each file has 1 open, 1 IO enqueues, total 2000
23513         # but now we have also +1 getxattr for security.capability, total 3000
23514         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23515         unlinkmany $dom 1000
23516
23517         cancel_lru_locks mdc
23518         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23519         createmany -o $dom 1000
23520         lctl set_param -n mdc.*.stats=clear
23521         smalliomany -w $dom 1000 200
23522         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23523         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23524         # for OPEN and IO lock.
23525         [ $((enq - enq_2)) -ge 1000 ] ||
23526                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23527         unlinkmany $dom 1000
23528         return 0
23529 }
23530 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23531
23532 cleanup_271def_tests() {
23533         trap 0
23534         rm -f $1
23535 }
23536
23537 test_271d() {
23538         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23539                 skip "Need MDS version at least 2.10.57"
23540
23541         local dom=$DIR/$tdir/dom
23542         local tmp=$TMP/$tfile
23543         trap "cleanup_271def_tests $tmp" EXIT
23544
23545         mkdir -p $DIR/$tdir
23546
23547         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23548
23549         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23550
23551         cancel_lru_locks mdc
23552         dd if=/dev/urandom of=$tmp bs=1000 count=1
23553         dd if=$tmp of=$dom bs=1000 count=1
23554         cancel_lru_locks mdc
23555
23556         cat /etc/hosts >> $tmp
23557         lctl set_param -n mdc.*.stats=clear
23558
23559         # append data to the same file it should update local page
23560         echo "Append to the same page"
23561         cat /etc/hosts >> $dom
23562         local num=$(get_mdc_stats $mdtidx ost_read)
23563         local ra=$(get_mdc_stats $mdtidx req_active)
23564         local rw=$(get_mdc_stats $mdtidx req_waittime)
23565
23566         [ -z $num ] || error "$num READ RPC occured"
23567         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23568         echo "... DONE"
23569
23570         # compare content
23571         cmp $tmp $dom || error "file miscompare"
23572
23573         cancel_lru_locks mdc
23574         lctl set_param -n mdc.*.stats=clear
23575
23576         echo "Open and read file"
23577         cat $dom > /dev/null
23578         local num=$(get_mdc_stats $mdtidx ost_read)
23579         local ra=$(get_mdc_stats $mdtidx req_active)
23580         local rw=$(get_mdc_stats $mdtidx req_waittime)
23581
23582         [ -z $num ] || error "$num READ RPC occured"
23583         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23584         echo "... DONE"
23585
23586         # compare content
23587         cmp $tmp $dom || error "file miscompare"
23588
23589         return 0
23590 }
23591 run_test 271d "DoM: read on open (1K file in reply buffer)"
23592
23593 test_271f() {
23594         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23595                 skip "Need MDS version at least 2.10.57"
23596
23597         local dom=$DIR/$tdir/dom
23598         local tmp=$TMP/$tfile
23599         trap "cleanup_271def_tests $tmp" EXIT
23600
23601         mkdir -p $DIR/$tdir
23602
23603         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23604
23605         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23606
23607         cancel_lru_locks mdc
23608         dd if=/dev/urandom of=$tmp bs=265000 count=1
23609         dd if=$tmp of=$dom bs=265000 count=1
23610         cancel_lru_locks mdc
23611         cat /etc/hosts >> $tmp
23612         lctl set_param -n mdc.*.stats=clear
23613
23614         echo "Append to the same page"
23615         cat /etc/hosts >> $dom
23616         local num=$(get_mdc_stats $mdtidx ost_read)
23617         local ra=$(get_mdc_stats $mdtidx req_active)
23618         local rw=$(get_mdc_stats $mdtidx req_waittime)
23619
23620         [ -z $num ] || error "$num READ RPC occured"
23621         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23622         echo "... DONE"
23623
23624         # compare content
23625         cmp $tmp $dom || error "file miscompare"
23626
23627         cancel_lru_locks mdc
23628         lctl set_param -n mdc.*.stats=clear
23629
23630         echo "Open and read file"
23631         cat $dom > /dev/null
23632         local num=$(get_mdc_stats $mdtidx ost_read)
23633         local ra=$(get_mdc_stats $mdtidx req_active)
23634         local rw=$(get_mdc_stats $mdtidx req_waittime)
23635
23636         [ -z $num ] && num=0
23637         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23638         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23639         echo "... DONE"
23640
23641         # compare content
23642         cmp $tmp $dom || error "file miscompare"
23643
23644         return 0
23645 }
23646 run_test 271f "DoM: read on open (200K file and read tail)"
23647
23648 test_271g() {
23649         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23650                 skip "Skipping due to old client or server version"
23651
23652         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23653         # to get layout
23654         $CHECKSTAT -t file $DIR1/$tfile
23655
23656         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23657         MULTIOP_PID=$!
23658         sleep 1
23659         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23660         $LCTL set_param fail_loc=0x80000314
23661         rm $DIR1/$tfile || error "Unlink fails"
23662         RC=$?
23663         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23664         [ $RC -eq 0 ] || error "Failed write to stale object"
23665 }
23666 run_test 271g "Discard DoM data vs client flush race"
23667
23668 test_272a() {
23669         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23670                 skip "Need MDS version at least 2.11.50"
23671
23672         local dom=$DIR/$tdir/dom
23673         mkdir -p $DIR/$tdir
23674
23675         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23676         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23677                 error "failed to write data into $dom"
23678         local old_md5=$(md5sum $dom)
23679
23680         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23681                 error "failed to migrate to the same DoM component"
23682
23683         local new_md5=$(md5sum $dom)
23684
23685         [ "$old_md5" == "$new_md5" ] ||
23686                 error "md5sum differ: $old_md5, $new_md5"
23687
23688         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23689                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23690 }
23691 run_test 272a "DoM migration: new layout with the same DOM component"
23692
23693 test_272b() {
23694         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23695                 skip "Need MDS version at least 2.11.50"
23696
23697         local dom=$DIR/$tdir/dom
23698         mkdir -p $DIR/$tdir
23699         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23700
23701         local mdtidx=$($LFS getstripe -m $dom)
23702         local mdtname=MDT$(printf %04x $mdtidx)
23703         local facet=mds$((mdtidx + 1))
23704
23705         local mdtfree1=$(do_facet $facet \
23706                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23707         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23708                 error "failed to write data into $dom"
23709         local old_md5=$(md5sum $dom)
23710         cancel_lru_locks mdc
23711         local mdtfree1=$(do_facet $facet \
23712                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23713
23714         $LFS migrate -c2 $dom ||
23715                 error "failed to migrate to the new composite layout"
23716         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23717                 error "MDT stripe was not removed"
23718
23719         cancel_lru_locks mdc
23720         local new_md5=$(md5sum $dom)
23721         [ "$old_md5" == "$new_md5" ] ||
23722                 error "$old_md5 != $new_md5"
23723
23724         # Skip free space checks with ZFS
23725         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23726                 local mdtfree2=$(do_facet $facet \
23727                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23728                 [ $mdtfree2 -gt $mdtfree1 ] ||
23729                         error "MDT space is not freed after migration"
23730         fi
23731         return 0
23732 }
23733 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23734
23735 test_272c() {
23736         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23737                 skip "Need MDS version at least 2.11.50"
23738
23739         local dom=$DIR/$tdir/$tfile
23740         mkdir -p $DIR/$tdir
23741         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23742
23743         local mdtidx=$($LFS getstripe -m $dom)
23744         local mdtname=MDT$(printf %04x $mdtidx)
23745         local facet=mds$((mdtidx + 1))
23746
23747         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23748                 error "failed to write data into $dom"
23749         local old_md5=$(md5sum $dom)
23750         cancel_lru_locks mdc
23751         local mdtfree1=$(do_facet $facet \
23752                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23753
23754         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23755                 error "failed to migrate to the new composite layout"
23756         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23757                 error "MDT stripe was not removed"
23758
23759         cancel_lru_locks mdc
23760         local new_md5=$(md5sum $dom)
23761         [ "$old_md5" == "$new_md5" ] ||
23762                 error "$old_md5 != $new_md5"
23763
23764         # Skip free space checks with ZFS
23765         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23766                 local mdtfree2=$(do_facet $facet \
23767                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23768                 [ $mdtfree2 -gt $mdtfree1 ] ||
23769                         error "MDS space is not freed after migration"
23770         fi
23771         return 0
23772 }
23773 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23774
23775 test_272d() {
23776         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23777                 skip "Need MDS version at least 2.12.55"
23778
23779         local dom=$DIR/$tdir/$tfile
23780         mkdir -p $DIR/$tdir
23781         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23782
23783         local mdtidx=$($LFS getstripe -m $dom)
23784         local mdtname=MDT$(printf %04x $mdtidx)
23785         local facet=mds$((mdtidx + 1))
23786
23787         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23788                 error "failed to write data into $dom"
23789         local old_md5=$(md5sum $dom)
23790         cancel_lru_locks mdc
23791         local mdtfree1=$(do_facet $facet \
23792                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23793
23794         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23795                 error "failed mirroring to the new composite layout"
23796         $LFS mirror resync $dom ||
23797                 error "failed mirror resync"
23798         $LFS mirror split --mirror-id 1 -d $dom ||
23799                 error "failed mirror split"
23800
23801         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23802                 error "MDT stripe was not removed"
23803
23804         cancel_lru_locks mdc
23805         local new_md5=$(md5sum $dom)
23806         [ "$old_md5" == "$new_md5" ] ||
23807                 error "$old_md5 != $new_md5"
23808
23809         # Skip free space checks with ZFS
23810         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23811                 local mdtfree2=$(do_facet $facet \
23812                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23813                 [ $mdtfree2 -gt $mdtfree1 ] ||
23814                         error "MDS space is not freed after DOM mirror deletion"
23815         fi
23816         return 0
23817 }
23818 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23819
23820 test_272e() {
23821         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23822                 skip "Need MDS version at least 2.12.55"
23823
23824         local dom=$DIR/$tdir/$tfile
23825         mkdir -p $DIR/$tdir
23826         $LFS setstripe -c 2 $dom
23827
23828         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23829                 error "failed to write data into $dom"
23830         local old_md5=$(md5sum $dom)
23831         cancel_lru_locks
23832
23833         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23834                 error "failed mirroring to the DOM layout"
23835         $LFS mirror resync $dom ||
23836                 error "failed mirror resync"
23837         $LFS mirror split --mirror-id 1 -d $dom ||
23838                 error "failed mirror split"
23839
23840         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23841                 error "MDT stripe wasn't set"
23842
23843         cancel_lru_locks
23844         local new_md5=$(md5sum $dom)
23845         [ "$old_md5" == "$new_md5" ] ||
23846                 error "$old_md5 != $new_md5"
23847
23848         return 0
23849 }
23850 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23851
23852 test_272f() {
23853         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23854                 skip "Need MDS version at least 2.12.55"
23855
23856         local dom=$DIR/$tdir/$tfile
23857         mkdir -p $DIR/$tdir
23858         $LFS setstripe -c 2 $dom
23859
23860         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23861                 error "failed to write data into $dom"
23862         local old_md5=$(md5sum $dom)
23863         cancel_lru_locks
23864
23865         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23866                 error "failed migrating to the DOM file"
23867
23868         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23869                 error "MDT stripe wasn't set"
23870
23871         cancel_lru_locks
23872         local new_md5=$(md5sum $dom)
23873         [ "$old_md5" != "$new_md5" ] &&
23874                 error "$old_md5 != $new_md5"
23875
23876         return 0
23877 }
23878 run_test 272f "DoM migration: OST-striped file to DOM file"
23879
23880 test_273a() {
23881         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23882                 skip "Need MDS version at least 2.11.50"
23883
23884         # Layout swap cannot be done if either file has DOM component,
23885         # this will never be supported, migration should be used instead
23886
23887         local dom=$DIR/$tdir/$tfile
23888         mkdir -p $DIR/$tdir
23889
23890         $LFS setstripe -c2 ${dom}_plain
23891         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23892         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23893                 error "can swap layout with DoM component"
23894         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23895                 error "can swap layout with DoM component"
23896
23897         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23898         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23899                 error "can swap layout with DoM component"
23900         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23901                 error "can swap layout with DoM component"
23902         return 0
23903 }
23904 run_test 273a "DoM: layout swapping should fail with DOM"
23905
23906 test_273b() {
23907         mkdir -p $DIR/$tdir
23908         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23909
23910 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23911         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23912
23913         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23914 }
23915 run_test 273b "DoM: race writeback and object destroy"
23916
23917 test_273c() {
23918         mkdir -p $DIR/$tdir
23919         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
23920
23921         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
23922         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
23923
23924         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23925 }
23926 run_test 273c "race writeback and object destroy"
23927
23928 test_275() {
23929         remote_ost_nodsh && skip "remote OST with nodsh"
23930         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23931                 skip "Need OST version >= 2.10.57"
23932
23933         local file=$DIR/$tfile
23934         local oss
23935
23936         oss=$(comma_list $(osts_nodes))
23937
23938         dd if=/dev/urandom of=$file bs=1M count=2 ||
23939                 error "failed to create a file"
23940         cancel_lru_locks osc
23941
23942         #lock 1
23943         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23944                 error "failed to read a file"
23945
23946 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23947         $LCTL set_param fail_loc=0x8000031f
23948
23949         cancel_lru_locks osc &
23950         sleep 1
23951
23952 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23953         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23954         #IO takes another lock, but matches the PENDING one
23955         #and places it to the IO RPC
23956         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23957                 error "failed to read a file with PENDING lock"
23958 }
23959 run_test 275 "Read on a canceled duplicate lock"
23960
23961 test_276() {
23962         remote_ost_nodsh && skip "remote OST with nodsh"
23963         local pid
23964
23965         do_facet ost1 "(while true; do \
23966                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23967                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23968         pid=$!
23969
23970         for LOOP in $(seq 20); do
23971                 stop ost1
23972                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23973         done
23974         kill -9 $pid
23975         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23976                 rm $TMP/sanity_276_pid"
23977 }
23978 run_test 276 "Race between mount and obd_statfs"
23979
23980 test_277() {
23981         $LCTL set_param ldlm.namespaces.*.lru_size=0
23982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23983         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23984                         grep ^used_mb | awk '{print $2}')
23985         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23986         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23987                 oflag=direct conv=notrunc
23988         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23989                         grep ^used_mb | awk '{print $2}')
23990         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23991 }
23992 run_test 277 "Direct IO shall drop page cache"
23993
23994 test_278() {
23995         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23996         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23997         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23998                 skip "needs the same host for mdt1 mdt2" && return
23999
24000         local pid1
24001         local pid2
24002
24003 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24004         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24005         stop mds2 &
24006         pid2=$!
24007
24008         stop mds1
24009
24010         echo "Starting MDTs"
24011         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24012         wait $pid2
24013 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24014 #will return NULL
24015         do_facet mds2 $LCTL set_param fail_loc=0
24016
24017         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24018         wait_recovery_complete mds2
24019 }
24020 run_test 278 "Race starting MDS between MDTs stop/start"
24021
24022 test_280() {
24023         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24024                 skip "Need MGS version at least 2.13.52"
24025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24026         combined_mgs_mds || skip "needs combined MGS/MDT"
24027
24028         umount_client $MOUNT
24029 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24030         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24031
24032         mount_client $MOUNT &
24033         sleep 1
24034         stop mgs || error "stop mgs failed"
24035         #for a race mgs would crash
24036         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24037         # make sure we unmount client before remounting
24038         wait
24039         umount_client $MOUNT
24040         mount_client $MOUNT || error "mount client failed"
24041 }
24042 run_test 280 "Race between MGS umount and client llog processing"
24043
24044 cleanup_test_300() {
24045         trap 0
24046         umask $SAVE_UMASK
24047 }
24048 test_striped_dir() {
24049         local mdt_index=$1
24050         local stripe_count
24051         local stripe_index
24052
24053         mkdir -p $DIR/$tdir
24054
24055         SAVE_UMASK=$(umask)
24056         trap cleanup_test_300 RETURN EXIT
24057
24058         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24059                                                 $DIR/$tdir/striped_dir ||
24060                 error "set striped dir error"
24061
24062         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24063         [ "$mode" = "755" ] || error "expect 755 got $mode"
24064
24065         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24066                 error "getdirstripe failed"
24067         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24068         if [ "$stripe_count" != "2" ]; then
24069                 error "1:stripe_count is $stripe_count, expect 2"
24070         fi
24071         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24072         if [ "$stripe_count" != "2" ]; then
24073                 error "2:stripe_count is $stripe_count, expect 2"
24074         fi
24075
24076         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24077         if [ "$stripe_index" != "$mdt_index" ]; then
24078                 error "stripe_index is $stripe_index, expect $mdt_index"
24079         fi
24080
24081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24082                 error "nlink error after create striped dir"
24083
24084         mkdir $DIR/$tdir/striped_dir/a
24085         mkdir $DIR/$tdir/striped_dir/b
24086
24087         stat $DIR/$tdir/striped_dir/a ||
24088                 error "create dir under striped dir failed"
24089         stat $DIR/$tdir/striped_dir/b ||
24090                 error "create dir under striped dir failed"
24091
24092         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24093                 error "nlink error after mkdir"
24094
24095         rmdir $DIR/$tdir/striped_dir/a
24096         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24097                 error "nlink error after rmdir"
24098
24099         rmdir $DIR/$tdir/striped_dir/b
24100         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24101                 error "nlink error after rmdir"
24102
24103         chattr +i $DIR/$tdir/striped_dir
24104         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24105                 error "immutable flags not working under striped dir!"
24106         chattr -i $DIR/$tdir/striped_dir
24107
24108         rmdir $DIR/$tdir/striped_dir ||
24109                 error "rmdir striped dir error"
24110
24111         cleanup_test_300
24112
24113         true
24114 }
24115
24116 test_300a() {
24117         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24118                 skip "skipped for lustre < 2.7.0"
24119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24121
24122         test_striped_dir 0 || error "failed on striped dir on MDT0"
24123         test_striped_dir 1 || error "failed on striped dir on MDT0"
24124 }
24125 run_test 300a "basic striped dir sanity test"
24126
24127 test_300b() {
24128         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24129                 skip "skipped for lustre < 2.7.0"
24130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24131         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24132
24133         local i
24134         local mtime1
24135         local mtime2
24136         local mtime3
24137
24138         test_mkdir $DIR/$tdir || error "mkdir fail"
24139         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24140                 error "set striped dir error"
24141         for i in {0..9}; do
24142                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24143                 sleep 1
24144                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24145                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24146                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24147                 sleep 1
24148                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24149                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24150                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24151         done
24152         true
24153 }
24154 run_test 300b "check ctime/mtime for striped dir"
24155
24156 test_300c() {
24157         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24158                 skip "skipped for lustre < 2.7.0"
24159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24160         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24161
24162         local file_count
24163
24164         mkdir_on_mdt0 $DIR/$tdir
24165         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24166                 error "set striped dir error"
24167
24168         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24169                 error "chown striped dir failed"
24170
24171         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24172                 error "create 5k files failed"
24173
24174         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24175
24176         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24177
24178         rm -rf $DIR/$tdir
24179 }
24180 run_test 300c "chown && check ls under striped directory"
24181
24182 test_300d() {
24183         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24184                 skip "skipped for lustre < 2.7.0"
24185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24186         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24187
24188         local stripe_count
24189         local file
24190
24191         mkdir -p $DIR/$tdir
24192         $LFS setstripe -c 2 $DIR/$tdir
24193
24194         #local striped directory
24195         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24196                 error "set striped dir error"
24197         #look at the directories for debug purposes
24198         ls -l $DIR/$tdir
24199         $LFS getdirstripe $DIR/$tdir
24200         ls -l $DIR/$tdir/striped_dir
24201         $LFS getdirstripe $DIR/$tdir/striped_dir
24202         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24203                 error "create 10 files failed"
24204
24205         #remote striped directory
24206         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24207                 error "set striped dir error"
24208         #look at the directories for debug purposes
24209         ls -l $DIR/$tdir
24210         $LFS getdirstripe $DIR/$tdir
24211         ls -l $DIR/$tdir/remote_striped_dir
24212         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24213         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24214                 error "create 10 files failed"
24215
24216         for file in $(find $DIR/$tdir); do
24217                 stripe_count=$($LFS getstripe -c $file)
24218                 [ $stripe_count -eq 2 ] ||
24219                         error "wrong stripe $stripe_count for $file"
24220         done
24221
24222         rm -rf $DIR/$tdir
24223 }
24224 run_test 300d "check default stripe under striped directory"
24225
24226 test_300e() {
24227         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24228                 skip "Need MDS version at least 2.7.55"
24229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24230         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24231
24232         local stripe_count
24233         local file
24234
24235         mkdir -p $DIR/$tdir
24236
24237         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24238                 error "set striped dir error"
24239
24240         touch $DIR/$tdir/striped_dir/a
24241         touch $DIR/$tdir/striped_dir/b
24242         touch $DIR/$tdir/striped_dir/c
24243
24244         mkdir $DIR/$tdir/striped_dir/dir_a
24245         mkdir $DIR/$tdir/striped_dir/dir_b
24246         mkdir $DIR/$tdir/striped_dir/dir_c
24247
24248         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24249                 error "set striped adir under striped dir error"
24250
24251         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24252                 error "set striped bdir under striped dir error"
24253
24254         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24255                 error "set striped cdir under striped dir error"
24256
24257         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24258                 error "rename dir under striped dir fails"
24259
24260         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24261                 error "rename dir under different stripes fails"
24262
24263         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24264                 error "rename file under striped dir should succeed"
24265
24266         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24267                 error "rename dir under striped dir should succeed"
24268
24269         rm -rf $DIR/$tdir
24270 }
24271 run_test 300e "check rename under striped directory"
24272
24273 test_300f() {
24274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24276         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24277                 skip "Need MDS version at least 2.7.55"
24278
24279         local stripe_count
24280         local file
24281
24282         rm -rf $DIR/$tdir
24283         mkdir -p $DIR/$tdir
24284
24285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24286                 error "set striped dir error"
24287
24288         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24289                 error "set striped dir error"
24290
24291         touch $DIR/$tdir/striped_dir/a
24292         mkdir $DIR/$tdir/striped_dir/dir_a
24293         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24294                 error "create striped dir under striped dir fails"
24295
24296         touch $DIR/$tdir/striped_dir1/b
24297         mkdir $DIR/$tdir/striped_dir1/dir_b
24298         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24299                 error "create striped dir under striped dir fails"
24300
24301         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24302                 error "rename dir under different striped dir should fail"
24303
24304         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24305                 error "rename striped dir under diff striped dir should fail"
24306
24307         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24308                 error "rename file under diff striped dirs fails"
24309
24310         rm -rf $DIR/$tdir
24311 }
24312 run_test 300f "check rename cross striped directory"
24313
24314 test_300_check_default_striped_dir()
24315 {
24316         local dirname=$1
24317         local default_count=$2
24318         local default_index=$3
24319         local stripe_count
24320         local stripe_index
24321         local dir_stripe_index
24322         local dir
24323
24324         echo "checking $dirname $default_count $default_index"
24325         $LFS setdirstripe -D -c $default_count -i $default_index \
24326                                 -H all_char $DIR/$tdir/$dirname ||
24327                 error "set default stripe on striped dir error"
24328         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24329         [ $stripe_count -eq $default_count ] ||
24330                 error "expect $default_count get $stripe_count for $dirname"
24331
24332         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24333         [ $stripe_index -eq $default_index ] ||
24334                 error "expect $default_index get $stripe_index for $dirname"
24335
24336         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24337                                                 error "create dirs failed"
24338
24339         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24340         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24341         for dir in $(find $DIR/$tdir/$dirname/*); do
24342                 stripe_count=$($LFS getdirstripe -c $dir)
24343                 (( $stripe_count == $default_count )) ||
24344                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24345                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24346                 error "stripe count $default_count != $stripe_count for $dir"
24347
24348                 stripe_index=$($LFS getdirstripe -i $dir)
24349                 [ $default_index -eq -1 ] ||
24350                         [ $stripe_index -eq $default_index ] ||
24351                         error "$stripe_index != $default_index for $dir"
24352
24353                 #check default stripe
24354                 stripe_count=$($LFS getdirstripe -D -c $dir)
24355                 [ $stripe_count -eq $default_count ] ||
24356                 error "default count $default_count != $stripe_count for $dir"
24357
24358                 stripe_index=$($LFS getdirstripe -D -i $dir)
24359                 [ $stripe_index -eq $default_index ] ||
24360                 error "default index $default_index != $stripe_index for $dir"
24361         done
24362         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24363 }
24364
24365 test_300g() {
24366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24367         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24368                 skip "Need MDS version at least 2.7.55"
24369
24370         local dir
24371         local stripe_count
24372         local stripe_index
24373
24374         mkdir_on_mdt0 $DIR/$tdir
24375         mkdir $DIR/$tdir/normal_dir
24376
24377         #Checking when client cache stripe index
24378         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24379         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24380                 error "create striped_dir failed"
24381
24382         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24383                 error "create dir0 fails"
24384         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24385         [ $stripe_index -eq 0 ] ||
24386                 error "dir0 expect index 0 got $stripe_index"
24387
24388         mkdir $DIR/$tdir/striped_dir/dir1 ||
24389                 error "create dir1 fails"
24390         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24391         [ $stripe_index -eq 1 ] ||
24392                 error "dir1 expect index 1 got $stripe_index"
24393
24394         #check default stripe count/stripe index
24395         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24396         test_300_check_default_striped_dir normal_dir 1 0
24397         test_300_check_default_striped_dir normal_dir -1 1
24398         test_300_check_default_striped_dir normal_dir 2 -1
24399
24400         #delete default stripe information
24401         echo "delete default stripeEA"
24402         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24403                 error "set default stripe on striped dir error"
24404
24405         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24406         for dir in $(find $DIR/$tdir/normal_dir/*); do
24407                 stripe_count=$($LFS getdirstripe -c $dir)
24408                 [ $stripe_count -eq 0 ] ||
24409                         error "expect 1 get $stripe_count for $dir"
24410         done
24411 }
24412 run_test 300g "check default striped directory for normal directory"
24413
24414 test_300h() {
24415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24417                 skip "Need MDS version at least 2.7.55"
24418
24419         local dir
24420         local stripe_count
24421
24422         mkdir $DIR/$tdir
24423         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24424                 error "set striped dir error"
24425
24426         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24427         test_300_check_default_striped_dir striped_dir 1 0
24428         test_300_check_default_striped_dir striped_dir -1 1
24429         test_300_check_default_striped_dir striped_dir 2 -1
24430
24431         #delete default stripe information
24432         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24433                 error "set default stripe on striped dir error"
24434
24435         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24436         for dir in $(find $DIR/$tdir/striped_dir/*); do
24437                 stripe_count=$($LFS getdirstripe -c $dir)
24438                 [ $stripe_count -eq 0 ] ||
24439                         error "expect 1 get $stripe_count for $dir"
24440         done
24441 }
24442 run_test 300h "check default striped directory for striped directory"
24443
24444 test_300i() {
24445         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24446         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24447         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24448                 skip "Need MDS version at least 2.7.55"
24449
24450         local stripe_count
24451         local file
24452
24453         mkdir $DIR/$tdir
24454
24455         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24456                 error "set striped dir error"
24457
24458         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24459                 error "create files under striped dir failed"
24460
24461         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24462                 error "set striped hashdir error"
24463
24464         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24465                 error "create dir0 under hash dir failed"
24466         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24467                 error "create dir1 under hash dir failed"
24468         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24469                 error "create dir2 under hash dir failed"
24470
24471         # unfortunately, we need to umount to clear dir layout cache for now
24472         # once we fully implement dir layout, we can drop this
24473         umount_client $MOUNT || error "umount failed"
24474         mount_client $MOUNT || error "mount failed"
24475
24476         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24477         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24478         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24479
24480         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24481                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24482                         error "create crush2 dir $tdir/hashdir/d3 failed"
24483                 $LFS find -H crush2 $DIR/$tdir/hashdir
24484                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24485                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24486
24487                 # mkdir with an invalid hash type (hash=fail_val) from client
24488                 # should be replaced on MDS with a valid (default) hash type
24489                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24490                 $LCTL set_param fail_loc=0x1901 fail_val=99
24491                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24492
24493                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24494                 local expect=$(do_facet mds1 \
24495                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24496                 [[ $hash == $expect ]] ||
24497                         error "d99 hash '$hash' != expected hash '$expect'"
24498         fi
24499
24500         #set the stripe to be unknown hash type on read
24501         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24502         $LCTL set_param fail_loc=0x1901 fail_val=99
24503         for ((i = 0; i < 10; i++)); do
24504                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24505                         error "stat f-$i failed"
24506                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24507         done
24508
24509         touch $DIR/$tdir/striped_dir/f0 &&
24510                 error "create under striped dir with unknown hash should fail"
24511
24512         $LCTL set_param fail_loc=0
24513
24514         umount_client $MOUNT || error "umount failed"
24515         mount_client $MOUNT || error "mount failed"
24516
24517         return 0
24518 }
24519 run_test 300i "client handle unknown hash type striped directory"
24520
24521 test_300j() {
24522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24525                 skip "Need MDS version at least 2.7.55"
24526
24527         local stripe_count
24528         local file
24529
24530         mkdir $DIR/$tdir
24531
24532         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24533         $LCTL set_param fail_loc=0x1702
24534         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24535                 error "set striped dir error"
24536
24537         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24538                 error "create files under striped dir failed"
24539
24540         $LCTL set_param fail_loc=0
24541
24542         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24543
24544         return 0
24545 }
24546 run_test 300j "test large update record"
24547
24548 test_300k() {
24549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24551         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24552                 skip "Need MDS version at least 2.7.55"
24553
24554         # this test needs a huge transaction
24555         local kb
24556         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24557              osd*.$FSNAME-MDT0000.kbytestotal")
24558         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24559
24560         local stripe_count
24561         local file
24562
24563         mkdir $DIR/$tdir
24564
24565         #define OBD_FAIL_LARGE_STRIPE   0x1703
24566         $LCTL set_param fail_loc=0x1703
24567         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24568                 error "set striped dir error"
24569         $LCTL set_param fail_loc=0
24570
24571         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24572                 error "getstripeddir fails"
24573         rm -rf $DIR/$tdir/striped_dir ||
24574                 error "unlink striped dir fails"
24575
24576         return 0
24577 }
24578 run_test 300k "test large striped directory"
24579
24580 test_300l() {
24581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24583         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24584                 skip "Need MDS version at least 2.7.55"
24585
24586         local stripe_index
24587
24588         test_mkdir -p $DIR/$tdir/striped_dir
24589         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24590                         error "chown $RUNAS_ID failed"
24591         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24592                 error "set default striped dir failed"
24593
24594         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24595         $LCTL set_param fail_loc=0x80000158
24596         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24597
24598         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24599         [ $stripe_index -eq 1 ] ||
24600                 error "expect 1 get $stripe_index for $dir"
24601 }
24602 run_test 300l "non-root user to create dir under striped dir with stale layout"
24603
24604 test_300m() {
24605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24606         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24607         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24608                 skip "Need MDS version at least 2.7.55"
24609
24610         mkdir -p $DIR/$tdir/striped_dir
24611         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24612                 error "set default stripes dir error"
24613
24614         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24615
24616         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24617         [ $stripe_count -eq 0 ] ||
24618                         error "expect 0 get $stripe_count for a"
24619
24620         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24621                 error "set default stripes dir error"
24622
24623         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24624
24625         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24626         [ $stripe_count -eq 0 ] ||
24627                         error "expect 0 get $stripe_count for b"
24628
24629         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24630                 error "set default stripes dir error"
24631
24632         mkdir $DIR/$tdir/striped_dir/c &&
24633                 error "default stripe_index is invalid, mkdir c should fails"
24634
24635         rm -rf $DIR/$tdir || error "rmdir fails"
24636 }
24637 run_test 300m "setstriped directory on single MDT FS"
24638
24639 cleanup_300n() {
24640         local list=$(comma_list $(mdts_nodes))
24641
24642         trap 0
24643         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24644 }
24645
24646 test_300n() {
24647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24649         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24650                 skip "Need MDS version at least 2.7.55"
24651         remote_mds_nodsh && skip "remote MDS with nodsh"
24652
24653         local stripe_index
24654         local list=$(comma_list $(mdts_nodes))
24655
24656         trap cleanup_300n RETURN EXIT
24657         mkdir -p $DIR/$tdir
24658         chmod 777 $DIR/$tdir
24659         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24660                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24661                 error "create striped dir succeeds with gid=0"
24662
24663         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24664         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24665                 error "create striped dir fails with gid=-1"
24666
24667         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24668         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24669                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24670                 error "set default striped dir succeeds with gid=0"
24671
24672
24673         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24674         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24675                 error "set default striped dir fails with gid=-1"
24676
24677
24678         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24679         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24680                                         error "create test_dir fails"
24681         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24682                                         error "create test_dir1 fails"
24683         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24684                                         error "create test_dir2 fails"
24685         cleanup_300n
24686 }
24687 run_test 300n "non-root user to create dir under striped dir with default EA"
24688
24689 test_300o() {
24690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24692         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24693                 skip "Need MDS version at least 2.7.55"
24694
24695         local numfree1
24696         local numfree2
24697
24698         mkdir -p $DIR/$tdir
24699
24700         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24701         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24702         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24703                 skip "not enough free inodes $numfree1 $numfree2"
24704         fi
24705
24706         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24707         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24708         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24709                 skip "not enough free space $numfree1 $numfree2"
24710         fi
24711
24712         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24713                 error "setdirstripe fails"
24714
24715         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24716                 error "create dirs fails"
24717
24718         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24719         ls $DIR/$tdir/striped_dir > /dev/null ||
24720                 error "ls striped dir fails"
24721         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24722                 error "unlink big striped dir fails"
24723 }
24724 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24725
24726 test_300p() {
24727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24728         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24729         remote_mds_nodsh && skip "remote MDS with nodsh"
24730
24731         mkdir_on_mdt0 $DIR/$tdir
24732
24733         #define OBD_FAIL_OUT_ENOSPC     0x1704
24734         do_facet mds2 lctl set_param fail_loc=0x80001704
24735         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24736                  && error "create striped directory should fail"
24737
24738         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24739
24740         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24741         true
24742 }
24743 run_test 300p "create striped directory without space"
24744
24745 test_300q() {
24746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24748
24749         local fd=$(free_fd)
24750         local cmd="exec $fd<$tdir"
24751         cd $DIR
24752         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24753         eval $cmd
24754         cmd="exec $fd<&-"
24755         trap "eval $cmd" EXIT
24756         cd $tdir || error "cd $tdir fails"
24757         rmdir  ../$tdir || error "rmdir $tdir fails"
24758         mkdir local_dir && error "create dir succeeds"
24759         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24760         eval $cmd
24761         return 0
24762 }
24763 run_test 300q "create remote directory under orphan directory"
24764
24765 test_300r() {
24766         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24767                 skip "Need MDS version at least 2.7.55" && return
24768         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24769
24770         mkdir $DIR/$tdir
24771
24772         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24773                 error "set striped dir error"
24774
24775         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24776                 error "getstripeddir fails"
24777
24778         local stripe_count
24779         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24780                       awk '/lmv_stripe_count:/ { print $2 }')
24781
24782         [ $MDSCOUNT -ne $stripe_count ] &&
24783                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24784
24785         rm -rf $DIR/$tdir/striped_dir ||
24786                 error "unlink striped dir fails"
24787 }
24788 run_test 300r "test -1 striped directory"
24789
24790 test_300s_helper() {
24791         local count=$1
24792
24793         local stripe_dir=$DIR/$tdir/striped_dir.$count
24794
24795         $LFS mkdir -c $count $stripe_dir ||
24796                 error "lfs mkdir -c error"
24797
24798         $LFS getdirstripe $stripe_dir ||
24799                 error "lfs getdirstripe fails"
24800
24801         local stripe_count
24802         stripe_count=$($LFS getdirstripe $stripe_dir |
24803                       awk '/lmv_stripe_count:/ { print $2 }')
24804
24805         [ $count -ne $stripe_count ] &&
24806                 error_noexit "bad stripe count $stripe_count expected $count"
24807
24808         local dupe_stripes
24809         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24810                 awk '/0x/ {count[$1] += 1}; END {
24811                         for (idx in count) {
24812                                 if (count[idx]>1) {
24813                                         print "index " idx " count " count[idx]
24814                                 }
24815                         }
24816                 }')
24817
24818         if [[ -n "$dupe_stripes" ]] ; then
24819                 lfs getdirstripe $stripe_dir
24820                 error_noexit "Dupe MDT above: $dupe_stripes "
24821         fi
24822
24823         rm -rf $stripe_dir ||
24824                 error_noexit "unlink $stripe_dir fails"
24825 }
24826
24827 test_300s() {
24828         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24829                 skip "Need MDS version at least 2.7.55" && return
24830         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24831
24832         mkdir $DIR/$tdir
24833         for count in $(seq 2 $MDSCOUNT); do
24834                 test_300s_helper $count
24835         done
24836 }
24837 run_test 300s "test lfs mkdir -c without -i"
24838
24839 test_300t() {
24840         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24841                 skip "need MDS 2.14.55 or later"
24842         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24843
24844         local testdir="$DIR/$tdir/striped_dir"
24845         local dir1=$testdir/dir1
24846         local dir2=$testdir/dir2
24847
24848         mkdir -p $testdir
24849
24850         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24851                 error "failed to set default stripe count for $testdir"
24852
24853         mkdir $dir1
24854         local stripe_count=$($LFS getdirstripe -c $dir1)
24855
24856         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24857
24858         local max_count=$((MDSCOUNT - 1))
24859         local mdts=$(comma_list $(mdts_nodes))
24860
24861         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24862         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24863
24864         mkdir $dir2
24865         stripe_count=$($LFS getdirstripe -c $dir2)
24866
24867         (( $stripe_count == $max_count )) || error "wrong stripe count"
24868 }
24869 run_test 300t "test max_mdt_stripecount"
24870
24871 prepare_remote_file() {
24872         mkdir $DIR/$tdir/src_dir ||
24873                 error "create remote source failed"
24874
24875         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24876                  error "cp to remote source failed"
24877         touch $DIR/$tdir/src_dir/a
24878
24879         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24880                 error "create remote target dir failed"
24881
24882         touch $DIR/$tdir/tgt_dir/b
24883
24884         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24885                 error "rename dir cross MDT failed!"
24886
24887         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24888                 error "src_child still exists after rename"
24889
24890         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24891                 error "missing file(a) after rename"
24892
24893         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24894                 error "diff after rename"
24895 }
24896
24897 test_310a() {
24898         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24900
24901         local remote_file=$DIR/$tdir/tgt_dir/b
24902
24903         mkdir -p $DIR/$tdir
24904
24905         prepare_remote_file || error "prepare remote file failed"
24906
24907         #open-unlink file
24908         $OPENUNLINK $remote_file $remote_file ||
24909                 error "openunlink $remote_file failed"
24910         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24911 }
24912 run_test 310a "open unlink remote file"
24913
24914 test_310b() {
24915         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24917
24918         local remote_file=$DIR/$tdir/tgt_dir/b
24919
24920         mkdir -p $DIR/$tdir
24921
24922         prepare_remote_file || error "prepare remote file failed"
24923
24924         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24925         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24926         $CHECKSTAT -t file $remote_file || error "check file failed"
24927 }
24928 run_test 310b "unlink remote file with multiple links while open"
24929
24930 test_310c() {
24931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24932         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24933
24934         local remote_file=$DIR/$tdir/tgt_dir/b
24935
24936         mkdir -p $DIR/$tdir
24937
24938         prepare_remote_file || error "prepare remote file failed"
24939
24940         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24941         multiop_bg_pause $remote_file O_uc ||
24942                         error "mulitop failed for remote file"
24943         MULTIPID=$!
24944         $MULTIOP $DIR/$tfile Ouc
24945         kill -USR1 $MULTIPID
24946         wait $MULTIPID
24947 }
24948 run_test 310c "open-unlink remote file with multiple links"
24949
24950 #LU-4825
24951 test_311() {
24952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24953         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24954         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24955                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24956         remote_mds_nodsh && skip "remote MDS with nodsh"
24957
24958         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24959         local mdts=$(comma_list $(mdts_nodes))
24960
24961         mkdir -p $DIR/$tdir
24962         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24963         createmany -o $DIR/$tdir/$tfile. 1000
24964
24965         # statfs data is not real time, let's just calculate it
24966         old_iused=$((old_iused + 1000))
24967
24968         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24969                         osp.*OST0000*MDT0000.create_count")
24970         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24971                                 osp.*OST0000*MDT0000.max_create_count")
24972         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24973
24974         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24975         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24976         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24977
24978         unlinkmany $DIR/$tdir/$tfile. 1000
24979
24980         do_nodes $mdts "$LCTL set_param -n \
24981                         osp.*OST0000*.max_create_count=$max_count"
24982         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24983                 do_nodes $mdts "$LCTL set_param -n \
24984                                 osp.*OST0000*.create_count=$count"
24985         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24986                         grep "=0" && error "create_count is zero"
24987
24988         local new_iused
24989         for i in $(seq 120); do
24990                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24991                 # system may be too busy to destroy all objs in time, use
24992                 # a somewhat small value to not fail autotest
24993                 [ $((old_iused - new_iused)) -gt 400 ] && break
24994                 sleep 1
24995         done
24996
24997         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24998         [ $((old_iused - new_iused)) -gt 400 ] ||
24999                 error "objs not destroyed after unlink"
25000 }
25001 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25002
25003 zfs_get_objid()
25004 {
25005         local ost=$1
25006         local tf=$2
25007         local fid=($($LFS getstripe $tf | grep 0x))
25008         local seq=${fid[3]#0x}
25009         local objid=${fid[1]}
25010
25011         local vdevdir=$(dirname $(facet_vdevice $ost))
25012         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25013         local zfs_zapid=$(do_facet $ost $cmd |
25014                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25015                           awk '/Object/{getline; print $1}')
25016         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25017                           awk "/$objid = /"'{printf $3}')
25018
25019         echo $zfs_objid
25020 }
25021
25022 zfs_object_blksz() {
25023         local ost=$1
25024         local objid=$2
25025
25026         local vdevdir=$(dirname $(facet_vdevice $ost))
25027         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25028         local blksz=$(do_facet $ost $cmd $objid |
25029                       awk '/dblk/{getline; printf $4}')
25030
25031         case "${blksz: -1}" in
25032                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25033                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25034                 *) ;;
25035         esac
25036
25037         echo $blksz
25038 }
25039
25040 test_312() { # LU-4856
25041         remote_ost_nodsh && skip "remote OST with nodsh"
25042         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25043
25044         local max_blksz=$(do_facet ost1 \
25045                           $ZFS get -p recordsize $(facet_device ost1) |
25046                           awk '!/VALUE/{print $3}')
25047         local tf=$DIR/$tfile
25048
25049         $LFS setstripe -c1 $tf
25050         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25051
25052         # Get ZFS object id
25053         local zfs_objid=$(zfs_get_objid $facet $tf)
25054         # block size change by sequential overwrite
25055         local bs
25056
25057         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25058                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25059
25060                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25061                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25062         done
25063         rm -f $tf
25064
25065         $LFS setstripe -c1 $tf
25066         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25067
25068         # block size change by sequential append write
25069         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25070         zfs_objid=$(zfs_get_objid $facet $tf)
25071         local count
25072
25073         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25074                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25075                         oflag=sync conv=notrunc
25076
25077                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25078                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25079                         error "blksz error, actual $blksz, " \
25080                                 "expected: 2 * $count * $PAGE_SIZE"
25081         done
25082         rm -f $tf
25083
25084         # random write
25085         $LFS setstripe -c1 $tf
25086         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25087         zfs_objid=$(zfs_get_objid $facet $tf)
25088
25089         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25090         blksz=$(zfs_object_blksz $facet $zfs_objid)
25091         (( blksz == PAGE_SIZE )) ||
25092                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25093
25094         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25095         blksz=$(zfs_object_blksz $facet $zfs_objid)
25096         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25097
25098         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25099         blksz=$(zfs_object_blksz $facet $zfs_objid)
25100         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25101 }
25102 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25103
25104 test_313() {
25105         remote_ost_nodsh && skip "remote OST with nodsh"
25106
25107         local file=$DIR/$tfile
25108
25109         rm -f $file
25110         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25111
25112         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25113         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25114         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25115                 error "write should failed"
25116         do_facet ost1 "$LCTL set_param fail_loc=0"
25117         rm -f $file
25118 }
25119 run_test 313 "io should fail after last_rcvd update fail"
25120
25121 test_314() {
25122         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25123
25124         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25125         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25126         rm -f $DIR/$tfile
25127         wait_delete_completed
25128         do_facet ost1 "$LCTL set_param fail_loc=0"
25129 }
25130 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25131
25132 test_315() { # LU-618
25133         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25134
25135         local file=$DIR/$tfile
25136         rm -f $file
25137
25138         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25139                 error "multiop file write failed"
25140         $MULTIOP $file oO_RDONLY:r4063232_c &
25141         PID=$!
25142
25143         sleep 2
25144
25145         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25146         kill -USR1 $PID
25147
25148         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25149         rm -f $file
25150 }
25151 run_test 315 "read should be accounted"
25152
25153 test_316() {
25154         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25155         large_xattr_enabled || skip "ea_inode feature disabled"
25156
25157         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25158         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25159         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25160         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25161
25162         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25163 }
25164 run_test 316 "lfs migrate of file with large_xattr enabled"
25165
25166 test_317() {
25167         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25168                 skip "Need MDS version at least 2.11.53"
25169         if [ "$ost1_FSTYPE" == "zfs" ]; then
25170                 skip "LU-10370: no implementation for ZFS"
25171         fi
25172
25173         local trunc_sz
25174         local grant_blk_size
25175
25176         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25177                         awk '/grant_block_size:/ { print $2; exit; }')
25178         #
25179         # Create File of size 5M. Truncate it to below size's and verify
25180         # blocks count.
25181         #
25182         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25183                 error "Create file $DIR/$tfile failed"
25184         stack_trap "rm -f $DIR/$tfile" EXIT
25185
25186         for trunc_sz in 2097152 4097 4000 509 0; do
25187                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25188                         error "truncate $tfile to $trunc_sz failed"
25189                 local sz=$(stat --format=%s $DIR/$tfile)
25190                 local blk=$(stat --format=%b $DIR/$tfile)
25191                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25192                                      grant_blk_size) * 8))
25193
25194                 if [[ $blk -ne $trunc_blk ]]; then
25195                         $(which stat) $DIR/$tfile
25196                         error "Expected Block $trunc_blk got $blk for $tfile"
25197                 fi
25198
25199                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25200                         error "Expected Size $trunc_sz got $sz for $tfile"
25201         done
25202
25203         #
25204         # sparse file test
25205         # Create file with a hole and write actual 65536 bytes which aligned
25206         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25207         #
25208         local bs=65536
25209         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25210                 error "Create file : $DIR/$tfile"
25211
25212         #
25213         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25214         # blocks. The block count must drop to 8.
25215         #
25216         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25217                 ((bs - grant_blk_size) + 1)))
25218         $TRUNCATE $DIR/$tfile $trunc_sz ||
25219                 error "truncate $tfile to $trunc_sz failed"
25220
25221         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25222         sz=$(stat --format=%s $DIR/$tfile)
25223         blk=$(stat --format=%b $DIR/$tfile)
25224
25225         if [[ $blk -ne $trunc_bsz ]]; then
25226                 $(which stat) $DIR/$tfile
25227                 error "Expected Block $trunc_bsz got $blk for $tfile"
25228         fi
25229
25230         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25231                 error "Expected Size $trunc_sz got $sz for $tfile"
25232 }
25233 run_test 317 "Verify blocks get correctly update after truncate"
25234
25235 test_318() {
25236         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25237         local old_max_active=$($LCTL get_param -n \
25238                             ${llite_name}.max_read_ahead_async_active \
25239                             2>/dev/null)
25240
25241         $LCTL set_param llite.*.max_read_ahead_async_active=256
25242         local max_active=$($LCTL get_param -n \
25243                            ${llite_name}.max_read_ahead_async_active \
25244                            2>/dev/null)
25245         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25246
25247         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25248                 error "set max_read_ahead_async_active should succeed"
25249
25250         $LCTL set_param llite.*.max_read_ahead_async_active=512
25251         max_active=$($LCTL get_param -n \
25252                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25253         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25254
25255         # restore @max_active
25256         [ $old_max_active -ne 0 ] && $LCTL set_param \
25257                 llite.*.max_read_ahead_async_active=$old_max_active
25258
25259         local old_threshold=$($LCTL get_param -n \
25260                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25261         local max_per_file_mb=$($LCTL get_param -n \
25262                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25263
25264         local invalid=$(($max_per_file_mb + 1))
25265         $LCTL set_param \
25266                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25267                         && error "set $invalid should fail"
25268
25269         local valid=$(($invalid - 1))
25270         $LCTL set_param \
25271                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25272                         error "set $valid should succeed"
25273         local threshold=$($LCTL get_param -n \
25274                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25275         [ $threshold -eq $valid ] || error \
25276                 "expect threshold $valid got $threshold"
25277         $LCTL set_param \
25278                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25279 }
25280 run_test 318 "Verify async readahead tunables"
25281
25282 test_319() {
25283         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25284
25285         local before=$(date +%s)
25286         local evict
25287         local mdir=$DIR/$tdir
25288         local file=$mdir/xxx
25289
25290         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25291         touch $file
25292
25293 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25294         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25295         $LFS migrate -m1 $mdir &
25296
25297         sleep 1
25298         dd if=$file of=/dev/null
25299         wait
25300         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25301           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25302
25303         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25304 }
25305 run_test 319 "lost lease lock on migrate error"
25306
25307 test_398a() { # LU-4198
25308         local ost1_imp=$(get_osc_import_name client ost1)
25309         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25310                          cut -d'.' -f2)
25311
25312         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25313         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25314
25315         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25316         # request a new lock on client
25317         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25318
25319         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25320         #local lock_count=$($LCTL get_param -n \
25321         #                  ldlm.namespaces.$imp_name.lru_size)
25322         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25323
25324         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25325
25326         # no lock cached, should use lockless DIO and not enqueue new lock
25327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25328                 conv=notrunc ||
25329                 error "dio write failed"
25330         lock_count=$($LCTL get_param -n \
25331                      ldlm.namespaces.$imp_name.lru_size)
25332         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25333
25334         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25335
25336         # no lock cached, should use locked DIO append
25337         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25338                 conv=notrunc || error "DIO append failed"
25339         lock_count=$($LCTL get_param -n \
25340                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25341         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25342 }
25343 run_test 398a "direct IO should cancel lock otherwise lockless"
25344
25345 test_398b() { # LU-4198
25346         local before=$(date +%s)
25347         local njobs=4
25348         local size=48
25349
25350         which fio || skip_env "no fio installed"
25351         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25352         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25353
25354         # Single page, multiple pages, stripe size, 4*stripe size
25355         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25356                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25357                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25358                         --numjobs=$njobs --fallocate=none \
25359                         --iodepth=16 --allow_file_create=0 \
25360                         --size=$((size/njobs))M \
25361                         --filename=$DIR/$tfile &
25362                 bg_pid=$!
25363
25364                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25365                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25366                         --numjobs=$njobs --fallocate=none \
25367                         --iodepth=16 --allow_file_create=0 \
25368                         --size=$((size/njobs))M \
25369                         --filename=$DIR/$tfile || true
25370                 wait $bg_pid
25371         done
25372
25373         evict=$(do_facet client $LCTL get_param \
25374                 osc.$FSNAME-OST*-osc-*/state |
25375             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25376
25377         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25378                 (do_facet client $LCTL get_param \
25379                         osc.$FSNAME-OST*-osc-*/state;
25380                     error "eviction happened: $evict before:$before")
25381
25382         rm -f $DIR/$tfile
25383 }
25384 run_test 398b "DIO and buffer IO race"
25385
25386 test_398c() { # LU-4198
25387         local ost1_imp=$(get_osc_import_name client ost1)
25388         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25389                          cut -d'.' -f2)
25390
25391         which fio || skip_env "no fio installed"
25392
25393         saved_debug=$($LCTL get_param -n debug)
25394         $LCTL set_param debug=0
25395
25396         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25397         ((size /= 1024)) # by megabytes
25398         ((size /= 2)) # write half of the OST at most
25399         [ $size -gt 40 ] && size=40 #reduce test time anyway
25400
25401         $LFS setstripe -c 1 $DIR/$tfile
25402
25403         # it seems like ldiskfs reserves more space than necessary if the
25404         # writing blocks are not mapped, so it extends the file firstly
25405         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25406         cancel_lru_locks osc
25407
25408         # clear and verify rpc_stats later
25409         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25410
25411         local njobs=4
25412         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25413         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25414                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25415                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25416                 --filename=$DIR/$tfile
25417         [ $? -eq 0 ] || error "fio write error"
25418
25419         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25420                 error "Locks were requested while doing AIO"
25421
25422         # get the percentage of 1-page I/O
25423         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25424                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25425                 awk '{print $7}')
25426         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25427
25428         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25429         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25430                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25431                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25432                 --filename=$DIR/$tfile
25433         [ $? -eq 0 ] || error "fio mixed read write error"
25434
25435         echo "AIO with large block size ${size}M"
25436         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25437                 --numjobs=1 --fallocate=none --ioengine=libaio \
25438                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25439                 --filename=$DIR/$tfile
25440         [ $? -eq 0 ] || error "fio large block size failed"
25441
25442         rm -f $DIR/$tfile
25443         $LCTL set_param debug="$saved_debug"
25444 }
25445 run_test 398c "run fio to test AIO"
25446
25447 test_398d() { #  LU-13846
25448         which aiocp || skip_env "no aiocp installed"
25449         local aio_file=$DIR/$tfile.aio
25450
25451         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25452
25453         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25454         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25455         stack_trap "rm -f $DIR/$tfile $aio_file"
25456
25457         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25458
25459         # make sure we don't crash and fail properly
25460         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25461                 error "aio not aligned with PAGE SIZE should fail"
25462
25463         rm -f $DIR/$tfile $aio_file
25464 }
25465 run_test 398d "run aiocp to verify block size > stripe size"
25466
25467 test_398e() {
25468         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25469         touch $DIR/$tfile.new
25470         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25471 }
25472 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25473
25474 test_398f() { #  LU-14687
25475         which aiocp || skip_env "no aiocp installed"
25476         local aio_file=$DIR/$tfile.aio
25477
25478         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25479
25480         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25481         stack_trap "rm -f $DIR/$tfile $aio_file"
25482
25483         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25484         $LCTL set_param fail_loc=0x1418
25485         # make sure we don't crash and fail properly
25486         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25487                 error "aio with page allocation failure succeeded"
25488         $LCTL set_param fail_loc=0
25489         diff $DIR/$tfile $aio_file
25490         [[ $? != 0 ]] || error "no diff after failed aiocp"
25491 }
25492 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25493
25494 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25495 # stripe and i/o size must be > stripe size
25496 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25497 # single RPC in flight.  This test shows async DIO submission is working by
25498 # showing multiple RPCs in flight.
25499 test_398g() { #  LU-13798
25500         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25501
25502         # We need to do some i/o first to acquire enough grant to put our RPCs
25503         # in flight; otherwise a new connection may not have enough grant
25504         # available
25505         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25506                 error "parallel dio failed"
25507         stack_trap "rm -f $DIR/$tfile"
25508
25509         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25510         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25511         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25512         stack_trap "$LCTL set_param -n $pages_per_rpc"
25513
25514         # Recreate file so it's empty
25515         rm -f $DIR/$tfile
25516         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25517         #Pause rpc completion to guarantee we see multiple rpcs in flight
25518         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25519         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25520         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25521
25522         # Clear rpc stats
25523         $LCTL set_param osc.*.rpc_stats=c
25524
25525         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25526                 error "parallel dio failed"
25527         stack_trap "rm -f $DIR/$tfile"
25528
25529         $LCTL get_param osc.*-OST0000-*.rpc_stats
25530         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25531                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25532                 grep "8:" | awk '{print $8}')
25533         # We look at the "8 rpcs in flight" field, and verify A) it is present
25534         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25535         # as expected for an 8M DIO to a file with 1M stripes.
25536         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25537
25538         # Verify turning off parallel dio works as expected
25539         # Clear rpc stats
25540         $LCTL set_param osc.*.rpc_stats=c
25541         $LCTL set_param llite.*.parallel_dio=0
25542         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25543
25544         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25545                 error "dio with parallel dio disabled failed"
25546
25547         # Ideally, we would see only one RPC in flight here, but there is an
25548         # unavoidable race between i/o completion and RPC in flight counting,
25549         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25550         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25551         # So instead we just verify it's always < 8.
25552         $LCTL get_param osc.*-OST0000-*.rpc_stats
25553         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25554                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25555                 grep '^$' -B1 | grep . | awk '{print $1}')
25556         [ $ret != "8:" ] ||
25557                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25558 }
25559 run_test 398g "verify parallel dio async RPC submission"
25560
25561 test_398h() { #  LU-13798
25562         local dio_file=$DIR/$tfile.dio
25563
25564         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25565
25566         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25567         stack_trap "rm -f $DIR/$tfile $dio_file"
25568
25569         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25570                 error "parallel dio failed"
25571         diff $DIR/$tfile $dio_file
25572         [[ $? == 0 ]] || error "file diff after aiocp"
25573 }
25574 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25575
25576 test_398i() { #  LU-13798
25577         local dio_file=$DIR/$tfile.dio
25578
25579         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25580
25581         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25582         stack_trap "rm -f $DIR/$tfile $dio_file"
25583
25584         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25585         $LCTL set_param fail_loc=0x1418
25586         # make sure we don't crash and fail properly
25587         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25588                 error "parallel dio page allocation failure succeeded"
25589         diff $DIR/$tfile $dio_file
25590         [[ $? != 0 ]] || error "no diff after failed aiocp"
25591 }
25592 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25593
25594 test_398j() { #  LU-13798
25595         # Stripe size > RPC size but less than i/o size tests split across
25596         # stripes and RPCs for individual i/o op
25597         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25598
25599         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25600         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25601         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25602         stack_trap "$LCTL set_param -n $pages_per_rpc"
25603
25604         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25605                 error "parallel dio write failed"
25606         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25607
25608         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25609                 error "parallel dio read failed"
25610         diff $DIR/$tfile $DIR/$tfile.2
25611         [[ $? == 0 ]] || error "file diff after parallel dio read"
25612 }
25613 run_test 398j "test parallel dio where stripe size > rpc_size"
25614
25615 test_398k() { #  LU-13798
25616         wait_delete_completed
25617         wait_mds_ost_sync
25618
25619         # 4 stripe file; we will cause out of space on OST0
25620         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25621
25622         # Fill OST0 (if it's not too large)
25623         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25624                    head -n1)
25625         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25626                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25627         fi
25628         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25629         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25630                 error "dd should fill OST0"
25631         stack_trap "rm -f $DIR/$tfile.1"
25632
25633         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25634         err=$?
25635
25636         ls -la $DIR/$tfile
25637         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25638                 error "file is not 0 bytes in size"
25639
25640         # dd above should not succeed, but don't error until here so we can
25641         # get debug info above
25642         [[ $err != 0 ]] ||
25643                 error "parallel dio write with enospc succeeded"
25644         stack_trap "rm -f $DIR/$tfile"
25645 }
25646 run_test 398k "test enospc on first stripe"
25647
25648 test_398l() { #  LU-13798
25649         wait_delete_completed
25650         wait_mds_ost_sync
25651
25652         # 4 stripe file; we will cause out of space on OST0
25653         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25654         # happens on the second i/o chunk we issue
25655         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25656
25657         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25658         stack_trap "rm -f $DIR/$tfile"
25659
25660         # Fill OST0 (if it's not too large)
25661         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25662                    head -n1)
25663         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25664                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25665         fi
25666         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25667         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25668                 error "dd should fill OST0"
25669         stack_trap "rm -f $DIR/$tfile.1"
25670
25671         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25672         err=$?
25673         stack_trap "rm -f $DIR/$tfile.2"
25674
25675         # Check that short write completed as expected
25676         ls -la $DIR/$tfile.2
25677         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25678                 error "file is not 1M in size"
25679
25680         # dd above should not succeed, but don't error until here so we can
25681         # get debug info above
25682         [[ $err != 0 ]] ||
25683                 error "parallel dio write with enospc succeeded"
25684
25685         # Truncate source file to same length as output file and diff them
25686         $TRUNCATE $DIR/$tfile 1048576
25687         diff $DIR/$tfile $DIR/$tfile.2
25688         [[ $? == 0 ]] || error "data incorrect after short write"
25689 }
25690 run_test 398l "test enospc on intermediate stripe/RPC"
25691
25692 test_398m() { #  LU-13798
25693         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25694
25695         # Set up failure on OST0, the first stripe:
25696         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25697         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25698         # OST0 is on ost1, OST1 is on ost2.
25699         # So this fail_val specifies OST0
25700         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25701         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25702
25703         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25704                 error "parallel dio write with failure on first stripe succeeded"
25705         stack_trap "rm -f $DIR/$tfile"
25706         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25707
25708         # Place data in file for read
25709         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25710                 error "parallel dio write failed"
25711
25712         # Fail read on OST0, first stripe
25713         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25714         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25715         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25716                 error "parallel dio read with error on first stripe succeeded"
25717         rm -f $DIR/$tfile.2
25718         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25719
25720         # Switch to testing on OST1, second stripe
25721         # Clear file contents, maintain striping
25722         echo > $DIR/$tfile
25723         # Set up failure on OST1, second stripe:
25724         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25725         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25726
25727         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25728                 error "parallel dio write with failure on second stripe succeeded"
25729         stack_trap "rm -f $DIR/$tfile"
25730         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25731
25732         # Place data in file for read
25733         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25734                 error "parallel dio write failed"
25735
25736         # Fail read on OST1, second stripe
25737         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25738         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25739         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25740                 error "parallel dio read with error on second stripe succeeded"
25741         rm -f $DIR/$tfile.2
25742         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25743 }
25744 run_test 398m "test RPC failures with parallel dio"
25745
25746 # Parallel submission of DIO should not cause problems for append, but it's
25747 # important to verify.
25748 test_398n() { #  LU-13798
25749         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25750
25751         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25752                 error "dd to create source file failed"
25753         stack_trap "rm -f $DIR/$tfile"
25754
25755         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25756                 error "parallel dio write with failure on second stripe succeeded"
25757         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25758         diff $DIR/$tfile $DIR/$tfile.1
25759         [[ $? == 0 ]] || error "data incorrect after append"
25760
25761 }
25762 run_test 398n "test append with parallel DIO"
25763
25764 test_398o() {
25765         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25766 }
25767 run_test 398o "right kms with DIO"
25768
25769 test_fake_rw() {
25770         local read_write=$1
25771         if [ "$read_write" = "write" ]; then
25772                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25773         elif [ "$read_write" = "read" ]; then
25774                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25775         else
25776                 error "argument error"
25777         fi
25778
25779         # turn off debug for performance testing
25780         local saved_debug=$($LCTL get_param -n debug)
25781         $LCTL set_param debug=0
25782
25783         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25784
25785         # get ost1 size - $FSNAME-OST0000
25786         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25787         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25788         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25789
25790         if [ "$read_write" = "read" ]; then
25791                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25792         fi
25793
25794         local start_time=$(date +%s.%N)
25795         $dd_cmd bs=1M count=$blocks oflag=sync ||
25796                 error "real dd $read_write error"
25797         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25798
25799         if [ "$read_write" = "write" ]; then
25800                 rm -f $DIR/$tfile
25801         fi
25802
25803         # define OBD_FAIL_OST_FAKE_RW           0x238
25804         do_facet ost1 $LCTL set_param fail_loc=0x238
25805
25806         local start_time=$(date +%s.%N)
25807         $dd_cmd bs=1M count=$blocks oflag=sync ||
25808                 error "fake dd $read_write error"
25809         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25810
25811         if [ "$read_write" = "write" ]; then
25812                 # verify file size
25813                 cancel_lru_locks osc
25814                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25815                         error "$tfile size not $blocks MB"
25816         fi
25817         do_facet ost1 $LCTL set_param fail_loc=0
25818
25819         echo "fake $read_write $duration_fake vs. normal $read_write" \
25820                 "$duration in seconds"
25821         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25822                 error_not_in_vm "fake write is slower"
25823
25824         $LCTL set_param -n debug="$saved_debug"
25825         rm -f $DIR/$tfile
25826 }
25827 test_399a() { # LU-7655 for OST fake write
25828         remote_ost_nodsh && skip "remote OST with nodsh"
25829
25830         test_fake_rw write
25831 }
25832 run_test 399a "fake write should not be slower than normal write"
25833
25834 test_399b() { # LU-8726 for OST fake read
25835         remote_ost_nodsh && skip "remote OST with nodsh"
25836         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25837                 skip_env "ldiskfs only test"
25838         fi
25839
25840         test_fake_rw read
25841 }
25842 run_test 399b "fake read should not be slower than normal read"
25843
25844 test_400a() { # LU-1606, was conf-sanity test_74
25845         if ! which $CC > /dev/null 2>&1; then
25846                 skip_env "$CC is not installed"
25847         fi
25848
25849         local extra_flags=''
25850         local out=$TMP/$tfile
25851         local prefix=/usr/include/lustre
25852         local prog
25853
25854         # Oleg removes .c files in his test rig so test if any c files exist
25855         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25856                 skip_env "Needed .c test files are missing"
25857
25858         if ! [[ -d $prefix ]]; then
25859                 # Assume we're running in tree and fixup the include path.
25860                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25861                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25862                 extra_flags+=" -L$LUSTRE/utils/.libs"
25863         fi
25864
25865         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25866                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25867                         error "client api broken"
25868         done
25869         rm -f $out
25870 }
25871 run_test 400a "Lustre client api program can compile and link"
25872
25873 test_400b() { # LU-1606, LU-5011
25874         local header
25875         local out=$TMP/$tfile
25876         local prefix=/usr/include/linux/lustre
25877
25878         # We use a hard coded prefix so that this test will not fail
25879         # when run in tree. There are headers in lustre/include/lustre/
25880         # that are not packaged (like lustre_idl.h) and have more
25881         # complicated include dependencies (like config.h and lnet/types.h).
25882         # Since this test about correct packaging we just skip them when
25883         # they don't exist (see below) rather than try to fixup cppflags.
25884
25885         if ! which $CC > /dev/null 2>&1; then
25886                 skip_env "$CC is not installed"
25887         fi
25888
25889         for header in $prefix/*.h; do
25890                 if ! [[ -f "$header" ]]; then
25891                         continue
25892                 fi
25893
25894                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25895                         continue # lustre_ioctl.h is internal header
25896                 fi
25897
25898                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25899                         error "cannot compile '$header'"
25900         done
25901         rm -f $out
25902 }
25903 run_test 400b "packaged headers can be compiled"
25904
25905 test_401a() { #LU-7437
25906         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25907         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25908
25909         #count the number of parameters by "list_param -R"
25910         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25911         #count the number of parameters by listing proc files
25912         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25913         echo "proc_dirs='$proc_dirs'"
25914         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25915         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25916                       sort -u | wc -l)
25917
25918         [ $params -eq $procs ] ||
25919                 error "found $params parameters vs. $procs proc files"
25920
25921         # test the list_param -D option only returns directories
25922         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25923         #count the number of parameters by listing proc directories
25924         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25925                 sort -u | wc -l)
25926
25927         [ $params -eq $procs ] ||
25928                 error "found $params parameters vs. $procs proc files"
25929 }
25930 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25931
25932 test_401b() {
25933         # jobid_var may not allow arbitrary values, so use jobid_name
25934         # if available
25935         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25936                 local testname=jobid_name tmp='testing%p'
25937         else
25938                 local testname=jobid_var tmp=testing
25939         fi
25940
25941         local save=$($LCTL get_param -n $testname)
25942
25943         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25944                 error "no error returned when setting bad parameters"
25945
25946         local jobid_new=$($LCTL get_param -n foe $testname baz)
25947         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25948
25949         $LCTL set_param -n fog=bam $testname=$save bat=fog
25950         local jobid_old=$($LCTL get_param -n foe $testname bag)
25951         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25952 }
25953 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25954
25955 test_401c() {
25956         # jobid_var may not allow arbitrary values, so use jobid_name
25957         # if available
25958         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25959                 local testname=jobid_name
25960         else
25961                 local testname=jobid_var
25962         fi
25963
25964         local jobid_var_old=$($LCTL get_param -n $testname)
25965         local jobid_var_new
25966
25967         $LCTL set_param $testname= &&
25968                 error "no error returned for 'set_param a='"
25969
25970         jobid_var_new=$($LCTL get_param -n $testname)
25971         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25972                 error "$testname was changed by setting without value"
25973
25974         $LCTL set_param $testname &&
25975                 error "no error returned for 'set_param a'"
25976
25977         jobid_var_new=$($LCTL get_param -n $testname)
25978         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25979                 error "$testname was changed by setting without value"
25980 }
25981 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25982
25983 test_401d() {
25984         # jobid_var may not allow arbitrary values, so use jobid_name
25985         # if available
25986         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25987                 local testname=jobid_name new_value='foo=bar%p'
25988         else
25989                 local testname=jobid_var new_valuie=foo=bar
25990         fi
25991
25992         local jobid_var_old=$($LCTL get_param -n $testname)
25993         local jobid_var_new
25994
25995         $LCTL set_param $testname=$new_value ||
25996                 error "'set_param a=b' did not accept a value containing '='"
25997
25998         jobid_var_new=$($LCTL get_param -n $testname)
25999         [[ "$jobid_var_new" == "$new_value" ]] ||
26000                 error "'set_param a=b' failed on a value containing '='"
26001
26002         # Reset the $testname to test the other format
26003         $LCTL set_param $testname=$jobid_var_old
26004         jobid_var_new=$($LCTL get_param -n $testname)
26005         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26006                 error "failed to reset $testname"
26007
26008         $LCTL set_param $testname $new_value ||
26009                 error "'set_param a b' did not accept a value containing '='"
26010
26011         jobid_var_new=$($LCTL get_param -n $testname)
26012         [[ "$jobid_var_new" == "$new_value" ]] ||
26013                 error "'set_param a b' failed on a value containing '='"
26014
26015         $LCTL set_param $testname $jobid_var_old
26016         jobid_var_new=$($LCTL get_param -n $testname)
26017         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26018                 error "failed to reset $testname"
26019 }
26020 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26021
26022 test_401e() { # LU-14779
26023         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26024                 error "lctl list_param MGC* failed"
26025         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26026         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26027                 error "lctl get_param lru_size failed"
26028 }
26029 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26030
26031 test_402() {
26032         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26033         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26034                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26035         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26036                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26037                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26038         remote_mds_nodsh && skip "remote MDS with nodsh"
26039
26040         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26041 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26042         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26043         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26044                 echo "Touch failed - OK"
26045 }
26046 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26047
26048 test_403() {
26049         local file1=$DIR/$tfile.1
26050         local file2=$DIR/$tfile.2
26051         local tfile=$TMP/$tfile
26052
26053         rm -f $file1 $file2 $tfile
26054
26055         touch $file1
26056         ln $file1 $file2
26057
26058         # 30 sec OBD_TIMEOUT in ll_getattr()
26059         # right before populating st_nlink
26060         $LCTL set_param fail_loc=0x80001409
26061         stat -c %h $file1 > $tfile &
26062
26063         # create an alias, drop all locks and reclaim the dentry
26064         < $file2
26065         cancel_lru_locks mdc
26066         cancel_lru_locks osc
26067         sysctl -w vm.drop_caches=2
26068
26069         wait
26070
26071         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26072
26073         rm -f $tfile $file1 $file2
26074 }
26075 run_test 403 "i_nlink should not drop to zero due to aliasing"
26076
26077 test_404() { # LU-6601
26078         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26079                 skip "Need server version newer than 2.8.52"
26080         remote_mds_nodsh && skip "remote MDS with nodsh"
26081
26082         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26083                 awk '/osp .*-osc-MDT/ { print $4}')
26084
26085         local osp
26086         for osp in $mosps; do
26087                 echo "Deactivate: " $osp
26088                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26089                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26090                         awk -vp=$osp '$4 == p { print $2 }')
26091                 [ $stat = IN ] || {
26092                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26093                         error "deactivate error"
26094                 }
26095                 echo "Activate: " $osp
26096                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26097                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26098                         awk -vp=$osp '$4 == p { print $2 }')
26099                 [ $stat = UP ] || {
26100                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26101                         error "activate error"
26102                 }
26103         done
26104 }
26105 run_test 404 "validate manual {de}activated works properly for OSPs"
26106
26107 test_405() {
26108         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26109         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26110                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26111                         skip "Layout swap lock is not supported"
26112
26113         check_swap_layouts_support
26114         check_swap_layout_no_dom $DIR
26115
26116         test_mkdir $DIR/$tdir
26117         swap_lock_test -d $DIR/$tdir ||
26118                 error "One layout swap locked test failed"
26119 }
26120 run_test 405 "Various layout swap lock tests"
26121
26122 test_406() {
26123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26124         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26125         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26127         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26128                 skip "Need MDS version at least 2.8.50"
26129
26130         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26131         local test_pool=$TESTNAME
26132
26133         pool_add $test_pool || error "pool_add failed"
26134         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26135                 error "pool_add_targets failed"
26136
26137         save_layout_restore_at_exit $MOUNT
26138
26139         # parent set default stripe count only, child will stripe from both
26140         # parent and fs default
26141         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26142                 error "setstripe $MOUNT failed"
26143         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26144         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26145         for i in $(seq 10); do
26146                 local f=$DIR/$tdir/$tfile.$i
26147                 touch $f || error "touch failed"
26148                 local count=$($LFS getstripe -c $f)
26149                 [ $count -eq $OSTCOUNT ] ||
26150                         error "$f stripe count $count != $OSTCOUNT"
26151                 local offset=$($LFS getstripe -i $f)
26152                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26153                 local size=$($LFS getstripe -S $f)
26154                 [ $size -eq $((def_stripe_size * 2)) ] ||
26155                         error "$f stripe size $size != $((def_stripe_size * 2))"
26156                 local pool=$($LFS getstripe -p $f)
26157                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26158         done
26159
26160         # change fs default striping, delete parent default striping, now child
26161         # will stripe from new fs default striping only
26162         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26163                 error "change $MOUNT default stripe failed"
26164         $LFS setstripe -c 0 $DIR/$tdir ||
26165                 error "delete $tdir default stripe failed"
26166         for i in $(seq 11 20); do
26167                 local f=$DIR/$tdir/$tfile.$i
26168                 touch $f || error "touch $f failed"
26169                 local count=$($LFS getstripe -c $f)
26170                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26171                 local offset=$($LFS getstripe -i $f)
26172                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26173                 local size=$($LFS getstripe -S $f)
26174                 [ $size -eq $def_stripe_size ] ||
26175                         error "$f stripe size $size != $def_stripe_size"
26176                 local pool=$($LFS getstripe -p $f)
26177                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26178         done
26179
26180         unlinkmany $DIR/$tdir/$tfile. 1 20
26181
26182         local f=$DIR/$tdir/$tfile
26183         pool_remove_all_targets $test_pool $f
26184         pool_remove $test_pool $f
26185 }
26186 run_test 406 "DNE support fs default striping"
26187
26188 test_407() {
26189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26190         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26191                 skip "Need MDS version at least 2.8.55"
26192         remote_mds_nodsh && skip "remote MDS with nodsh"
26193
26194         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26195                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26196         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26197                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26198         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26199
26200         #define OBD_FAIL_DT_TXN_STOP    0x2019
26201         for idx in $(seq $MDSCOUNT); do
26202                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26203         done
26204         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26205         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26206                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26207         true
26208 }
26209 run_test 407 "transaction fail should cause operation fail"
26210
26211 test_408() {
26212         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26213
26214         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26215         lctl set_param fail_loc=0x8000040a
26216         # let ll_prepare_partial_page() fail
26217         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26218
26219         rm -f $DIR/$tfile
26220
26221         # create at least 100 unused inodes so that
26222         # shrink_icache_memory(0) should not return 0
26223         touch $DIR/$tfile-{0..100}
26224         rm -f $DIR/$tfile-{0..100}
26225         sync
26226
26227         echo 2 > /proc/sys/vm/drop_caches
26228 }
26229 run_test 408 "drop_caches should not hang due to page leaks"
26230
26231 test_409()
26232 {
26233         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26234
26235         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26236         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26237         touch $DIR/$tdir/guard || error "(2) Fail to create"
26238
26239         local PREFIX=$(str_repeat 'A' 128)
26240         echo "Create 1K hard links start at $(date)"
26241         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26242                 error "(3) Fail to hard link"
26243
26244         echo "Links count should be right although linkEA overflow"
26245         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26246         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26247         [ $linkcount -eq 1001 ] ||
26248                 error "(5) Unexpected hard links count: $linkcount"
26249
26250         echo "List all links start at $(date)"
26251         ls -l $DIR/$tdir/foo > /dev/null ||
26252                 error "(6) Fail to list $DIR/$tdir/foo"
26253
26254         echo "Unlink hard links start at $(date)"
26255         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26256                 error "(7) Fail to unlink"
26257         echo "Unlink hard links finished at $(date)"
26258 }
26259 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26260
26261 test_410()
26262 {
26263         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26264                 skip "Need client version at least 2.9.59"
26265         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26266                 skip "Need MODULES build"
26267
26268         # Create a file, and stat it from the kernel
26269         local testfile=$DIR/$tfile
26270         touch $testfile
26271
26272         local run_id=$RANDOM
26273         local my_ino=$(stat --format "%i" $testfile)
26274
26275         # Try to insert the module. This will always fail as the
26276         # module is designed to not be inserted.
26277         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26278             &> /dev/null
26279
26280         # Anything but success is a test failure
26281         dmesg | grep -q \
26282             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26283             error "no inode match"
26284 }
26285 run_test 410 "Test inode number returned from kernel thread"
26286
26287 cleanup_test411_cgroup() {
26288         trap 0
26289         rmdir "$1"
26290 }
26291
26292 test_411() {
26293         local cg_basedir=/sys/fs/cgroup/memory
26294         # LU-9966
26295         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26296                 skip "no setup for cgroup"
26297
26298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26299                 error "test file creation failed"
26300         cancel_lru_locks osc
26301
26302         # Create a very small memory cgroup to force a slab allocation error
26303         local cgdir=$cg_basedir/osc_slab_alloc
26304         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26305         trap "cleanup_test411_cgroup $cgdir" EXIT
26306         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26307         echo 1M > $cgdir/memory.limit_in_bytes
26308
26309         # Should not LBUG, just be killed by oom-killer
26310         # dd will return 0 even allocation failure in some environment.
26311         # So don't check return value
26312         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26313         cleanup_test411_cgroup $cgdir
26314
26315         return 0
26316 }
26317 run_test 411 "Slab allocation error with cgroup does not LBUG"
26318
26319 test_412() {
26320         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26321         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26322                 skip "Need server version at least 2.10.55"
26323
26324         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26325                 error "mkdir failed"
26326         $LFS getdirstripe $DIR/$tdir
26327         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26328         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26329                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26330         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26331         [ $stripe_count -eq 2 ] ||
26332                 error "expect 2 get $stripe_count"
26333
26334         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26335
26336         local index
26337         local index2
26338
26339         # subdirs should be on the same MDT as parent
26340         for i in $(seq 0 $((MDSCOUNT - 1))); do
26341                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26342                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26343                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26344                 (( index == i )) || error "mdt$i/sub on MDT$index"
26345         done
26346
26347         # stripe offset -1, ditto
26348         for i in {1..10}; do
26349                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26350                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26351                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26352                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26353                 (( index == index2 )) ||
26354                         error "qos$i on MDT$index, sub on MDT$index2"
26355         done
26356
26357         local testdir=$DIR/$tdir/inherit
26358
26359         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26360         # inherit 2 levels
26361         for i in 1 2; do
26362                 testdir=$testdir/s$i
26363                 mkdir $testdir || error "mkdir $testdir failed"
26364                 index=$($LFS getstripe -m $testdir)
26365                 (( index == 1 )) ||
26366                         error "$testdir on MDT$index"
26367         done
26368
26369         # not inherit any more
26370         testdir=$testdir/s3
26371         mkdir $testdir || error "mkdir $testdir failed"
26372         getfattr -d -m dmv $testdir | grep dmv &&
26373                 error "default LMV set on $testdir" || true
26374 }
26375 run_test 412 "mkdir on specific MDTs"
26376
26377 TEST413_COUNT=${TEST413_COUNT:-200}
26378
26379 #
26380 # set_maxage() is used by test_413 only.
26381 # This is a helper function to set maxage. Does not return any value.
26382 # Input: maxage to set
26383 #
26384 set_maxage() {
26385         local lmv_qos_maxage
26386         local lod_qos_maxage
26387         local new_maxage=$1
26388
26389         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26390         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26391         stack_trap "$LCTL set_param \
26392                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26393         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26394                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26395         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26396                 lod.*.mdt_qos_maxage=$new_maxage
26397         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26398                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26399 }
26400
26401 generate_uneven_mdts() {
26402         local threshold=$1
26403         local ffree
26404         local bavail
26405         local max
26406         local min
26407         local max_index
26408         local min_index
26409         local tmp
26410         local i
26411
26412         echo
26413         echo "Check for uneven MDTs: "
26414
26415         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26416         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26417         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26418
26419         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26420         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26421         max_index=0
26422         min_index=0
26423         for ((i = 1; i < ${#ffree[@]}; i++)); do
26424                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26425                 if [ $tmp -gt $max ]; then
26426                         max=$tmp
26427                         max_index=$i
26428                 fi
26429                 if [ $tmp -lt $min ]; then
26430                         min=$tmp
26431                         min_index=$i
26432                 fi
26433         done
26434
26435         (( min > 0 )) || skip "low space on MDT$min_index"
26436         (( ${ffree[min_index]} > 0 )) ||
26437                 skip "no free files on MDT$min_index"
26438         (( ${ffree[min_index]} < 10000000 )) ||
26439                 skip "too many free files on MDT$min_index"
26440
26441         # Check if we need to generate uneven MDTs
26442         local diff=$(((max - min) * 100 / min))
26443         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26444         local testdir # individual folder within $testdirp
26445         local start
26446         local cmd
26447
26448         # fallocate is faster to consume space on MDT, if available
26449         if check_fallocate_supported mds$((min_index + 1)); then
26450                 cmd="fallocate -l 128K "
26451         else
26452                 cmd="dd if=/dev/zero bs=128K count=1 of="
26453         fi
26454
26455         echo "using cmd $cmd"
26456         for (( i = 0; diff < threshold; i++ )); do
26457                 testdir=${testdirp}/$i
26458                 [ -d $testdir ] && continue
26459
26460                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26461
26462                 mkdir -p $testdirp
26463                 # generate uneven MDTs, create till $threshold% diff
26464                 echo -n "weight diff=$diff% must be > $threshold% ..."
26465                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26466                 $LFS mkdir -i $min_index $testdir ||
26467                         error "mkdir $testdir failed"
26468                 $LFS setstripe -E 1M -L mdt $testdir ||
26469                         error "setstripe $testdir failed"
26470                 start=$SECONDS
26471                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26472                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26473                 done
26474                 sync; sleep 1; sync
26475
26476                 # wait for QOS to update
26477                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26478
26479                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26480                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26481                 max=$(((${ffree[max_index]} >> 8) *
26482                         (${bavail[max_index]} * bsize >> 16)))
26483                 min=$(((${ffree[min_index]} >> 8) *
26484                         (${bavail[min_index]} * bsize >> 16)))
26485                 (( min > 0 )) || skip "low space on MDT$min_index"
26486                 diff=$(((max - min) * 100 / min))
26487         done
26488
26489         echo "MDT filesfree available: ${ffree[*]}"
26490         echo "MDT blocks available: ${bavail[*]}"
26491         echo "weight diff=$diff%"
26492 }
26493
26494 test_qos_mkdir() {
26495         local mkdir_cmd=$1
26496         local stripe_count=$2
26497         local mdts=$(comma_list $(mdts_nodes))
26498
26499         local testdir
26500         local lmv_qos_prio_free
26501         local lmv_qos_threshold_rr
26502         local lod_qos_prio_free
26503         local lod_qos_threshold_rr
26504         local total
26505         local count
26506         local i
26507
26508         # @total is total directories created if it's testing plain
26509         # directories, otherwise it's total stripe object count for
26510         # striped directories test.
26511         # remote/striped directory unlinking is slow on zfs and may
26512         # timeout, test with fewer directories
26513         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26514
26515         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26516         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26517         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26518                 head -n1)
26519         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26520         stack_trap "$LCTL set_param \
26521                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26522         stack_trap "$LCTL set_param \
26523                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26524
26525         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26526                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26527         lod_qos_prio_free=${lod_qos_prio_free%%%}
26528         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26529                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26530         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26531         stack_trap "do_nodes $mdts $LCTL set_param \
26532                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26533         stack_trap "do_nodes $mdts $LCTL set_param \
26534                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26535
26536         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26537         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26538
26539         testdir=$DIR/$tdir-s$stripe_count/rr
26540
26541         local stripe_index=$($LFS getstripe -m $testdir)
26542         local test_mkdir_rr=true
26543
26544         getfattr -d -m dmv -e hex $testdir | grep dmv
26545         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26546                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26547                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26548                         test_mkdir_rr=false
26549         fi
26550
26551         echo
26552         $test_mkdir_rr &&
26553                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26554                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26555
26556         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26557         for (( i = 0; i < total / stripe_count; i++ )); do
26558                 eval $mkdir_cmd $testdir/subdir$i ||
26559                         error "$mkdir_cmd subdir$i failed"
26560         done
26561
26562         for (( i = 0; i < $MDSCOUNT; i++ )); do
26563                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26564                 echo "$count directories created on MDT$i"
26565                 if $test_mkdir_rr; then
26566                         (( count == total / stripe_count / MDSCOUNT )) ||
26567                                 error "subdirs are not evenly distributed"
26568                 elif (( i == stripe_index )); then
26569                         (( count == total / stripe_count )) ||
26570                                 error "$count subdirs created on MDT$i"
26571                 else
26572                         (( count == 0 )) ||
26573                                 error "$count subdirs created on MDT$i"
26574                 fi
26575
26576                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26577                         count=$($LFS getdirstripe $testdir/* |
26578                                 grep -c -P "^\s+$i\t")
26579                         echo "$count stripes created on MDT$i"
26580                         # deviation should < 5% of average
26581                         delta=$((count - total / MDSCOUNT))
26582                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26583                                 error "stripes are not evenly distributed"
26584                 fi
26585         done
26586
26587         echo
26588         echo "Check for uneven MDTs: "
26589
26590         local ffree
26591         local bavail
26592         local max
26593         local min
26594         local max_index
26595         local min_index
26596         local tmp
26597
26598         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26599         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26600         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26601
26602         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26603         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26604         max_index=0
26605         min_index=0
26606         for ((i = 1; i < ${#ffree[@]}; i++)); do
26607                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26608                 if [ $tmp -gt $max ]; then
26609                         max=$tmp
26610                         max_index=$i
26611                 fi
26612                 if [ $tmp -lt $min ]; then
26613                         min=$tmp
26614                         min_index=$i
26615                 fi
26616         done
26617         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26618
26619         (( min > 0 )) || skip "low space on MDT$min_index"
26620         (( ${ffree[min_index]} < 10000000 )) ||
26621                 skip "too many free files on MDT$min_index"
26622
26623         generate_uneven_mdts 120
26624
26625         echo "MDT filesfree available: ${ffree[*]}"
26626         echo "MDT blocks available: ${bavail[*]}"
26627         echo "weight diff=$(((max - min) * 100 / min))%"
26628         echo
26629         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26630
26631         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26632         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26633         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26634         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26635         # decrease statfs age, so that it can be updated in time
26636         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26637         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26638
26639         sleep 1
26640
26641         testdir=$DIR/$tdir-s$stripe_count/qos
26642
26643         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26644         for (( i = 0; i < total / stripe_count; i++ )); do
26645                 eval $mkdir_cmd $testdir/subdir$i ||
26646                         error "$mkdir_cmd subdir$i failed"
26647         done
26648
26649         max=0
26650         for (( i = 0; i < $MDSCOUNT; i++ )); do
26651                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26652                 (( count > max )) && max=$count
26653                 echo "$count directories created on MDT$i : curmax=$max"
26654         done
26655
26656         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26657
26658         # D-value should > 10% of average
26659         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26660                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26661
26662         # ditto for stripes
26663         if (( stripe_count > 1 )); then
26664                 max=0
26665                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26666                         count=$($LFS getdirstripe $testdir/* |
26667                                 grep -c -P "^\s+$i\t")
26668                         (( count > max )) && max=$count
26669                         echo "$count stripes created on MDT$i"
26670                 done
26671
26672                 min=$($LFS getdirstripe $testdir/* |
26673                         grep -c -P "^\s+$min_index\t")
26674                 (( max - min > total / MDSCOUNT / 10 )) ||
26675                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26676         fi
26677 }
26678
26679 most_full_mdt() {
26680         local ffree
26681         local bavail
26682         local bsize
26683         local min
26684         local min_index
26685         local tmp
26686
26687         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26688         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26689         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26690
26691         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26692         min_index=0
26693         for ((i = 1; i < ${#ffree[@]}; i++)); do
26694                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26695                 (( tmp < min )) && min=$tmp && min_index=$i
26696         done
26697
26698         echo -n $min_index
26699 }
26700
26701 test_413a() {
26702         [ $MDSCOUNT -lt 2 ] &&
26703                 skip "We need at least 2 MDTs for this test"
26704
26705         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26706                 skip "Need server version at least 2.12.52"
26707
26708         local stripe_max=$((MDSCOUNT - 1))
26709         local stripe_count
26710
26711         # let caller set maxage for latest result
26712         set_maxage 1
26713
26714         # fill MDT unevenly
26715         generate_uneven_mdts 120
26716
26717         # test 4-stripe directory at most, otherwise it's too slow
26718         # We are being very defensive. Although Autotest uses 4 MDTs.
26719         # We make sure stripe_max does not go over 4.
26720         (( stripe_max > 4 )) && stripe_max=4
26721         # unlinking striped directory is slow on zfs, and may timeout, only test
26722         # plain directory
26723         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26724         for stripe_count in $(seq 1 $stripe_max); do
26725                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26726                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26727                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26728                         error "mkdir failed"
26729                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26730         done
26731 }
26732 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26733
26734 test_413b() {
26735         [ $MDSCOUNT -lt 2 ] &&
26736                 skip "We need at least 2 MDTs for this test"
26737
26738         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26739                 skip "Need server version at least 2.12.52"
26740
26741         local stripe_max=$((MDSCOUNT - 1))
26742         local testdir
26743         local stripe_count
26744
26745         # let caller set maxage for latest result
26746         set_maxage 1
26747
26748         # fill MDT unevenly
26749         generate_uneven_mdts 120
26750
26751         # test 4-stripe directory at most, otherwise it's too slow
26752         # We are being very defensive. Although Autotest uses 4 MDTs.
26753         # We make sure stripe_max does not go over 4.
26754         (( stripe_max > 4 )) && stripe_max=4
26755         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26756         for stripe_count in $(seq 1 $stripe_max); do
26757                 testdir=$DIR/$tdir-s$stripe_count
26758                 mkdir $testdir || error "mkdir $testdir failed"
26759                 mkdir $testdir/rr || error "mkdir rr failed"
26760                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26761                         error "mkdir qos failed"
26762                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26763                         $testdir/rr || error "setdirstripe rr failed"
26764                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26765                         error "setdirstripe failed"
26766                 test_qos_mkdir "mkdir" $stripe_count
26767         done
26768 }
26769 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26770
26771 test_413c() {
26772         (( $MDSCOUNT >= 2 )) ||
26773                 skip "We need at least 2 MDTs for this test"
26774
26775         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26776                 skip "Need server version at least 2.14.51"
26777
26778         local testdir
26779         local inherit
26780         local inherit_rr
26781         local lmv_qos_maxage
26782         local lod_qos_maxage
26783
26784         # let caller set maxage for latest result
26785         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26786         $LCTL set_param lmv.*.qos_maxage=1
26787         stack_trap "$LCTL set_param \
26788                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26789         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26790                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26791         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26792                 lod.*.mdt_qos_maxage=1
26793         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26794                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26795
26796         # fill MDT unevenly
26797         generate_uneven_mdts 120
26798
26799         testdir=$DIR/${tdir}-s1
26800         mkdir $testdir || error "mkdir $testdir failed"
26801         mkdir $testdir/rr || error "mkdir rr failed"
26802         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26803         # default max_inherit is -1, default max_inherit_rr is 0
26804         $LFS setdirstripe -D -c 1 $testdir/rr ||
26805                 error "setdirstripe rr failed"
26806         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26807                 error "setdirstripe qos failed"
26808         test_qos_mkdir "mkdir" 1
26809
26810         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26811         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26812         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26813         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26814         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26815
26816         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26817         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26818         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26819         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26820         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26821         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26822         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26823                 error "level2 shouldn't have default LMV" || true
26824 }
26825 run_test 413c "mkdir with default LMV max inherit rr"
26826
26827 test_413d() {
26828         (( MDSCOUNT >= 2 )) ||
26829                 skip "We need at least 2 MDTs for this test"
26830
26831         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26832                 skip "Need server version at least 2.14.51"
26833
26834         local lmv_qos_threshold_rr
26835
26836         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26837                 head -n1)
26838         stack_trap "$LCTL set_param \
26839                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26840
26841         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26842         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26843         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26844                 error "$tdir shouldn't have default LMV"
26845         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26846                 error "mkdir sub failed"
26847
26848         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26849
26850         (( count == 100 )) || error "$count subdirs on MDT0"
26851 }
26852 run_test 413d "inherit ROOT default LMV"
26853
26854 test_413e() {
26855         (( MDSCOUNT >= 2 )) ||
26856                 skip "We need at least 2 MDTs for this test"
26857         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26858                 skip "Need server version at least 2.14.55"
26859
26860         local testdir=$DIR/$tdir
26861         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26862         local max_inherit
26863         local sub_max_inherit
26864
26865         mkdir -p $testdir || error "failed to create $testdir"
26866
26867         # set default max-inherit to -1 if stripe count is 0 or 1
26868         $LFS setdirstripe -D -c 1 $testdir ||
26869                 error "failed to set default LMV"
26870         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26871         (( max_inherit == -1 )) ||
26872                 error "wrong max_inherit value $max_inherit"
26873
26874         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26875         $LFS setdirstripe -D -c -1 $testdir ||
26876                 error "failed to set default LMV"
26877         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26878         (( max_inherit > 0 )) ||
26879                 error "wrong max_inherit value $max_inherit"
26880
26881         # and the subdir will decrease the max_inherit by 1
26882         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26883         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26884         (( sub_max_inherit == max_inherit - 1)) ||
26885                 error "wrong max-inherit of subdir $sub_max_inherit"
26886
26887         # check specified --max-inherit and warning message
26888         stack_trap "rm -f $tmpfile"
26889         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26890                 error "failed to set default LMV"
26891         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26892         (( max_inherit == -1 )) ||
26893                 error "wrong max_inherit value $max_inherit"
26894
26895         # check the warning messages
26896         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26897                 error "failed to detect warning string"
26898         fi
26899 }
26900 run_test 413e "check default max-inherit value"
26901
26902 test_fs_dmv_inherit()
26903 {
26904         local testdir=$DIR/$tdir
26905
26906         local count
26907         local inherit
26908         local inherit_rr
26909
26910         for i in 1 2; do
26911                 mkdir $testdir || error "mkdir $testdir failed"
26912                 count=$($LFS getdirstripe -D -c $testdir)
26913                 (( count == 1 )) ||
26914                         error "$testdir default LMV count mismatch $count != 1"
26915                 inherit=$($LFS getdirstripe -D -X $testdir)
26916                 (( inherit == 3 - i )) ||
26917                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26918                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26919                 (( inherit_rr == 3 - i )) ||
26920                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26921                 testdir=$testdir/sub
26922         done
26923
26924         mkdir $testdir || error "mkdir $testdir failed"
26925         count=$($LFS getdirstripe -D -c $testdir)
26926         (( count == 0 )) ||
26927                 error "$testdir default LMV count not zero: $count"
26928 }
26929
26930 test_413f() {
26931         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26932
26933         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26934                 skip "Need server version at least 2.14.55"
26935
26936         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26937                 error "dump $DIR default LMV failed"
26938         stack_trap "setfattr --restore=$TMP/dmv.ea"
26939
26940         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26941                 error "set $DIR default LMV failed"
26942
26943         test_fs_dmv_inherit
26944 }
26945 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26946
26947 test_413g() {
26948         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26949
26950         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26951         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26952                 error "dump $DIR default LMV failed"
26953         stack_trap "setfattr --restore=$TMP/dmv.ea"
26954
26955         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26956                 error "set $DIR default LMV failed"
26957
26958         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26959                 error "mount $MOUNT2 failed"
26960         stack_trap "umount_client $MOUNT2"
26961
26962         local saved_DIR=$DIR
26963
26964         export DIR=$MOUNT2
26965
26966         stack_trap "export DIR=$saved_DIR"
26967
26968         # first check filesystem-wide default LMV inheritance
26969         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26970
26971         # then check subdirs are spread to all MDTs
26972         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26973
26974         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26975
26976         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26977 }
26978 run_test 413g "enforce ROOT default LMV on subdir mount"
26979
26980 test_413h() {
26981         (( MDSCOUNT >= 2 )) ||
26982                 skip "We need at least 2 MDTs for this test"
26983
26984         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26985                 skip "Need server version at least 2.15.50.6"
26986
26987         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26988
26989         stack_trap "$LCTL set_param \
26990                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26991         $LCTL set_param lmv.*.qos_maxage=1
26992
26993         local depth=5
26994         local rr_depth=4
26995         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26996         local count=$((MDSCOUNT * 20))
26997
26998         generate_uneven_mdts 50
26999
27000         mkdir -p $dir || error "mkdir $dir failed"
27001         stack_trap "rm -rf $dir"
27002         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27003                 --max-inherit-rr=$rr_depth $dir
27004
27005         for ((d=0; d < depth + 2; d++)); do
27006                 log "dir=$dir:"
27007                 for ((sub=0; sub < count; sub++)); do
27008                         mkdir $dir/d$sub
27009                 done
27010                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27011                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27012                 # subdirs within $rr_depth should be created round-robin
27013                 if (( d < rr_depth )); then
27014                         (( ${num[0]} != count )) ||
27015                                 error "all objects created on MDT ${num[1]}"
27016                 fi
27017
27018                 dir=$dir/d0
27019         done
27020 }
27021 run_test 413h "don't stick to parent for round-robin dirs"
27022
27023 test_413i() {
27024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27025
27026         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27027                 skip "Need server version at least 2.14.55"
27028
27029         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27030                 error "dump $DIR default LMV failed"
27031         stack_trap "setfattr --restore=$TMP/dmv.ea"
27032
27033         local testdir=$DIR/$tdir
27034         local def_max_rr=1
27035         local def_max=3
27036         local count
27037
27038         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27039                 --max-inherit-rr=$def_max_rr $DIR ||
27040                 error "set $DIR default LMV failed"
27041
27042         for i in $(seq 2 3); do
27043                 def_max=$((def_max - 1))
27044                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27045
27046                 mkdir $testdir
27047                 # RR is decremented and keeps zeroed once exhausted
27048                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27049                 (( count == def_max_rr )) ||
27050                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27051
27052                 # max-inherit is decremented
27053                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27054                 (( count == def_max )) ||
27055                         error_noexit "$testdir: max-inherit $count != $def_max"
27056
27057                 testdir=$testdir/d$i
27058         done
27059
27060         # d3 is the last inherited from ROOT, no inheritance anymore
27061         # i.e. no the default layout anymore
27062         mkdir -p $testdir/d4/d5
27063         count=$($LFS getdirstripe -D --max-inherit $testdir)
27064         (( count == -1 )) ||
27065                 error_noexit "$testdir: max-inherit $count != -1"
27066
27067         local p_count=$($LFS getdirstripe -i $testdir)
27068
27069         for i in $(seq 4 5); do
27070                 testdir=$testdir/d$i
27071
27072                 # the root default layout is not applied once exhausted
27073                 count=$($LFS getdirstripe -i $testdir)
27074                 (( count == p_count )) ||
27075                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27076         done
27077
27078         $LFS setdirstripe -i 0 $DIR/d2
27079         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27080         (( count == -1 )) ||
27081                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27082 }
27083 run_test 413i "check default layout inheritance"
27084
27085 test_413z() {
27086         local pids=""
27087         local subdir
27088         local pid
27089
27090         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27091                 unlinkmany $subdir/f. $TEST413_COUNT &
27092                 pids="$pids $!"
27093         done
27094
27095         for pid in $pids; do
27096                 wait $pid
27097         done
27098
27099         true
27100 }
27101 run_test 413z "413 test cleanup"
27102
27103 test_414() {
27104 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27105         $LCTL set_param fail_loc=0x80000521
27106         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27107         rm -f $DIR/$tfile
27108 }
27109 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27110
27111 test_415() {
27112         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27113         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27114                 skip "Need server version at least 2.11.52"
27115
27116         # LU-11102
27117         local total=500
27118         local max=120
27119
27120         # this test may be slow on ZFS
27121         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27122
27123         # though this test is designed for striped directory, let's test normal
27124         # directory too since lock is always saved as CoS lock.
27125         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27126         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27127         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27128         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27129         wait_delete_completed_mds
27130
27131         # run a loop without concurrent touch to measure rename duration.
27132         # only for test debug/robustness, NOT part of COS functional test.
27133         local start_time=$SECONDS
27134         for ((i = 0; i < total; i++)); do
27135                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27136                         > /dev/null
27137         done
27138         local baseline=$((SECONDS - start_time))
27139         echo "rename $total files without 'touch' took $baseline sec"
27140
27141         (
27142                 while true; do
27143                         touch $DIR/$tdir
27144                 done
27145         ) &
27146         local setattr_pid=$!
27147
27148         # rename files back to original name so unlinkmany works
27149         start_time=$SECONDS
27150         for ((i = 0; i < total; i++)); do
27151                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27152                         > /dev/null
27153         done
27154         local duration=$((SECONDS - start_time))
27155
27156         kill -9 $setattr_pid
27157
27158         echo "rename $total files with 'touch' took $duration sec"
27159         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27160         (( duration <= max )) || error "rename took $duration > $max sec"
27161 }
27162 run_test 415 "lock revoke is not missing"
27163
27164 test_416() {
27165         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27166                 skip "Need server version at least 2.11.55"
27167
27168         # define OBD_FAIL_OSD_TXN_START    0x19a
27169         do_facet mds1 lctl set_param fail_loc=0x19a
27170
27171         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27172
27173         true
27174 }
27175 run_test 416 "transaction start failure won't cause system hung"
27176
27177 cleanup_417() {
27178         trap 0
27179         do_nodes $(comma_list $(mdts_nodes)) \
27180                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27181         do_nodes $(comma_list $(mdts_nodes)) \
27182                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27183         do_nodes $(comma_list $(mdts_nodes)) \
27184                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27185 }
27186
27187 test_417() {
27188         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27189         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27190                 skip "Need MDS version at least 2.11.56"
27191
27192         trap cleanup_417 RETURN EXIT
27193
27194         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27195         do_nodes $(comma_list $(mdts_nodes)) \
27196                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27197         $LFS migrate -m 0 $DIR/$tdir.1 &&
27198                 error "migrate dir $tdir.1 should fail"
27199
27200         do_nodes $(comma_list $(mdts_nodes)) \
27201                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27202         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27203                 error "create remote dir $tdir.2 should fail"
27204
27205         do_nodes $(comma_list $(mdts_nodes)) \
27206                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27207         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27208                 error "create striped dir $tdir.3 should fail"
27209         true
27210 }
27211 run_test 417 "disable remote dir, striped dir and dir migration"
27212
27213 # Checks that the outputs of df [-i] and lfs df [-i] match
27214 #
27215 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27216 check_lfs_df() {
27217         local dir=$2
27218         local inodes
27219         local df_out
27220         local lfs_df_out
27221         local count
27222         local passed=false
27223
27224         # blocks or inodes
27225         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27226
27227         for count in {1..100}; do
27228                 do_nodes "$CLIENTS" \
27229                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27230                 sync; sleep 0.2
27231
27232                 # read the lines of interest
27233                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27234                         error "df $inodes $dir | tail -n +2 failed"
27235                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27236                         error "lfs df $inodes $dir | grep summary: failed"
27237
27238                 # skip first substrings of each output as they are different
27239                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27240                 # compare the two outputs
27241                 passed=true
27242                 #  skip "available" on MDT until LU-13997 is fixed.
27243                 #for i in {1..5}; do
27244                 for i in 1 2 4 5; do
27245                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27246                 done
27247                 $passed && break
27248         done
27249
27250         if ! $passed; then
27251                 df -P $inodes $dir
27252                 echo
27253                 lfs df $inodes $dir
27254                 error "df and lfs df $1 output mismatch: "      \
27255                       "df ${inodes}: ${df_out[*]}, "            \
27256                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27257         fi
27258 }
27259
27260 test_418() {
27261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27262
27263         local dir=$DIR/$tdir
27264         local numfiles=$((RANDOM % 4096 + 2))
27265         local numblocks=$((RANDOM % 256 + 1))
27266
27267         wait_delete_completed
27268         test_mkdir $dir
27269
27270         # check block output
27271         check_lfs_df blocks $dir
27272         # check inode output
27273         check_lfs_df inodes $dir
27274
27275         # create a single file and retest
27276         echo "Creating a single file and testing"
27277         createmany -o $dir/$tfile- 1 &>/dev/null ||
27278                 error "creating 1 file in $dir failed"
27279         check_lfs_df blocks $dir
27280         check_lfs_df inodes $dir
27281
27282         # create a random number of files
27283         echo "Creating $((numfiles - 1)) files and testing"
27284         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27285                 error "creating $((numfiles - 1)) files in $dir failed"
27286
27287         # write a random number of blocks to the first test file
27288         echo "Writing $numblocks 4K blocks and testing"
27289         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27290                 count=$numblocks &>/dev/null ||
27291                 error "dd to $dir/${tfile}-0 failed"
27292
27293         # retest
27294         check_lfs_df blocks $dir
27295         check_lfs_df inodes $dir
27296
27297         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27298                 error "unlinking $numfiles files in $dir failed"
27299 }
27300 run_test 418 "df and lfs df outputs match"
27301
27302 test_419()
27303 {
27304         local dir=$DIR/$tdir
27305
27306         mkdir -p $dir
27307         touch $dir/file
27308
27309         cancel_lru_locks mdc
27310
27311         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27312         $LCTL set_param fail_loc=0x1410
27313         cat $dir/file
27314         $LCTL set_param fail_loc=0
27315         rm -rf $dir
27316 }
27317 run_test 419 "Verify open file by name doesn't crash kernel"
27318
27319 test_420()
27320 {
27321         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27322                 skip "Need MDS version at least 2.12.53"
27323
27324         local SAVE_UMASK=$(umask)
27325         local dir=$DIR/$tdir
27326         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27327
27328         mkdir -p $dir
27329         umask 0000
27330         mkdir -m03777 $dir/testdir
27331         ls -dn $dir/testdir
27332         # Need to remove trailing '.' when SELinux is enabled
27333         local dirperms=$(ls -dn $dir/testdir |
27334                          awk '{ sub(/\.$/, "", $1); print $1}')
27335         [ $dirperms == "drwxrwsrwt" ] ||
27336                 error "incorrect perms on $dir/testdir"
27337
27338         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27339                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27340         ls -n $dir/testdir/testfile
27341         local fileperms=$(ls -n $dir/testdir/testfile |
27342                           awk '{ sub(/\.$/, "", $1); print $1}')
27343         [ $fileperms == "-rwxr-xr-x" ] ||
27344                 error "incorrect perms on $dir/testdir/testfile"
27345
27346         umask $SAVE_UMASK
27347 }
27348 run_test 420 "clear SGID bit on non-directories for non-members"
27349
27350 test_421a() {
27351         local cnt
27352         local fid1
27353         local fid2
27354
27355         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27356                 skip "Need MDS version at least 2.12.54"
27357
27358         test_mkdir $DIR/$tdir
27359         createmany -o $DIR/$tdir/f 3
27360         cnt=$(ls -1 $DIR/$tdir | wc -l)
27361         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27362
27363         fid1=$(lfs path2fid $DIR/$tdir/f1)
27364         fid2=$(lfs path2fid $DIR/$tdir/f2)
27365         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27366
27367         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27368         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27369
27370         cnt=$(ls -1 $DIR/$tdir | wc -l)
27371         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27372
27373         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27374         createmany -o $DIR/$tdir/f 3
27375         cnt=$(ls -1 $DIR/$tdir | wc -l)
27376         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27377
27378         fid1=$(lfs path2fid $DIR/$tdir/f1)
27379         fid2=$(lfs path2fid $DIR/$tdir/f2)
27380         echo "remove using fsname $FSNAME"
27381         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27382
27383         cnt=$(ls -1 $DIR/$tdir | wc -l)
27384         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27385 }
27386 run_test 421a "simple rm by fid"
27387
27388 test_421b() {
27389         local cnt
27390         local FID1
27391         local FID2
27392
27393         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27394                 skip "Need MDS version at least 2.12.54"
27395
27396         test_mkdir $DIR/$tdir
27397         createmany -o $DIR/$tdir/f 3
27398         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27399         MULTIPID=$!
27400
27401         FID1=$(lfs path2fid $DIR/$tdir/f1)
27402         FID2=$(lfs path2fid $DIR/$tdir/f2)
27403         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27404
27405         kill -USR1 $MULTIPID
27406         wait
27407
27408         cnt=$(ls $DIR/$tdir | wc -l)
27409         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27410 }
27411 run_test 421b "rm by fid on open file"
27412
27413 test_421c() {
27414         local cnt
27415         local FIDS
27416
27417         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27418                 skip "Need MDS version at least 2.12.54"
27419
27420         test_mkdir $DIR/$tdir
27421         createmany -o $DIR/$tdir/f 3
27422         touch $DIR/$tdir/$tfile
27423         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27424         cnt=$(ls -1 $DIR/$tdir | wc -l)
27425         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27426
27427         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27428         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27429
27430         cnt=$(ls $DIR/$tdir | wc -l)
27431         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27432 }
27433 run_test 421c "rm by fid against hardlinked files"
27434
27435 test_421d() {
27436         local cnt
27437         local FIDS
27438
27439         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27440                 skip "Need MDS version at least 2.12.54"
27441
27442         test_mkdir $DIR/$tdir
27443         createmany -o $DIR/$tdir/f 4097
27444         cnt=$(ls -1 $DIR/$tdir | wc -l)
27445         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27446
27447         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27448         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27449
27450         cnt=$(ls $DIR/$tdir | wc -l)
27451         rm -rf $DIR/$tdir
27452         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27453 }
27454 run_test 421d "rmfid en masse"
27455
27456 test_421e() {
27457         local cnt
27458         local FID
27459
27460         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27461         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27462                 skip "Need MDS version at least 2.12.54"
27463
27464         mkdir -p $DIR/$tdir
27465         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27466         createmany -o $DIR/$tdir/striped_dir/f 512
27467         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27468         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27469
27470         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27471                 sed "s/[/][^:]*://g")
27472         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27473
27474         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27475         rm -rf $DIR/$tdir
27476         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27477 }
27478 run_test 421e "rmfid in DNE"
27479
27480 test_421f() {
27481         local cnt
27482         local FID
27483
27484         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27485                 skip "Need MDS version at least 2.12.54"
27486
27487         test_mkdir $DIR/$tdir
27488         touch $DIR/$tdir/f
27489         cnt=$(ls -1 $DIR/$tdir | wc -l)
27490         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27491
27492         FID=$(lfs path2fid $DIR/$tdir/f)
27493         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27494         # rmfid should fail
27495         cnt=$(ls -1 $DIR/$tdir | wc -l)
27496         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27497
27498         chmod a+rw $DIR/$tdir
27499         ls -la $DIR/$tdir
27500         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27501         # rmfid should fail
27502         cnt=$(ls -1 $DIR/$tdir | wc -l)
27503         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27504
27505         rm -f $DIR/$tdir/f
27506         $RUNAS touch $DIR/$tdir/f
27507         FID=$(lfs path2fid $DIR/$tdir/f)
27508         echo "rmfid as root"
27509         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27510         cnt=$(ls -1 $DIR/$tdir | wc -l)
27511         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27512
27513         rm -f $DIR/$tdir/f
27514         $RUNAS touch $DIR/$tdir/f
27515         cnt=$(ls -1 $DIR/$tdir | wc -l)
27516         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27517         FID=$(lfs path2fid $DIR/$tdir/f)
27518         # rmfid w/o user_fid2path mount option should fail
27519         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27520         cnt=$(ls -1 $DIR/$tdir | wc -l)
27521         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27522
27523         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27524         stack_trap "rmdir $tmpdir"
27525         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27526                 error "failed to mount client'"
27527         stack_trap "umount_client $tmpdir"
27528
27529         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27530         # rmfid should succeed
27531         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27532         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27533
27534         # rmfid shouldn't allow to remove files due to dir's permission
27535         chmod a+rwx $tmpdir/$tdir
27536         touch $tmpdir/$tdir/f
27537         ls -la $tmpdir/$tdir
27538         FID=$(lfs path2fid $tmpdir/$tdir/f)
27539         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27540         return 0
27541 }
27542 run_test 421f "rmfid checks permissions"
27543
27544 test_421g() {
27545         local cnt
27546         local FIDS
27547
27548         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27549         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27550                 skip "Need MDS version at least 2.12.54"
27551
27552         mkdir -p $DIR/$tdir
27553         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27554         createmany -o $DIR/$tdir/striped_dir/f 512
27555         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27556         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27557
27558         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27559                 sed "s/[/][^:]*://g")
27560
27561         rm -f $DIR/$tdir/striped_dir/f1*
27562         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27563         removed=$((512 - cnt))
27564
27565         # few files have been just removed, so we expect
27566         # rmfid to fail on their fids
27567         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27568         [ $removed != $errors ] && error "$errors != $removed"
27569
27570         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27571         rm -rf $DIR/$tdir
27572         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27573 }
27574 run_test 421g "rmfid to return errors properly"
27575
27576 test_421h() {
27577         local mount_other
27578         local mount_ret
27579         local rmfid_ret
27580         local old_fid
27581         local fidA
27582         local fidB
27583         local fidC
27584         local fidD
27585
27586         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27587                 skip "Need MDS version at least 2.15.53"
27588
27589         test_mkdir $DIR/$tdir
27590         test_mkdir $DIR/$tdir/subdir
27591         touch $DIR/$tdir/subdir/file0
27592         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27593         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27594         rm -f $DIR/$tdir/subdir/file0
27595         touch $DIR/$tdir/subdir/fileA
27596         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27597         echo File $DIR/$tdir/subdir/fileA FID $fidA
27598         touch $DIR/$tdir/subdir/fileB
27599         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27600         echo File $DIR/$tdir/subdir/fileB FID $fidB
27601         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27602         touch $DIR/$tdir/subdir/fileC
27603         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27604         echo File $DIR/$tdir/subdir/fileC FID $fidC
27605         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27606         touch $DIR/$tdir/fileD
27607         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27608         echo File $DIR/$tdir/fileD FID $fidD
27609
27610         # mount another client mount point with subdirectory mount
27611         export FILESET=/$tdir/subdir
27612         mount_other=${MOUNT}_other
27613         mount_client $mount_other ${MOUNT_OPTS}
27614         mount_ret=$?
27615         export FILESET=""
27616         (( mount_ret == 0 )) || error "mount $mount_other failed"
27617
27618         echo Removing FIDs:
27619         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27620         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27621         rmfid_ret=$?
27622
27623         umount_client $mount_other || error "umount $mount_other failed"
27624
27625         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27626
27627         # fileA should have been deleted
27628         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27629
27630         # fileB should have been deleted
27631         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27632
27633         # fileC should not have been deleted, fid also exists outside of fileset
27634         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27635
27636         # fileD should not have been deleted, it exists outside of fileset
27637         stat $DIR/$tdir/fileD || error "fileD deleted"
27638 }
27639 run_test 421h "rmfid with fileset mount"
27640
27641 test_422() {
27642         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27643         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27644         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27645         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27646         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27647
27648         local amc=$(at_max_get client)
27649         local amo=$(at_max_get mds1)
27650         local timeout=`lctl get_param -n timeout`
27651
27652         at_max_set 0 client
27653         at_max_set 0 mds1
27654
27655 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27656         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27657                         fail_val=$(((2*timeout + 10)*1000))
27658         touch $DIR/$tdir/d3/file &
27659         sleep 2
27660 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27661         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27662                         fail_val=$((2*timeout + 5))
27663         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27664         local pid=$!
27665         sleep 1
27666         kill -9 $pid
27667         sleep $((2 * timeout))
27668         echo kill $pid
27669         kill -9 $pid
27670         lctl mark touch
27671         touch $DIR/$tdir/d2/file3
27672         touch $DIR/$tdir/d2/file4
27673         touch $DIR/$tdir/d2/file5
27674
27675         wait
27676         at_max_set $amc client
27677         at_max_set $amo mds1
27678
27679         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27680         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27681                 error "Watchdog is always throttled"
27682 }
27683 run_test 422 "kill a process with RPC in progress"
27684
27685 stat_test() {
27686     df -h $MOUNT &
27687     df -h $MOUNT &
27688     df -h $MOUNT &
27689     df -h $MOUNT &
27690     df -h $MOUNT &
27691     df -h $MOUNT &
27692 }
27693
27694 test_423() {
27695     local _stats
27696     # ensure statfs cache is expired
27697     sleep 2;
27698
27699     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27700     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27701
27702     return 0
27703 }
27704 run_test 423 "statfs should return a right data"
27705
27706 test_424() {
27707 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27708         $LCTL set_param fail_loc=0x80000522
27709         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27710         rm -f $DIR/$tfile
27711 }
27712 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27713
27714 test_425() {
27715         test_mkdir -c -1 $DIR/$tdir
27716         $LFS setstripe -c -1 $DIR/$tdir
27717
27718         lru_resize_disable "" 100
27719         stack_trap "lru_resize_enable" EXIT
27720
27721         sleep 5
27722
27723         for i in $(seq $((MDSCOUNT * 125))); do
27724                 local t=$DIR/$tdir/$tfile_$i
27725
27726                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27727                         error_noexit "Create file $t"
27728         done
27729         stack_trap "rm -rf $DIR/$tdir" EXIT
27730
27731         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27732                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27733                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27734
27735                 [ $lock_count -le $lru_size ] ||
27736                         error "osc lock count $lock_count > lru size $lru_size"
27737         done
27738
27739         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27740                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27741                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27742
27743                 [ $lock_count -le $lru_size ] ||
27744                         error "mdc lock count $lock_count > lru size $lru_size"
27745         done
27746 }
27747 run_test 425 "lock count should not exceed lru size"
27748
27749 test_426() {
27750         splice-test -r $DIR/$tfile
27751         splice-test -rd $DIR/$tfile
27752         splice-test $DIR/$tfile
27753         splice-test -d $DIR/$tfile
27754 }
27755 run_test 426 "splice test on Lustre"
27756
27757 test_427() {
27758         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27759         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27760                 skip "Need MDS version at least 2.12.4"
27761         local log
27762
27763         mkdir $DIR/$tdir
27764         mkdir $DIR/$tdir/1
27765         mkdir $DIR/$tdir/2
27766         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27767         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27768
27769         $LFS getdirstripe $DIR/$tdir/1/dir
27770
27771         #first setfattr for creating updatelog
27772         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27773
27774 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27775         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27776         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27777         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27778
27779         sleep 2
27780         fail mds2
27781         wait_recovery_complete mds2 $((2*TIMEOUT))
27782
27783         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27784         echo $log | grep "get update log failed" &&
27785                 error "update log corruption is detected" || true
27786 }
27787 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27788
27789 test_428() {
27790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27791         local cache_limit=$CACHE_MAX
27792
27793         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27794         $LCTL set_param -n llite.*.max_cached_mb=64
27795
27796         mkdir $DIR/$tdir
27797         $LFS setstripe -c 1 $DIR/$tdir
27798         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27799         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27800         #test write
27801         for f in $(seq 4); do
27802                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27803         done
27804         wait
27805
27806         cancel_lru_locks osc
27807         # Test read
27808         for f in $(seq 4); do
27809                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27810         done
27811         wait
27812 }
27813 run_test 428 "large block size IO should not hang"
27814
27815 test_429() { # LU-7915 / LU-10948
27816         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27817         local testfile=$DIR/$tfile
27818         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27819         local new_flag=1
27820         local first_rpc
27821         local second_rpc
27822         local third_rpc
27823
27824         $LCTL get_param $ll_opencache_threshold_count ||
27825                 skip "client does not have opencache parameter"
27826
27827         set_opencache $new_flag
27828         stack_trap "restore_opencache"
27829         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27830                 error "enable opencache failed"
27831         touch $testfile
27832         # drop MDC DLM locks
27833         cancel_lru_locks mdc
27834         # clear MDC RPC stats counters
27835         $LCTL set_param $mdc_rpcstats=clear
27836
27837         # According to the current implementation, we need to run 3 times
27838         # open & close file to verify if opencache is enabled correctly.
27839         # 1st, RPCs are sent for lookup/open and open handle is released on
27840         #      close finally.
27841         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27842         #      so open handle won't be released thereafter.
27843         # 3rd, No RPC is sent out.
27844         $MULTIOP $testfile oc || error "multiop failed"
27845         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27846         echo "1st: $first_rpc RPCs in flight"
27847
27848         $MULTIOP $testfile oc || error "multiop failed"
27849         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27850         echo "2nd: $second_rpc RPCs in flight"
27851
27852         $MULTIOP $testfile oc || error "multiop failed"
27853         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27854         echo "3rd: $third_rpc RPCs in flight"
27855
27856         #verify no MDC RPC is sent
27857         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27858 }
27859 run_test 429 "verify if opencache flag on client side does work"
27860
27861 lseek_test_430() {
27862         local offset
27863         local file=$1
27864
27865         # data at [200K, 400K)
27866         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27867                 error "256K->512K dd fails"
27868         # data at [2M, 3M)
27869         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27870                 error "2M->3M dd fails"
27871         # data at [4M, 5M)
27872         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27873                 error "4M->5M dd fails"
27874         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27875         # start at first component hole #1
27876         printf "Seeking hole from 1000 ... "
27877         offset=$(lseek_test -l 1000 $file)
27878         echo $offset
27879         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27880         printf "Seeking data from 1000 ... "
27881         offset=$(lseek_test -d 1000 $file)
27882         echo $offset
27883         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27884
27885         # start at first component data block
27886         printf "Seeking hole from 300000 ... "
27887         offset=$(lseek_test -l 300000 $file)
27888         echo $offset
27889         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27890         printf "Seeking data from 300000 ... "
27891         offset=$(lseek_test -d 300000 $file)
27892         echo $offset
27893         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27894
27895         # start at the first component but beyond end of object size
27896         printf "Seeking hole from 1000000 ... "
27897         offset=$(lseek_test -l 1000000 $file)
27898         echo $offset
27899         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27900         printf "Seeking data from 1000000 ... "
27901         offset=$(lseek_test -d 1000000 $file)
27902         echo $offset
27903         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27904
27905         # start at second component stripe 2 (empty file)
27906         printf "Seeking hole from 1500000 ... "
27907         offset=$(lseek_test -l 1500000 $file)
27908         echo $offset
27909         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27910         printf "Seeking data from 1500000 ... "
27911         offset=$(lseek_test -d 1500000 $file)
27912         echo $offset
27913         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27914
27915         # start at second component stripe 1 (all data)
27916         printf "Seeking hole from 3000000 ... "
27917         offset=$(lseek_test -l 3000000 $file)
27918         echo $offset
27919         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27920         printf "Seeking data from 3000000 ... "
27921         offset=$(lseek_test -d 3000000 $file)
27922         echo $offset
27923         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27924
27925         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27926                 error "2nd dd fails"
27927         echo "Add data block at 640K...1280K"
27928
27929         # start at before new data block, in hole
27930         printf "Seeking hole from 600000 ... "
27931         offset=$(lseek_test -l 600000 $file)
27932         echo $offset
27933         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27934         printf "Seeking data from 600000 ... "
27935         offset=$(lseek_test -d 600000 $file)
27936         echo $offset
27937         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27938
27939         # start at the first component new data block
27940         printf "Seeking hole from 1000000 ... "
27941         offset=$(lseek_test -l 1000000 $file)
27942         echo $offset
27943         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27944         printf "Seeking data from 1000000 ... "
27945         offset=$(lseek_test -d 1000000 $file)
27946         echo $offset
27947         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27948
27949         # start at second component stripe 2, new data
27950         printf "Seeking hole from 1200000 ... "
27951         offset=$(lseek_test -l 1200000 $file)
27952         echo $offset
27953         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27954         printf "Seeking data from 1200000 ... "
27955         offset=$(lseek_test -d 1200000 $file)
27956         echo $offset
27957         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27958
27959         # start beyond file end
27960         printf "Using offset > filesize ... "
27961         lseek_test -l 4000000 $file && error "lseek should fail"
27962         printf "Using offset > filesize ... "
27963         lseek_test -d 4000000 $file && error "lseek should fail"
27964
27965         printf "Done\n\n"
27966 }
27967
27968 test_430a() {
27969         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27970                 skip "MDT does not support SEEK_HOLE"
27971
27972         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27973                 skip "OST does not support SEEK_HOLE"
27974
27975         local file=$DIR/$tdir/$tfile
27976
27977         mkdir -p $DIR/$tdir
27978
27979         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27980         # OST stripe #1 will have continuous data at [1M, 3M)
27981         # OST stripe #2 is empty
27982         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27983         lseek_test_430 $file
27984         rm $file
27985         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27986         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27987         lseek_test_430 $file
27988         rm $file
27989         $LFS setstripe -c2 -S 512K $file
27990         echo "Two stripes, stripe size 512K"
27991         lseek_test_430 $file
27992         rm $file
27993         # FLR with stale mirror
27994         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27995                        -N -c2 -S 1M $file
27996         echo "Mirrored file:"
27997         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27998         echo "Plain 2 stripes 1M"
27999         lseek_test_430 $file
28000         rm $file
28001 }
28002 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28003
28004 test_430b() {
28005         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28006                 skip "OST does not support SEEK_HOLE"
28007
28008         local offset
28009         local file=$DIR/$tdir/$tfile
28010
28011         mkdir -p $DIR/$tdir
28012         # Empty layout lseek should fail
28013         $MCREATE $file
28014         # seek from 0
28015         printf "Seeking hole from 0 ... "
28016         lseek_test -l 0 $file && error "lseek should fail"
28017         printf "Seeking data from 0 ... "
28018         lseek_test -d 0 $file && error "lseek should fail"
28019         rm $file
28020
28021         # 1M-hole file
28022         $LFS setstripe -E 1M -c2 -E eof $file
28023         $TRUNCATE $file 1048576
28024         printf "Seeking hole from 1000000 ... "
28025         offset=$(lseek_test -l 1000000 $file)
28026         echo $offset
28027         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28028         printf "Seeking data from 1000000 ... "
28029         lseek_test -d 1000000 $file && error "lseek should fail"
28030         rm $file
28031
28032         # full component followed by non-inited one
28033         $LFS setstripe -E 1M -c2 -E eof $file
28034         dd if=/dev/urandom of=$file bs=1M count=1
28035         printf "Seeking hole from 1000000 ... "
28036         offset=$(lseek_test -l 1000000 $file)
28037         echo $offset
28038         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28039         printf "Seeking hole from 1048576 ... "
28040         lseek_test -l 1048576 $file && error "lseek should fail"
28041         # init second component and truncate back
28042         echo "123" >> $file
28043         $TRUNCATE $file 1048576
28044         printf "Seeking hole from 1000000 ... "
28045         offset=$(lseek_test -l 1000000 $file)
28046         echo $offset
28047         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28048         printf "Seeking hole from 1048576 ... "
28049         lseek_test -l 1048576 $file && error "lseek should fail"
28050         # boundary checks for big values
28051         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28052         offset=$(lseek_test -d 0 $file.10g)
28053         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28054         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28055         offset=$(lseek_test -d 0 $file.100g)
28056         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28057         return 0
28058 }
28059 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28060
28061 test_430c() {
28062         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28063                 skip "OST does not support SEEK_HOLE"
28064
28065         local file=$DIR/$tdir/$tfile
28066         local start
28067
28068         mkdir -p $DIR/$tdir
28069         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28070
28071         # cp version 8.33+ prefers lseek over fiemap
28072         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28073                 start=$SECONDS
28074                 time cp $file /dev/null
28075                 (( SECONDS - start < 5 )) ||
28076                         error "cp: too long runtime $((SECONDS - start))"
28077
28078         fi
28079         # tar version 1.29+ supports SEEK_HOLE/DATA
28080         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28081                 start=$SECONDS
28082                 time tar cS $file - | cat > /dev/null
28083                 (( SECONDS - start < 5 )) ||
28084                         error "tar: too long runtime $((SECONDS - start))"
28085         fi
28086 }
28087 run_test 430c "lseek: external tools check"
28088
28089 test_431() { # LU-14187
28090         local file=$DIR/$tdir/$tfile
28091
28092         mkdir -p $DIR/$tdir
28093         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28094         dd if=/dev/urandom of=$file bs=4k count=1
28095         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28096         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28097         #define OBD_FAIL_OST_RESTART_IO 0x251
28098         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28099         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28100         cp $file $file.0
28101         cancel_lru_locks
28102         sync_all_data
28103         echo 3 > /proc/sys/vm/drop_caches
28104         diff  $file $file.0 || error "data diff"
28105 }
28106 run_test 431 "Restart transaction for IO"
28107
28108 cleanup_test_432() {
28109         do_facet mgs $LCTL nodemap_activate 0
28110         wait_nm_sync active
28111 }
28112
28113 test_432() {
28114         local tmpdir=$TMP/dir432
28115
28116         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28117                 skip "Need MDS version at least 2.14.52"
28118
28119         stack_trap cleanup_test_432 EXIT
28120         mkdir $DIR/$tdir
28121         mkdir $tmpdir
28122
28123         do_facet mgs $LCTL nodemap_activate 1
28124         wait_nm_sync active
28125         do_facet mgs $LCTL nodemap_modify --name default \
28126                 --property admin --value 1
28127         do_facet mgs $LCTL nodemap_modify --name default \
28128                 --property trusted --value 1
28129         cancel_lru_locks mdc
28130         wait_nm_sync default admin_nodemap
28131         wait_nm_sync default trusted_nodemap
28132
28133         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28134                grep -ci "Operation not permitted") -ne 0 ]; then
28135                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28136         fi
28137 }
28138 run_test 432 "mv dir from outside Lustre"
28139
28140 test_433() {
28141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28142
28143         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28144                 skip "inode cache not supported"
28145
28146         $LCTL set_param llite.*.inode_cache=0
28147         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28148
28149         local count=256
28150         local before
28151         local after
28152
28153         cancel_lru_locks mdc
28154         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28155         createmany -m $DIR/$tdir/f $count
28156         createmany -d $DIR/$tdir/d $count
28157         ls -l $DIR/$tdir > /dev/null
28158         stack_trap "rm -rf $DIR/$tdir"
28159
28160         before=$(num_objects)
28161         cancel_lru_locks mdc
28162         after=$(num_objects)
28163
28164         # sometimes even @before is less than 2 * count
28165         while (( before - after < count )); do
28166                 sleep 1
28167                 after=$(num_objects)
28168                 wait=$((wait + 1))
28169                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28170                 if (( wait > 60 )); then
28171                         error "inode slab grew from $before to $after"
28172                 fi
28173         done
28174
28175         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28176 }
28177 run_test 433 "ldlm lock cancel releases dentries and inodes"
28178
28179 test_434() {
28180         local file
28181         local getxattr_count
28182         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28183         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28184
28185         [[ $(getenforce) == "Disabled" ]] ||
28186                 skip "lsm selinux module have to be disabled for this test"
28187
28188         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28189                 error "fail to create $DIR/$tdir/ on MDT0000"
28190
28191         touch $DIR/$tdir/$tfile-{001..100}
28192
28193         # disable the xattr cache
28194         save_lustre_params client "llite.*.xattr_cache" > $p
28195         lctl set_param llite.*.xattr_cache=0
28196         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28197
28198         # clear clients mdc stats
28199         clear_stats $mdc_stat_param ||
28200                 error "fail to clear stats on mdc MDT0000"
28201
28202         for file in $DIR/$tdir/$tfile-{001..100}; do
28203                 getfattr -n security.selinux $file |&
28204                         grep -q "Operation not supported" ||
28205                         error "getxattr on security.selinux should return EOPNOTSUPP"
28206         done
28207
28208         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28209         (( getxattr_count < 100 )) ||
28210                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28211 }
28212 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28213
28214 test_440() {
28215         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28216                 source $LUSTRE/scripts/bash-completion/lustre
28217         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28218                 source /usr/share/bash-completion/completions/lustre
28219         else
28220                 skip "bash completion scripts not found"
28221         fi
28222
28223         local lctl_completions
28224         local lfs_completions
28225
28226         lctl_completions=$(_lustre_cmds lctl)
28227         if [[ ! $lctl_completions =~ "get_param" ]]; then
28228                 error "lctl bash completion failed"
28229         fi
28230
28231         lfs_completions=$(_lustre_cmds lfs)
28232         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28233                 error "lfs bash completion failed"
28234         fi
28235 }
28236 run_test 440 "bash completion for lfs, lctl"
28237
28238 prep_801() {
28239         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28240         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28241                 skip "Need server version at least 2.9.55"
28242
28243         start_full_debug_logging
28244 }
28245
28246 post_801() {
28247         stop_full_debug_logging
28248 }
28249
28250 barrier_stat() {
28251         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28252                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28253                            awk '/The barrier for/ { print $7 }')
28254                 echo $st
28255         else
28256                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28257                 echo \'$st\'
28258         fi
28259 }
28260
28261 barrier_expired() {
28262         local expired
28263
28264         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28265                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28266                           awk '/will be expired/ { print $7 }')
28267         else
28268                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28269         fi
28270
28271         echo $expired
28272 }
28273
28274 test_801a() {
28275         prep_801
28276
28277         echo "Start barrier_freeze at: $(date)"
28278         #define OBD_FAIL_BARRIER_DELAY          0x2202
28279         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28280         # Do not reduce barrier time - See LU-11873
28281         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28282
28283         sleep 2
28284         local b_status=$(barrier_stat)
28285         echo "Got barrier status at: $(date)"
28286         [ "$b_status" = "'freezing_p1'" ] ||
28287                 error "(1) unexpected barrier status $b_status"
28288
28289         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28290         wait
28291         b_status=$(barrier_stat)
28292         [ "$b_status" = "'frozen'" ] ||
28293                 error "(2) unexpected barrier status $b_status"
28294
28295         local expired=$(barrier_expired)
28296         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28297         sleep $((expired + 3))
28298
28299         b_status=$(barrier_stat)
28300         [ "$b_status" = "'expired'" ] ||
28301                 error "(3) unexpected barrier status $b_status"
28302
28303         # Do not reduce barrier time - See LU-11873
28304         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28305                 error "(4) fail to freeze barrier"
28306
28307         b_status=$(barrier_stat)
28308         [ "$b_status" = "'frozen'" ] ||
28309                 error "(5) unexpected barrier status $b_status"
28310
28311         echo "Start barrier_thaw at: $(date)"
28312         #define OBD_FAIL_BARRIER_DELAY          0x2202
28313         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28314         do_facet mgs $LCTL barrier_thaw $FSNAME &
28315
28316         sleep 2
28317         b_status=$(barrier_stat)
28318         echo "Got barrier status at: $(date)"
28319         [ "$b_status" = "'thawing'" ] ||
28320                 error "(6) unexpected barrier status $b_status"
28321
28322         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28323         wait
28324         b_status=$(barrier_stat)
28325         [ "$b_status" = "'thawed'" ] ||
28326                 error "(7) unexpected barrier status $b_status"
28327
28328         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28329         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28330         do_facet mgs $LCTL barrier_freeze $FSNAME
28331
28332         b_status=$(barrier_stat)
28333         [ "$b_status" = "'failed'" ] ||
28334                 error "(8) unexpected barrier status $b_status"
28335
28336         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28337         do_facet mgs $LCTL barrier_thaw $FSNAME
28338
28339         post_801
28340 }
28341 run_test 801a "write barrier user interfaces and stat machine"
28342
28343 test_801b() {
28344         prep_801
28345
28346         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28347         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28348         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28349         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28350         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28351
28352         cancel_lru_locks mdc
28353
28354         # 180 seconds should be long enough
28355         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28356
28357         local b_status=$(barrier_stat)
28358         [ "$b_status" = "'frozen'" ] ||
28359                 error "(6) unexpected barrier status $b_status"
28360
28361         mkdir $DIR/$tdir/d0/d10 &
28362         mkdir_pid=$!
28363
28364         touch $DIR/$tdir/d1/f13 &
28365         touch_pid=$!
28366
28367         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28368         ln_pid=$!
28369
28370         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28371         mv_pid=$!
28372
28373         rm -f $DIR/$tdir/d4/f12 &
28374         rm_pid=$!
28375
28376         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28377
28378         # To guarantee taht the 'stat' is not blocked
28379         b_status=$(barrier_stat)
28380         [ "$b_status" = "'frozen'" ] ||
28381                 error "(8) unexpected barrier status $b_status"
28382
28383         # let above commands to run at background
28384         sleep 5
28385
28386         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28387         ps -p $touch_pid || error "(10) touch should be blocked"
28388         ps -p $ln_pid || error "(11) link should be blocked"
28389         ps -p $mv_pid || error "(12) rename should be blocked"
28390         ps -p $rm_pid || error "(13) unlink should be blocked"
28391
28392         b_status=$(barrier_stat)
28393         [ "$b_status" = "'frozen'" ] ||
28394                 error "(14) unexpected barrier status $b_status"
28395
28396         do_facet mgs $LCTL barrier_thaw $FSNAME
28397         b_status=$(barrier_stat)
28398         [ "$b_status" = "'thawed'" ] ||
28399                 error "(15) unexpected barrier status $b_status"
28400
28401         wait $mkdir_pid || error "(16) mkdir should succeed"
28402         wait $touch_pid || error "(17) touch should succeed"
28403         wait $ln_pid || error "(18) link should succeed"
28404         wait $mv_pid || error "(19) rename should succeed"
28405         wait $rm_pid || error "(20) unlink should succeed"
28406
28407         post_801
28408 }
28409 run_test 801b "modification will be blocked by write barrier"
28410
28411 test_801c() {
28412         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28413
28414         prep_801
28415
28416         stop mds2 || error "(1) Fail to stop mds2"
28417
28418         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28419
28420         local b_status=$(barrier_stat)
28421         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28422                 do_facet mgs $LCTL barrier_thaw $FSNAME
28423                 error "(2) unexpected barrier status $b_status"
28424         }
28425
28426         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28427                 error "(3) Fail to rescan barrier bitmap"
28428
28429         # Do not reduce barrier time - See LU-11873
28430         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28431
28432         b_status=$(barrier_stat)
28433         [ "$b_status" = "'frozen'" ] ||
28434                 error "(4) unexpected barrier status $b_status"
28435
28436         do_facet mgs $LCTL barrier_thaw $FSNAME
28437         b_status=$(barrier_stat)
28438         [ "$b_status" = "'thawed'" ] ||
28439                 error "(5) unexpected barrier status $b_status"
28440
28441         local devname=$(mdsdevname 2)
28442
28443         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28444
28445         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28446                 error "(7) Fail to rescan barrier bitmap"
28447
28448         post_801
28449 }
28450 run_test 801c "rescan barrier bitmap"
28451
28452 test_802b() {
28453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28454         remote_mds_nodsh && skip "remote MDS with nodsh"
28455
28456         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28457                 skip "readonly option not available"
28458
28459         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28460
28461         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28462                 error "(2) Fail to copy"
28463
28464         # write back all cached data before setting MDT to readonly
28465         cancel_lru_locks
28466         sync_all_data
28467
28468         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28469         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28470
28471         echo "Modify should be refused"
28472         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28473
28474         echo "Read should be allowed"
28475         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28476                 error "(7) Read should succeed under ro mode"
28477
28478         # disable readonly
28479         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28480 }
28481 run_test 802b "be able to set MDTs to readonly"
28482
28483 test_803a() {
28484         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28485         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28486                 skip "MDS needs to be newer than 2.10.54"
28487
28488         mkdir_on_mdt0 $DIR/$tdir
28489         # Create some objects on all MDTs to trigger related logs objects
28490         for idx in $(seq $MDSCOUNT); do
28491                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28492                         $DIR/$tdir/dir${idx} ||
28493                         error "Fail to create $DIR/$tdir/dir${idx}"
28494         done
28495
28496         wait_delete_completed # ensure old test cleanups are finished
28497         sleep 3
28498         echo "before create:"
28499         $LFS df -i $MOUNT
28500         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28501
28502         for i in {1..10}; do
28503                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28504                         error "Fail to create $DIR/$tdir/foo$i"
28505         done
28506
28507         # sync ZFS-on-MDS to refresh statfs data
28508         wait_zfs_commit mds1
28509         sleep 3
28510         echo "after create:"
28511         $LFS df -i $MOUNT
28512         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28513
28514         # allow for an llog to be cleaned up during the test
28515         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28516                 error "before ($before_used) + 10 > after ($after_used)"
28517
28518         for i in {1..10}; do
28519                 rm -rf $DIR/$tdir/foo$i ||
28520                         error "Fail to remove $DIR/$tdir/foo$i"
28521         done
28522
28523         # sync ZFS-on-MDS to refresh statfs data
28524         wait_zfs_commit mds1
28525         wait_delete_completed
28526         sleep 3 # avoid MDT return cached statfs
28527         echo "after unlink:"
28528         $LFS df -i $MOUNT
28529         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28530
28531         # allow for an llog to be created during the test
28532         [ $after_used -le $((before_used + 1)) ] ||
28533                 error "after ($after_used) > before ($before_used) + 1"
28534 }
28535 run_test 803a "verify agent object for remote object"
28536
28537 test_803b() {
28538         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28539         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28540                 skip "MDS needs to be newer than 2.13.56"
28541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28542
28543         for i in $(seq 0 $((MDSCOUNT - 1))); do
28544                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28545         done
28546
28547         local before=0
28548         local after=0
28549
28550         local tmp
28551
28552         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28553         for i in $(seq 0 $((MDSCOUNT - 1))); do
28554                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28555                         awk '/getattr/ { print $2 }')
28556                 before=$((before + tmp))
28557         done
28558         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28559         for i in $(seq 0 $((MDSCOUNT - 1))); do
28560                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28561                         awk '/getattr/ { print $2 }')
28562                 after=$((after + tmp))
28563         done
28564
28565         [ $before -eq $after ] || error "getattr count $before != $after"
28566 }
28567 run_test 803b "remote object can getattr from cache"
28568
28569 test_804() {
28570         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28571         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28572                 skip "MDS needs to be newer than 2.10.54"
28573         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28574
28575         mkdir -p $DIR/$tdir
28576         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28577                 error "Fail to create $DIR/$tdir/dir0"
28578
28579         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28580         local dev=$(mdsdevname 2)
28581
28582         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28583                 grep ${fid} || error "NOT found agent entry for dir0"
28584
28585         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28586                 error "Fail to create $DIR/$tdir/dir1"
28587
28588         touch $DIR/$tdir/dir1/foo0 ||
28589                 error "Fail to create $DIR/$tdir/dir1/foo0"
28590         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28591         local rc=0
28592
28593         for idx in $(seq $MDSCOUNT); do
28594                 dev=$(mdsdevname $idx)
28595                 do_facet mds${idx} \
28596                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28597                         grep ${fid} && rc=$idx
28598         done
28599
28600         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28601                 error "Fail to rename foo0 to foo1"
28602         if [ $rc -eq 0 ]; then
28603                 for idx in $(seq $MDSCOUNT); do
28604                         dev=$(mdsdevname $idx)
28605                         do_facet mds${idx} \
28606                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28607                         grep ${fid} && rc=$idx
28608                 done
28609         fi
28610
28611         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28612                 error "Fail to rename foo1 to foo2"
28613         if [ $rc -eq 0 ]; then
28614                 for idx in $(seq $MDSCOUNT); do
28615                         dev=$(mdsdevname $idx)
28616                         do_facet mds${idx} \
28617                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28618                         grep ${fid} && rc=$idx
28619                 done
28620         fi
28621
28622         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28623
28624         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28625                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28626         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28627                 error "Fail to rename foo2 to foo0"
28628         unlink $DIR/$tdir/dir1/foo0 ||
28629                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28630         rm -rf $DIR/$tdir/dir0 ||
28631                 error "Fail to rm $DIR/$tdir/dir0"
28632
28633         for idx in $(seq $MDSCOUNT); do
28634                 rc=0
28635
28636                 stop mds${idx}
28637                 dev=$(mdsdevname $idx)
28638                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28639                         rc=$?
28640                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28641                         error "mount mds$idx failed"
28642                 df $MOUNT > /dev/null 2>&1
28643
28644                 # e2fsck should not return error
28645                 [ $rc -eq 0 ] ||
28646                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28647         done
28648 }
28649 run_test 804 "verify agent entry for remote entry"
28650
28651 cleanup_805() {
28652         do_facet $SINGLEMDS zfs set quota=$old $fsset
28653         unlinkmany $DIR/$tdir/f- 1000000
28654         trap 0
28655 }
28656
28657 test_805() {
28658         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28659         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28660         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28661                 skip "netfree not implemented before 0.7"
28662         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28663                 skip "Need MDS version at least 2.10.57"
28664
28665         local fsset
28666         local freekb
28667         local usedkb
28668         local old
28669         local quota
28670         local pref="osd-zfs.$FSNAME-MDT0000."
28671
28672         # limit available space on MDS dataset to meet nospace issue
28673         # quickly. then ZFS 0.7.2 can use reserved space if asked
28674         # properly (using netfree flag in osd_declare_destroy()
28675         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28676         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28677                 gawk '{print $3}')
28678         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28679         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28680         let "usedkb=usedkb-freekb"
28681         let "freekb=freekb/2"
28682         if let "freekb > 5000"; then
28683                 let "freekb=5000"
28684         fi
28685         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28686         trap cleanup_805 EXIT
28687         mkdir_on_mdt0 $DIR/$tdir
28688         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28689                 error "Can't set PFL layout"
28690         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28691         rm -rf $DIR/$tdir || error "not able to remove"
28692         do_facet $SINGLEMDS zfs set quota=$old $fsset
28693         trap 0
28694 }
28695 run_test 805 "ZFS can remove from full fs"
28696
28697 # Size-on-MDS test
28698 check_lsom_data()
28699 {
28700         local file=$1
28701         local expect=$(stat -c %s $file)
28702
28703         check_lsom_size $1 $expect
28704
28705         local blocks=$($LFS getsom -b $file)
28706         expect=$(stat -c %b $file)
28707         [[ $blocks == $expect ]] ||
28708                 error "$file expected blocks: $expect, got: $blocks"
28709 }
28710
28711 check_lsom_size()
28712 {
28713         local size
28714         local expect=$2
28715
28716         cancel_lru_locks mdc
28717
28718         size=$($LFS getsom -s $1)
28719         [[ $size == $expect ]] ||
28720                 error "$file expected size: $expect, got: $size"
28721 }
28722
28723 test_806() {
28724         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28725                 skip "Need MDS version at least 2.11.52"
28726
28727         local bs=1048576
28728
28729         touch $DIR/$tfile || error "touch $tfile failed"
28730
28731         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28732         save_lustre_params client "llite.*.xattr_cache" > $save
28733         lctl set_param llite.*.xattr_cache=0
28734         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28735
28736         # single-threaded write
28737         echo "Test SOM for single-threaded write"
28738         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28739                 error "write $tfile failed"
28740         check_lsom_size $DIR/$tfile $bs
28741
28742         local num=32
28743         local size=$(($num * $bs))
28744         local offset=0
28745         local i
28746
28747         echo "Test SOM for single client multi-threaded($num) write"
28748         $TRUNCATE $DIR/$tfile 0
28749         for ((i = 0; i < $num; i++)); do
28750                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28751                 local pids[$i]=$!
28752                 offset=$((offset + $bs))
28753         done
28754         for (( i=0; i < $num; i++ )); do
28755                 wait ${pids[$i]}
28756         done
28757         check_lsom_size $DIR/$tfile $size
28758
28759         $TRUNCATE $DIR/$tfile 0
28760         for ((i = 0; i < $num; i++)); do
28761                 offset=$((offset - $bs))
28762                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28763                 local pids[$i]=$!
28764         done
28765         for (( i=0; i < $num; i++ )); do
28766                 wait ${pids[$i]}
28767         done
28768         check_lsom_size $DIR/$tfile $size
28769
28770         # multi-client writes
28771         num=$(get_node_count ${CLIENTS//,/ })
28772         size=$(($num * $bs))
28773         offset=0
28774         i=0
28775
28776         echo "Test SOM for multi-client ($num) writes"
28777         $TRUNCATE $DIR/$tfile 0
28778         for client in ${CLIENTS//,/ }; do
28779                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28780                 local pids[$i]=$!
28781                 i=$((i + 1))
28782                 offset=$((offset + $bs))
28783         done
28784         for (( i=0; i < $num; i++ )); do
28785                 wait ${pids[$i]}
28786         done
28787         check_lsom_size $DIR/$tfile $offset
28788
28789         i=0
28790         $TRUNCATE $DIR/$tfile 0
28791         for client in ${CLIENTS//,/ }; do
28792                 offset=$((offset - $bs))
28793                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28794                 local pids[$i]=$!
28795                 i=$((i + 1))
28796         done
28797         for (( i=0; i < $num; i++ )); do
28798                 wait ${pids[$i]}
28799         done
28800         check_lsom_size $DIR/$tfile $size
28801
28802         # verify truncate
28803         echo "Test SOM for truncate"
28804         $TRUNCATE $DIR/$tfile 1048576
28805         check_lsom_size $DIR/$tfile 1048576
28806         $TRUNCATE $DIR/$tfile 1234
28807         check_lsom_size $DIR/$tfile 1234
28808
28809         # verify SOM blocks count
28810         echo "Verify SOM block count"
28811         $TRUNCATE $DIR/$tfile 0
28812         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28813                 error "failed to write file $tfile"
28814         check_lsom_data $DIR/$tfile
28815 }
28816 run_test 806 "Verify Lazy Size on MDS"
28817
28818 test_807() {
28819         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28820         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28821                 skip "Need MDS version at least 2.11.52"
28822
28823         # Registration step
28824         changelog_register || error "changelog_register failed"
28825         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28826         changelog_users $SINGLEMDS | grep -q $cl_user ||
28827                 error "User $cl_user not found in changelog_users"
28828
28829         rm -rf $DIR/$tdir || error "rm $tdir failed"
28830         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28831         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28832         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28833         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28834                 error "truncate $tdir/trunc failed"
28835
28836         local bs=1048576
28837         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28838                 error "write $tfile failed"
28839
28840         # multi-client wirtes
28841         local num=$(get_node_count ${CLIENTS//,/ })
28842         local offset=0
28843         local i=0
28844
28845         echo "Test SOM for multi-client ($num) writes"
28846         touch $DIR/$tfile || error "touch $tfile failed"
28847         $TRUNCATE $DIR/$tfile 0
28848         for client in ${CLIENTS//,/ }; do
28849                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28850                 local pids[$i]=$!
28851                 i=$((i + 1))
28852                 offset=$((offset + $bs))
28853         done
28854         for (( i=0; i < $num; i++ )); do
28855                 wait ${pids[$i]}
28856         done
28857
28858         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28859         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28860         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28861         check_lsom_data $DIR/$tdir/trunc
28862         check_lsom_data $DIR/$tdir/single_dd
28863         check_lsom_data $DIR/$tfile
28864
28865         rm -rf $DIR/$tdir
28866         # Deregistration step
28867         changelog_deregister || error "changelog_deregister failed"
28868 }
28869 run_test 807 "verify LSOM syncing tool"
28870
28871 check_som_nologged()
28872 {
28873         local lines=$($LFS changelog $FSNAME-MDT0000 |
28874                 grep 'x=trusted.som' | wc -l)
28875         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28876 }
28877
28878 test_808() {
28879         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28880                 skip "Need MDS version at least 2.11.55"
28881
28882         # Registration step
28883         changelog_register || error "changelog_register failed"
28884
28885         touch $DIR/$tfile || error "touch $tfile failed"
28886         check_som_nologged
28887
28888         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28889                 error "write $tfile failed"
28890         check_som_nologged
28891
28892         $TRUNCATE $DIR/$tfile 1234
28893         check_som_nologged
28894
28895         $TRUNCATE $DIR/$tfile 1048576
28896         check_som_nologged
28897
28898         # Deregistration step
28899         changelog_deregister || error "changelog_deregister failed"
28900 }
28901 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28902
28903 check_som_nodata()
28904 {
28905         $LFS getsom $1
28906         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28907 }
28908
28909 test_809() {
28910         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28911                 skip "Need MDS version at least 2.11.56"
28912
28913         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28914                 error "failed to create DoM-only file $DIR/$tfile"
28915         touch $DIR/$tfile || error "touch $tfile failed"
28916         check_som_nodata $DIR/$tfile
28917
28918         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28919                 error "write $tfile failed"
28920         check_som_nodata $DIR/$tfile
28921
28922         $TRUNCATE $DIR/$tfile 1234
28923         check_som_nodata $DIR/$tfile
28924
28925         $TRUNCATE $DIR/$tfile 4097
28926         check_som_nodata $DIR/$file
28927 }
28928 run_test 809 "Verify no SOM xattr store for DoM-only files"
28929
28930 test_810() {
28931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28932         $GSS && skip_env "could not run with gss"
28933         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28934                 skip "OST < 2.12.58 doesn't align checksum"
28935
28936         set_checksums 1
28937         stack_trap "set_checksums $ORIG_CSUM" EXIT
28938         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28939
28940         local csum
28941         local before
28942         local after
28943         for csum in $CKSUM_TYPES; do
28944                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28945                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28946                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28947                         eval set -- $i
28948                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28949                         before=$(md5sum $DIR/$tfile)
28950                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28951                         after=$(md5sum $DIR/$tfile)
28952                         [ "$before" == "$after" ] ||
28953                                 error "$csum: $before != $after bs=$1 seek=$2"
28954                 done
28955         done
28956 }
28957 run_test 810 "partial page writes on ZFS (LU-11663)"
28958
28959 test_812a() {
28960         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28961                 skip "OST < 2.12.51 doesn't support this fail_loc"
28962
28963         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28964         # ensure ost1 is connected
28965         stat $DIR/$tfile >/dev/null || error "can't stat"
28966         wait_osc_import_state client ost1 FULL
28967         # no locks, no reqs to let the connection idle
28968         cancel_lru_locks osc
28969
28970         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28971 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28972         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28973         wait_osc_import_state client ost1 CONNECTING
28974         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28975
28976         stat $DIR/$tfile >/dev/null || error "can't stat file"
28977 }
28978 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28979
28980 test_812b() { # LU-12378
28981         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28982                 skip "OST < 2.12.51 doesn't support this fail_loc"
28983
28984         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28985         # ensure ost1 is connected
28986         stat $DIR/$tfile >/dev/null || error "can't stat"
28987         wait_osc_import_state client ost1 FULL
28988         # no locks, no reqs to let the connection idle
28989         cancel_lru_locks osc
28990
28991         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28992 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28993         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28994         wait_osc_import_state client ost1 CONNECTING
28995         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28996
28997         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28998         wait_osc_import_state client ost1 IDLE
28999 }
29000 run_test 812b "do not drop no resend request for idle connect"
29001
29002 test_812c() {
29003         local old
29004
29005         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29006
29007         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29008         $LFS getstripe $DIR/$tfile
29009         $LCTL set_param osc.*.idle_timeout=10
29010         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29011         # ensure ost1 is connected
29012         stat $DIR/$tfile >/dev/null || error "can't stat"
29013         wait_osc_import_state client ost1 FULL
29014         # no locks, no reqs to let the connection idle
29015         cancel_lru_locks osc
29016
29017 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29018         $LCTL set_param fail_loc=0x80000533
29019         sleep 15
29020         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29021 }
29022 run_test 812c "idle import vs lock enqueue race"
29023
29024 test_813() {
29025         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29026         [ -z "$file_heat_sav" ] && skip "no file heat support"
29027
29028         local readsample
29029         local writesample
29030         local readbyte
29031         local writebyte
29032         local readsample1
29033         local writesample1
29034         local readbyte1
29035         local writebyte1
29036
29037         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29038         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29039
29040         $LCTL set_param -n llite.*.file_heat=1
29041         echo "Turn on file heat"
29042         echo "Period second: $period_second, Decay percentage: $decay_pct"
29043
29044         echo "QQQQ" > $DIR/$tfile
29045         echo "QQQQ" > $DIR/$tfile
29046         echo "QQQQ" > $DIR/$tfile
29047         cat $DIR/$tfile > /dev/null
29048         cat $DIR/$tfile > /dev/null
29049         cat $DIR/$tfile > /dev/null
29050         cat $DIR/$tfile > /dev/null
29051
29052         local out=$($LFS heat_get $DIR/$tfile)
29053
29054         $LFS heat_get $DIR/$tfile
29055         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29056         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29057         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29058         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29059
29060         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29061         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29062         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29063         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29064
29065         sleep $((period_second + 3))
29066         echo "Sleep $((period_second + 3)) seconds..."
29067         # The recursion formula to calculate the heat of the file f is as
29068         # follow:
29069         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29070         # Where Hi is the heat value in the period between time points i*I and
29071         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29072         # to the weight of Ci.
29073         out=$($LFS heat_get $DIR/$tfile)
29074         $LFS heat_get $DIR/$tfile
29075         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29076         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29077         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29078         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29079
29080         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29081                 error "read sample ($readsample) is wrong"
29082         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29083                 error "write sample ($writesample) is wrong"
29084         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29085                 error "read bytes ($readbyte) is wrong"
29086         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29087                 error "write bytes ($writebyte) is wrong"
29088
29089         echo "QQQQ" > $DIR/$tfile
29090         echo "QQQQ" > $DIR/$tfile
29091         echo "QQQQ" > $DIR/$tfile
29092         cat $DIR/$tfile > /dev/null
29093         cat $DIR/$tfile > /dev/null
29094         cat $DIR/$tfile > /dev/null
29095         cat $DIR/$tfile > /dev/null
29096
29097         sleep $((period_second + 3))
29098         echo "Sleep $((period_second + 3)) seconds..."
29099
29100         out=$($LFS heat_get $DIR/$tfile)
29101         $LFS heat_get $DIR/$tfile
29102         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29103         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29104         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29105         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29106
29107         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29108                 4 * $decay_pct) / 100") -eq 1 ] ||
29109                 error "read sample ($readsample1) is wrong"
29110         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29111                 3 * $decay_pct) / 100") -eq 1 ] ||
29112                 error "write sample ($writesample1) is wrong"
29113         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29114                 20 * $decay_pct) / 100") -eq 1 ] ||
29115                 error "read bytes ($readbyte1) is wrong"
29116         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29117                 15 * $decay_pct) / 100") -eq 1 ] ||
29118                 error "write bytes ($writebyte1) is wrong"
29119
29120         echo "Turn off file heat for the file $DIR/$tfile"
29121         $LFS heat_set -o $DIR/$tfile
29122
29123         echo "QQQQ" > $DIR/$tfile
29124         echo "QQQQ" > $DIR/$tfile
29125         echo "QQQQ" > $DIR/$tfile
29126         cat $DIR/$tfile > /dev/null
29127         cat $DIR/$tfile > /dev/null
29128         cat $DIR/$tfile > /dev/null
29129         cat $DIR/$tfile > /dev/null
29130
29131         out=$($LFS heat_get $DIR/$tfile)
29132         $LFS heat_get $DIR/$tfile
29133         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29134         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29135         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29136         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29137
29138         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29139         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29140         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29141         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29142
29143         echo "Trun on file heat for the file $DIR/$tfile"
29144         $LFS heat_set -O $DIR/$tfile
29145
29146         echo "QQQQ" > $DIR/$tfile
29147         echo "QQQQ" > $DIR/$tfile
29148         echo "QQQQ" > $DIR/$tfile
29149         cat $DIR/$tfile > /dev/null
29150         cat $DIR/$tfile > /dev/null
29151         cat $DIR/$tfile > /dev/null
29152         cat $DIR/$tfile > /dev/null
29153
29154         out=$($LFS heat_get $DIR/$tfile)
29155         $LFS heat_get $DIR/$tfile
29156         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29157         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29158         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29159         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29160
29161         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29162         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29163         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29164         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29165
29166         $LFS heat_set -c $DIR/$tfile
29167         $LCTL set_param -n llite.*.file_heat=0
29168         echo "Turn off file heat support for the Lustre filesystem"
29169
29170         echo "QQQQ" > $DIR/$tfile
29171         echo "QQQQ" > $DIR/$tfile
29172         echo "QQQQ" > $DIR/$tfile
29173         cat $DIR/$tfile > /dev/null
29174         cat $DIR/$tfile > /dev/null
29175         cat $DIR/$tfile > /dev/null
29176         cat $DIR/$tfile > /dev/null
29177
29178         out=$($LFS heat_get $DIR/$tfile)
29179         $LFS heat_get $DIR/$tfile
29180         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29181         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29182         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29183         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29184
29185         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29186         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29187         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29188         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29189
29190         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29191         rm -f $DIR/$tfile
29192 }
29193 run_test 813 "File heat verfication"
29194
29195 test_814()
29196 {
29197         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29198         echo -n y >> $DIR/$tfile
29199         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29200         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29201 }
29202 run_test 814 "sparse cp works as expected (LU-12361)"
29203
29204 test_815()
29205 {
29206         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29207         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29208 }
29209 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29210
29211 test_816() {
29212         local ost1_imp=$(get_osc_import_name client ost1)
29213         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29214                          cut -d'.' -f2)
29215
29216         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29217         # ensure ost1 is connected
29218
29219         stat $DIR/$tfile >/dev/null || error "can't stat"
29220         wait_osc_import_state client ost1 FULL
29221         # no locks, no reqs to let the connection idle
29222         cancel_lru_locks osc
29223         lru_resize_disable osc
29224         local before
29225         local now
29226         before=$($LCTL get_param -n \
29227                  ldlm.namespaces.$imp_name.lru_size)
29228
29229         wait_osc_import_state client ost1 IDLE
29230         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29231         now=$($LCTL get_param -n \
29232               ldlm.namespaces.$imp_name.lru_size)
29233         [ $before == $now ] || error "lru_size changed $before != $now"
29234 }
29235 run_test 816 "do not reset lru_resize on idle reconnect"
29236
29237 cleanup_817() {
29238         umount $tmpdir
29239         exportfs -u localhost:$DIR/nfsexp
29240         rm -rf $DIR/nfsexp
29241 }
29242
29243 test_817() {
29244         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29245
29246         mkdir -p $DIR/nfsexp
29247         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29248                 error "failed to export nfs"
29249
29250         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29251         stack_trap cleanup_817 EXIT
29252
29253         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29254                 error "failed to mount nfs to $tmpdir"
29255
29256         cp /bin/true $tmpdir
29257         $DIR/nfsexp/true || error "failed to execute 'true' command"
29258 }
29259 run_test 817 "nfsd won't cache write lock for exec file"
29260
29261 test_818() {
29262         test_mkdir -i0 -c1 $DIR/$tdir
29263         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29264         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29265         stop $SINGLEMDS
29266
29267         # restore osp-syn threads
29268         stack_trap "fail $SINGLEMDS"
29269
29270         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29271         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29272         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29273                 error "start $SINGLEMDS failed"
29274         rm -rf $DIR/$tdir
29275
29276         local testid=$(echo $TESTNAME | tr '_' ' ')
29277
29278         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29279                 grep "run LFSCK" || error "run LFSCK is not suggested"
29280 }
29281 run_test 818 "unlink with failed llog"
29282
29283 test_819a() {
29284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29285         cancel_lru_locks osc
29286         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29287         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29288         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29289         rm -f $TDIR/$tfile
29290 }
29291 run_test 819a "too big niobuf in read"
29292
29293 test_819b() {
29294         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29295         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29297         cancel_lru_locks osc
29298         sleep 1
29299         rm -f $TDIR/$tfile
29300 }
29301 run_test 819b "too big niobuf in write"
29302
29303
29304 function test_820_start_ost() {
29305         sleep 5
29306
29307         for num in $(seq $OSTCOUNT); do
29308                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29309         done
29310 }
29311
29312 test_820() {
29313         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29314
29315         mkdir $DIR/$tdir
29316         umount_client $MOUNT || error "umount failed"
29317         for num in $(seq $OSTCOUNT); do
29318                 stop ost$num
29319         done
29320
29321         # mount client with no active OSTs
29322         # so that the client can't initialize max LOV EA size
29323         # from OSC notifications
29324         mount_client $MOUNT || error "mount failed"
29325         # delay OST starting to keep this 0 max EA size for a while
29326         test_820_start_ost &
29327
29328         # create a directory on MDS2
29329         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29330                 error "Failed to create directory"
29331         # open intent should update default EA size
29332         # see mdc_update_max_ea_from_body()
29333         # notice this is the very first RPC to MDS2
29334         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29335         ret=$?
29336         echo $out
29337         # With SSK, this situation can lead to -EPERM being returned.
29338         # In that case, simply retry.
29339         if [ $ret -ne 0 ] && $SHARED_KEY; then
29340                 if echo "$out" | grep -q "not permitted"; then
29341                         cp /etc/services $DIR/$tdir/mds2
29342                         ret=$?
29343                 fi
29344         fi
29345         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29346 }
29347 run_test 820 "update max EA from open intent"
29348
29349 test_823() {
29350         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29351         local OST_MAX_PRECREATE=20000
29352
29353         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29354                 skip "Need MDS version at least 2.14.56"
29355
29356         save_lustre_params mds1 \
29357                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29358         do_facet $SINGLEMDS "$LCTL set_param -n \
29359                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29360         do_facet $SINGLEMDS "$LCTL set_param -n \
29361                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29362
29363         stack_trap "restore_lustre_params < $p; rm $p"
29364
29365         do_facet $SINGLEMDS "$LCTL set_param -n \
29366                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29367
29368         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29369                       osp.$FSNAME-OST0000*MDT0000.create_count")
29370         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29371                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29372         local expect_count=$(((($max/2)/256) * 256))
29373
29374         log "setting create_count to 100200:"
29375         log " -result- count: $count with max: $max, expecting: $expect_count"
29376
29377         [[ $count -eq expect_count ]] ||
29378                 error "Create count not set to max precreate."
29379 }
29380 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29381
29382 test_831() {
29383         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29384                 skip "Need MDS version 2.14.56"
29385
29386         local sync_changes=$(do_facet $SINGLEMDS \
29387                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29388
29389         [ "$sync_changes" -gt 100 ] &&
29390                 skip "Sync changes $sync_changes > 100 already"
29391
29392         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29393
29394         $LFS mkdir -i 0 $DIR/$tdir
29395         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29396
29397         save_lustre_params mds1 \
29398                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29399         save_lustre_params mds1 \
29400                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29401
29402         do_facet mds1 "$LCTL set_param -n \
29403                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29404                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29405         stack_trap "restore_lustre_params < $p" EXIT
29406
29407         createmany -o $DIR/$tdir/f- 1000
29408         unlinkmany $DIR/$tdir/f- 1000 &
29409         local UNLINK_PID=$!
29410
29411         while sleep 1; do
29412                 sync_changes=$(do_facet mds1 \
29413                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29414                 # the check in the code is racy, fail the test
29415                 # if the value above the limit by 10.
29416                 [ $sync_changes -gt 110 ] && {
29417                         kill -2 $UNLINK_PID
29418                         wait
29419                         error "osp changes throttling failed, $sync_changes>110"
29420                 }
29421                 kill -0 $UNLINK_PID 2> /dev/null || break
29422         done
29423         wait
29424 }
29425 run_test 831 "throttling unlink/setattr queuing on OSP"
29426
29427 test_832() {
29428         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29429         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29430                 skip "Need MDS version 2.15.52+"
29431         is_rmentry_supported || skip "rm_entry not supported"
29432
29433         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29434         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29435         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29436                 error "mkdir remote_dir failed"
29437         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29438                 error "mkdir striped_dir failed"
29439         touch $DIR/$tdir/file || error "touch file failed"
29440         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29441         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29442 }
29443 run_test 832 "lfs rm_entry"
29444
29445 #
29446 # tests that do cleanup/setup should be run at the end
29447 #
29448
29449 test_900() {
29450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29451         local ls
29452
29453         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29454         $LCTL set_param fail_loc=0x903
29455
29456         cancel_lru_locks MGC
29457
29458         FAIL_ON_ERROR=true cleanup
29459         FAIL_ON_ERROR=true setup
29460 }
29461 run_test 900 "umount should not race with any mgc requeue thread"
29462
29463 # LUS-6253/LU-11185
29464 test_901() {
29465         local old
29466         local count
29467         local oldc
29468         local newc
29469         local olds
29470         local news
29471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29472
29473         # some get_param have a bug to handle dot in param name
29474         cancel_lru_locks MGC
29475         old=$(mount -t lustre | wc -l)
29476         # 1 config+sptlrpc
29477         # 2 params
29478         # 3 nodemap
29479         # 4 IR
29480         old=$((old * 4))
29481         oldc=0
29482         count=0
29483         while [ $old -ne $oldc ]; do
29484                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29485                 sleep 1
29486                 ((count++))
29487                 if [ $count -ge $TIMEOUT ]; then
29488                         error "too large timeout"
29489                 fi
29490         done
29491         umount_client $MOUNT || error "umount failed"
29492         mount_client $MOUNT || error "mount failed"
29493         cancel_lru_locks MGC
29494         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29495
29496         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29497
29498         return 0
29499 }
29500 run_test 901 "don't leak a mgc lock on client umount"
29501
29502 # LU-13377
29503 test_902() {
29504         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29505                 skip "client does not have LU-13377 fix"
29506         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29507         $LCTL set_param fail_loc=0x1415
29508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29509         cancel_lru_locks osc
29510         rm -f $DIR/$tfile
29511 }
29512 run_test 902 "test short write doesn't hang lustre"
29513
29514 # LU-14711
29515 test_903() {
29516         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29517         echo "blah" > $DIR/${tfile}-2
29518         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29519         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29520         $LCTL set_param fail_loc=0x417 fail_val=20
29521
29522         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29523         sleep 1 # To start the destroy
29524         wait_destroy_complete 150 || error "Destroy taking too long"
29525         cat $DIR/$tfile > /dev/null || error "Evicted"
29526 }
29527 run_test 903 "Test long page discard does not cause evictions"
29528
29529 test_904() {
29530         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29531         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29532                 grep -q project || skip "skip project quota not supported"
29533
29534         local testfile="$DIR/$tdir/$tfile"
29535         local xattr="trusted.projid"
29536         local projid
29537         local mdts=$(comma_list $(mdts_nodes))
29538         local saved=$(do_facet mds1 $LCTL get_param -n \
29539                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29540
29541         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29542         stack_trap "do_nodes $mdts $LCTL set_param \
29543                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29544
29545         mkdir -p $DIR/$tdir
29546         touch $testfile
29547         #hide projid xattr on server
29548         $LFS project -p 1 $testfile ||
29549                 error "set $testfile project id failed"
29550         getfattr -m - $testfile | grep $xattr &&
29551                 error "do not show trusted.projid when disabled on server"
29552         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29553         #should be hidden when projid is 0
29554         $LFS project -p 0 $testfile ||
29555                 error "set $testfile project id failed"
29556         getfattr -m - $testfile | grep $xattr &&
29557                 error "do not show trusted.projid with project ID 0"
29558
29559         #still can getxattr explicitly
29560         projid=$(getfattr -n $xattr $testfile |
29561                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29562         [ $projid == "0" ] ||
29563                 error "projid expected 0 not $projid"
29564
29565         #set the projid via setxattr
29566         setfattr -n $xattr -v "1000" $testfile ||
29567                 error "setattr failed with $?"
29568         projid=($($LFS project $testfile))
29569         [ ${projid[0]} == "1000" ] ||
29570                 error "projid expected 1000 not $projid"
29571
29572         #check the new projid via getxattr
29573         $LFS project -p 1001 $testfile ||
29574                 error "set $testfile project id failed"
29575         getfattr -m - $testfile | grep $xattr ||
29576                 error "should show trusted.projid when project ID != 0"
29577         projid=$(getfattr -n $xattr $testfile |
29578                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29579         [ $projid == "1001" ] ||
29580                 error "projid expected 1001 not $projid"
29581
29582         #try to set invalid projid
29583         setfattr -n $xattr -v "4294967295" $testfile &&
29584                 error "set invalid projid should fail"
29585
29586         #remove the xattr means setting projid to 0
29587         setfattr -x $xattr $testfile ||
29588                 error "setfattr failed with $?"
29589         projid=($($LFS project $testfile))
29590         [ ${projid[0]} == "0" ] ||
29591                 error "projid expected 0 not $projid"
29592
29593         #should be hidden when parent has inherit flag and same projid
29594         $LFS project -srp 1002 $DIR/$tdir ||
29595                 error "set $tdir project id failed"
29596         getfattr -m - $testfile | grep $xattr &&
29597                 error "do not show trusted.projid with inherit flag"
29598
29599         #still can getxattr explicitly
29600         projid=$(getfattr -n $xattr $testfile |
29601                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29602         [ $projid == "1002" ] ||
29603                 error "projid expected 1002 not $projid"
29604 }
29605 run_test 904 "virtual project ID xattr"
29606
29607 # LU-8582
29608 test_905() {
29609         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29610                 skip "lustre < 2.8.54 does not support ladvise"
29611
29612         remote_ost_nodsh && skip "remote OST with nodsh"
29613         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29614
29615         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29616
29617         #define OBD_FAIL_OST_OPCODE 0x253
29618         # OST_LADVISE = 21
29619         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29620         $LFS ladvise -a willread $DIR/$tfile &&
29621                 error "unexpected success of ladvise with fault injection"
29622         $LFS ladvise -a willread $DIR/$tfile |&
29623                 grep -q "Operation not supported"
29624         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29625 }
29626 run_test 905 "bad or new opcode should not stuck client"
29627
29628 test_906() {
29629         grep -q io_uring_setup /proc/kallsyms ||
29630                 skip "Client OS does not support io_uring I/O engine"
29631         io_uring_probe || skip "kernel does not support io_uring fully"
29632         which fio || skip_env "no fio installed"
29633         fio --enghelp | grep -q io_uring ||
29634                 skip_env "fio does not support io_uring I/O engine"
29635
29636         local file=$DIR/$tfile
29637         local ioengine="io_uring"
29638         local numjobs=2
29639         local size=50M
29640
29641         fio --name=seqwrite --ioengine=$ioengine        \
29642                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29643                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29644                 error "fio seqwrite $file failed"
29645
29646         fio --name=seqread --ioengine=$ioengine \
29647                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29648                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29649                 error "fio seqread $file failed"
29650
29651         rm -f $file || error "rm -f $file failed"
29652 }
29653 run_test 906 "Simple test for io_uring I/O engine via fio"
29654
29655 complete $SECONDS
29656 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29657 check_and_cleanup_lustre
29658 if [ "$I_MOUNTED" != "yes" ]; then
29659         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29660 fi
29661 exit_status