Whamcloud - gitweb
7cdee600efc8cb338f7e653b39aaf30b5cd2f966
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-14541 277
44 always_except LU-8411  407
45
46 if $SHARED_KEY; then
47         always_except LU-14181 64e 64f
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411
63 fi
64
65 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
66 # until the filemap_read() issue is fixed
67 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
68         always_except LU-16101 27J
69 fi
70
71 #                                  5              12     8   12  15   (min)"
72 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
73
74 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
75         #                                               13    (min)"
76         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
77 fi
78
79 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
80         always_except LU-1941 130b 130c 130d 130e 130f 130g
81         always_except LU-9054 312
82 fi
83
84 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
85
86 # Get the SLES distro version
87 #
88 # Returns a version string that should only be used in comparing
89 # strings returned by version_code()
90 sles_version_code()
91 {
92         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
93
94         # All SuSE Linux versions have one decimal. version_code expects two
95         local sles_version=$version.0
96         version_code $sles_version
97 }
98
99 # Check if we are running on Ubuntu or SLES so we can make decisions on
100 # what tests to run
101 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
102         sles_version=$(sles_version_code)
103         [ $sles_version -lt $(version_code 11.4.0) ] &&
104                 always_except LU-4341 170
105
106         [ $sles_version -lt $(version_code 12.0.0) ] &&
107                 always_except LU-3703 234
108
109         [ $sles_version -ge $(version_code 15.4.0) ] &&
110                 always_except LU-16101 27J
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         always_except LU-10366 410
120                 fi
121         fi
122 fi
123
124 build_test_filter
125 FAIL_ON_ERROR=false
126
127 cleanup() {
128         echo -n "cln.."
129         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
130         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
131 }
132 setup() {
133         echo -n "mnt.."
134         load_modules
135         setupall || exit 10
136         echo "done"
137 }
138
139 check_swap_layouts_support()
140 {
141         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
142                 skip "Does not support layout lock."
143 }
144
145 check_swap_layout_no_dom()
146 {
147         local FOLDER=$1
148         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
149         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
150 }
151
152 check_and_setup_lustre
153 DIR=${DIR:-$MOUNT}
154 assert_DIR
155
156 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
157
158 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
159 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
160 rm -rf $DIR/[Rdfs][0-9]*
161
162 # $RUNAS_ID may get set incorrectly somewhere else
163 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
164         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
165
166 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
167
168 if [ "${ONLY}" = "MOUNT" ] ; then
169         echo "Lustre is up, please go on"
170         exit
171 fi
172
173 echo "preparing for tests involving mounts"
174 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
175 touch $EXT2_DEV
176 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
177 echo # add a newline after mke2fs.
178
179 umask 077
180
181 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
182 lctl set_param debug=-1 2> /dev/null || true
183 test_0a() {
184         touch $DIR/$tfile
185         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
186         rm $DIR/$tfile
187         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
188 }
189 run_test 0a "touch; rm ====================="
190
191 test_0b() {
192         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
193         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
194 }
195 run_test 0b "chmod 0755 $DIR ============================="
196
197 test_0c() {
198         $LCTL get_param mdc.*.import | grep "state: FULL" ||
199                 error "import not FULL"
200         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
201                 error "bad target"
202 }
203 run_test 0c "check import proc"
204
205 test_0d() { # LU-3397
206         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
207                 skip "proc exports not supported before 2.10.57"
208
209         local mgs_exp="mgs.MGS.exports"
210         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
211         local exp_client_nid
212         local exp_client_version
213         local exp_val
214         local imp_val
215         local temp_imp=$DIR/$tfile.import
216         local temp_exp=$DIR/$tfile.export
217
218         # save mgc import file to $temp_imp
219         $LCTL get_param mgc.*.import | tee $temp_imp
220         # Check if client uuid is found in MGS export
221         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
222                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
223                         $client_uuid ] &&
224                         break;
225         done
226         # save mgs export file to $temp_exp
227         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
228
229         # Compare the value of field "connect_flags"
230         imp_val=$(grep "connect_flags" $temp_imp)
231         exp_val=$(grep "connect_flags" $temp_exp)
232         [ "$exp_val" == "$imp_val" ] ||
233                 error "export flags '$exp_val' != import flags '$imp_val'"
234
235         # Compare client versions.  Only compare top-3 fields for compatibility
236         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
237         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
238         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
239         [ "$exp_val" == "$imp_val" ] ||
240                 error "exp version '$exp_client_version'($exp_val) != " \
241                         "'$(lustre_build_version client)'($imp_val)"
242 }
243 run_test 0d "check export proc ============================="
244
245 test_0e() { # LU-13417
246         (( $MDSCOUNT > 1 )) ||
247                 skip "We need at least 2 MDTs for this test"
248
249         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
250                 skip "Need server version at least 2.14.51"
251
252         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
253         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
254
255         [ $default_lmv_count -eq 1 ] ||
256                 error "$MOUNT default stripe count $default_lmv_count"
257
258         [ $default_lmv_index -eq -1 ] ||
259                 error "$MOUNT default stripe index $default_lmv_index"
260
261         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
262         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
263
264         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
265         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
266
267         [ $mdt_index1 -eq $mdt_index2 ] &&
268                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
269
270         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
271 }
272 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
273
274 test_1() {
275         test_mkdir $DIR/$tdir
276         test_mkdir $DIR/$tdir/d2
277         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
278         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
279         rmdir $DIR/$tdir/d2
280         rmdir $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
282 }
283 run_test 1 "mkdir; remkdir; rmdir"
284
285 test_2() {
286         test_mkdir $DIR/$tdir
287         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
288         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
289         rm -r $DIR/$tdir
290         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
291 }
292 run_test 2 "mkdir; touch; rmdir; check file"
293
294 test_3() {
295         test_mkdir $DIR/$tdir
296         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
297         touch $DIR/$tdir/$tfile
298         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
299         rm -r $DIR/$tdir
300         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
301 }
302 run_test 3 "mkdir; touch; rmdir; check dir"
303
304 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
305 test_4() {
306         test_mkdir -i 1 $DIR/$tdir
307
308         touch $DIR/$tdir/$tfile ||
309                 error "Create file under remote directory failed"
310
311         rmdir $DIR/$tdir &&
312                 error "Expect error removing in-use dir $DIR/$tdir"
313
314         test -d $DIR/$tdir || error "Remote directory disappeared"
315
316         rm -rf $DIR/$tdir || error "remove remote dir error"
317 }
318 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
319
320 test_5() {
321         test_mkdir $DIR/$tdir
322         test_mkdir $DIR/$tdir/d2
323         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
324         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
325         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
326 }
327 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
328
329 test_6a() {
330         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
331         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
332         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
333                 error "$tfile does not have perm 0666 or UID $UID"
334         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
335         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
336                 error "$tfile should be 0666 and owned by UID $UID"
337 }
338 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
339
340 test_6c() {
341         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
342
343         touch $DIR/$tfile
344         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
345         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
346                 error "$tfile should be owned by UID $RUNAS_ID"
347         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
348         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
349                 error "$tfile should be owned by UID $RUNAS_ID"
350 }
351 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
352
353 test_6e() {
354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
355
356         touch $DIR/$tfile
357         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
358         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
359                 error "$tfile should be owned by GID $UID"
360         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
361         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
362                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
363 }
364 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
365
366 test_6g() {
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         test_mkdir $DIR/$tdir
370         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
371         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
372         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
373         test_mkdir $DIR/$tdir/d/subdir
374         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
375                 error "$tdir/d/subdir should be GID $RUNAS_GID"
376         if [[ $MDSCOUNT -gt 1 ]]; then
377                 # check remote dir sgid inherite
378                 $LFS mkdir -i 0 $DIR/$tdir.local ||
379                         error "mkdir $tdir.local failed"
380                 chmod g+s $DIR/$tdir.local ||
381                         error "chmod $tdir.local failed"
382                 chgrp $RUNAS_GID $DIR/$tdir.local ||
383                         error "chgrp $tdir.local failed"
384                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
385                         error "mkdir $tdir.remote failed"
386                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
387                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
388                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
389                         error "$tdir.remote should be mode 02755"
390         fi
391 }
392 run_test 6g "verify new dir in sgid dir inherits group"
393
394 test_6h() { # bug 7331
395         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
396
397         touch $DIR/$tfile || error "touch failed"
398         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
399         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
400                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
401         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
402                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
403 }
404 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
405
406 test_7a() {
407         test_mkdir $DIR/$tdir
408         $MCREATE $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tdir/$tfile should be mode 0666"
412 }
413 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
414
415 test_7b() {
416         if [ ! -d $DIR/$tdir ]; then
417                 test_mkdir $DIR/$tdir
418         fi
419         $MCREATE $DIR/$tdir/$tfile
420         echo -n foo > $DIR/$tdir/$tfile
421         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
422         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
423 }
424 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
425
426 test_8() {
427         test_mkdir $DIR/$tdir
428         touch $DIR/$tdir/$tfile
429         chmod 0666 $DIR/$tdir/$tfile
430         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
431                 error "$tfile mode not 0666"
432 }
433 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
434
435 test_9() {
436         test_mkdir $DIR/$tdir
437         test_mkdir $DIR/$tdir/d2
438         test_mkdir $DIR/$tdir/d2/d3
439         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
440 }
441 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
442
443 test_10() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         touch $DIR/$tdir/d2/$tfile
447         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
448                 error "$tdir/d2/$tfile not a file"
449 }
450 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
451
452 test_11() {
453         test_mkdir $DIR/$tdir
454         test_mkdir $DIR/$tdir/d2
455         chmod 0666 $DIR/$tdir/d2
456         chmod 0705 $DIR/$tdir/d2
457         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
458                 error "$tdir/d2 mode not 0705"
459 }
460 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
461
462 test_12() {
463         test_mkdir $DIR/$tdir
464         touch $DIR/$tdir/$tfile
465         chmod 0666 $DIR/$tdir/$tfile
466         chmod 0654 $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
468                 error "$tdir/d2 mode not 0654"
469 }
470 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
471
472 test_13() {
473         test_mkdir $DIR/$tdir
474         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
475         >  $DIR/$tdir/$tfile
476         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
477                 error "$tdir/$tfile size not 0 after truncate"
478 }
479 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
480
481 test_14() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         rm $DIR/$tdir/$tfile
485         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
486 }
487 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
488
489 test_15() {
490         test_mkdir $DIR/$tdir
491         touch $DIR/$tdir/$tfile
492         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
493         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
494                 error "$tdir/${tfile_2} not a file after rename"
495         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
496 }
497 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
498
499 test_16() {
500         test_mkdir $DIR/$tdir
501         touch $DIR/$tdir/$tfile
502         rm -rf $DIR/$tdir/$tfile
503         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
504 }
505 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
506
507 test_17a() {
508         test_mkdir $DIR/$tdir
509         touch $DIR/$tdir/$tfile
510         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
511         ls -l $DIR/$tdir
512         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
513                 error "$tdir/l-exist not a symlink"
514         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
515                 error "$tdir/l-exist not referencing a file"
516         rm -f $DIR/$tdir/l-exist
517         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
518 }
519 run_test 17a "symlinks: create, remove (real)"
520
521 test_17b() {
522         test_mkdir $DIR/$tdir
523         ln -s no-such-file $DIR/$tdir/l-dangle
524         ls -l $DIR/$tdir
525         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
526                 error "$tdir/l-dangle not referencing no-such-file"
527         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
528                 error "$tdir/l-dangle not referencing non-existent file"
529         rm -f $DIR/$tdir/l-dangle
530         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
531 }
532 run_test 17b "symlinks: create, remove (dangling)"
533
534 test_17c() { # bug 3440 - don't save failed open RPC for replay
535         test_mkdir $DIR/$tdir
536         ln -s foo $DIR/$tdir/$tfile
537         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
538 }
539 run_test 17c "symlinks: open dangling (should return error)"
540
541 test_17d() {
542         test_mkdir $DIR/$tdir
543         ln -s foo $DIR/$tdir/$tfile
544         touch $DIR/$tdir/$tfile || error "creating to new symlink"
545 }
546 run_test 17d "symlinks: create dangling"
547
548 test_17e() {
549         test_mkdir $DIR/$tdir
550         local foo=$DIR/$tdir/$tfile
551         ln -s $foo $foo || error "create symlink failed"
552         ls -l $foo || error "ls -l failed"
553         ls $foo && error "ls not failed" || true
554 }
555 run_test 17e "symlinks: create recursive symlink (should return error)"
556
557 test_17f() {
558         test_mkdir $DIR/$tdir
559         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
560         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
561         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
562         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
563         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
564         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
565         ls -l  $DIR/$tdir
566 }
567 run_test 17f "symlinks: long and very long symlink name"
568
569 # str_repeat(S, N) generate a string that is string S repeated N times
570 str_repeat() {
571         local s=$1
572         local n=$2
573         local ret=''
574         while [ $((n -= 1)) -ge 0 ]; do
575                 ret=$ret$s
576         done
577         echo $ret
578 }
579
580 # Long symlinks and LU-2241
581 test_17g() {
582         test_mkdir $DIR/$tdir
583         local TESTS="59 60 61 4094 4095"
584
585         # Fix for inode size boundary in 2.1.4
586         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
587                 TESTS="4094 4095"
588
589         # Patch not applied to 2.2 or 2.3 branches
590         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
591         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
592                 TESTS="4094 4095"
593
594         for i in $TESTS; do
595                 local SYMNAME=$(str_repeat 'x' $i)
596                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
597                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
598         done
599 }
600 run_test 17g "symlinks: really long symlink name and inode boundaries"
601
602 test_17h() { #bug 17378
603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
604         remote_mds_nodsh && skip "remote MDS with nodsh"
605
606         local mdt_idx
607
608         test_mkdir $DIR/$tdir
609         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
610         $LFS setstripe -c -1 $DIR/$tdir
611         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
612         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
613         touch $DIR/$tdir/$tfile || true
614 }
615 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
616
617 test_17i() { #bug 20018
618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
619         remote_mds_nodsh && skip "remote MDS with nodsh"
620
621         local foo=$DIR/$tdir/$tfile
622         local mdt_idx
623
624         test_mkdir -c1 $DIR/$tdir
625         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
626         ln -s $foo $foo || error "create symlink failed"
627 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
628         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
629         ls -l $foo && error "error not detected"
630         return 0
631 }
632 run_test 17i "don't panic on short symlink (should return error)"
633
634 test_17k() { #bug 22301
635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
636         [[ -z "$(which rsync 2>/dev/null)" ]] &&
637                 skip "no rsync command"
638         rsync --help | grep -q xattr ||
639                 skip_env "$(rsync --version | head -n1) does not support xattrs"
640         test_mkdir $DIR/$tdir
641         test_mkdir $DIR/$tdir.new
642         touch $DIR/$tdir/$tfile
643         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
644         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
645                 error "rsync failed with xattrs enabled"
646 }
647 run_test 17k "symlinks: rsync with xattrs enabled"
648
649 test_17l() { # LU-279
650         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
651                 skip "no getfattr command"
652
653         test_mkdir $DIR/$tdir
654         touch $DIR/$tdir/$tfile
655         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
656         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
657                 # -h to not follow symlinks. -m '' to list all the xattrs.
658                 # grep to remove first line: '# file: $path'.
659                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
660                 do
661                         lgetxattr_size_check $path $xattr ||
662                                 error "lgetxattr_size_check $path $xattr failed"
663                 done
664         done
665 }
666 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
667
668 # LU-1540
669 test_17m() {
670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
671         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
672         remote_mds_nodsh && skip "remote MDS with nodsh"
673         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
674         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
675                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
676
677         local short_sym="0123456789"
678         local wdir=$DIR/$tdir
679         local i
680
681         test_mkdir $wdir
682         long_sym=$short_sym
683         # create a long symlink file
684         for ((i = 0; i < 4; ++i)); do
685                 long_sym=${long_sym}${long_sym}
686         done
687
688         echo "create 512 short and long symlink files under $wdir"
689         for ((i = 0; i < 256; ++i)); do
690                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
691                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
692         done
693
694         echo "erase them"
695         rm -f $wdir/*
696         sync
697         wait_delete_completed
698
699         echo "recreate the 512 symlink files with a shorter string"
700         for ((i = 0; i < 512; ++i)); do
701                 # rewrite the symlink file with a shorter string
702                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
703                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
704         done
705
706         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
707
708         echo "stop and checking mds${mds_index}:"
709         # e2fsck should not return error
710         stop mds${mds_index}
711         local devname=$(mdsdevname $mds_index)
712         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
713         rc=$?
714
715         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
716                 error "start mds${mds_index} failed"
717         df $MOUNT > /dev/null 2>&1
718         [ $rc -eq 0 ] ||
719                 error "e2fsck detected error for short/long symlink: rc=$rc"
720         rm -f $wdir/*
721 }
722 run_test 17m "run e2fsck against MDT which contains short/long symlink"
723
724 check_fs_consistency_17n() {
725         local mdt_index
726         local rc=0
727
728         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
729         # so it only check MDT1/MDT2 instead of all of MDTs.
730         for mdt_index in 1 2; do
731                 # e2fsck should not return error
732                 stop mds${mdt_index}
733                 local devname=$(mdsdevname $mdt_index)
734                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
735                         rc=$((rc + $?))
736
737                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
738                         error "mount mds$mdt_index failed"
739                 df $MOUNT > /dev/null 2>&1
740         done
741         return $rc
742 }
743
744 test_17n() {
745         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
747         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
750         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
751                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
752
753         local i
754
755         test_mkdir $DIR/$tdir
756         for ((i=0; i<10; i++)); do
757                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
758                         error "create remote dir error $i"
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761         done
762
763         check_fs_consistency_17n ||
764                 error "e2fsck report error after create files under remote dir"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n ||
772                 error "e2fsck report error after unlink files under remote dir"
773
774         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
775                 skip "lustre < 2.4.50 does not support migrate mv"
776
777         for ((i = 0; i < 10; i++)); do
778                 mkdir -p $DIR/$tdir/remote_dir_${i}
779                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
780                         error "create files under remote dir failed $i"
781                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
782                         error "migrate remote dir error $i"
783         done
784         check_fs_consistency_17n || error "e2fsck report error after migration"
785
786         for ((i = 0; i < 10; i++)); do
787                 rm -rf $DIR/$tdir/remote_dir_${i} ||
788                         error "destroy remote dir error $i"
789         done
790
791         check_fs_consistency_17n || error "e2fsck report error after unlink"
792 }
793 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
794
795 test_17o() {
796         remote_mds_nodsh && skip "remote MDS with nodsh"
797         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
798                 skip "Need MDS version at least 2.3.64"
799
800         local wdir=$DIR/${tdir}o
801         local mdt_index
802         local rc=0
803
804         test_mkdir $wdir
805         touch $wdir/$tfile
806         mdt_index=$($LFS getstripe -m $wdir/$tfile)
807         mdt_index=$((mdt_index + 1))
808
809         cancel_lru_locks mdc
810         #fail mds will wait the failover finish then set
811         #following fail_loc to avoid interfer the recovery process.
812         fail mds${mdt_index}
813
814         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
815         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
816         ls -l $wdir/$tfile && rc=1
817         do_facet mds${mdt_index} lctl set_param fail_loc=0
818         [[ $rc -eq 0 ]] || error "stat file should fail"
819 }
820 run_test 17o "stat file with incompat LMA feature"
821
822 test_18() {
823         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
824         ls $DIR || error "Failed to ls $DIR: $?"
825 }
826 run_test 18 "touch .../f ; ls ... =============================="
827
828 test_19a() {
829         touch $DIR/$tfile
830         ls -l $DIR
831         rm $DIR/$tfile
832         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
833 }
834 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
835
836 test_19b() {
837         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
838 }
839 run_test 19b "ls -l .../f19 (should return error) =============="
840
841 test_19c() {
842         [ $RUNAS_ID -eq $UID ] &&
843                 skip_env "RUNAS_ID = UID = $UID -- skipping"
844
845         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
846 }
847 run_test 19c "$RUNAS touch .../f19 (should return error) =="
848
849 test_19d() {
850         cat $DIR/f19 && error || true
851 }
852 run_test 19d "cat .../f19 (should return error) =============="
853
854 test_20() {
855         touch $DIR/$tfile
856         rm $DIR/$tfile
857         touch $DIR/$tfile
858         rm $DIR/$tfile
859         touch $DIR/$tfile
860         rm $DIR/$tfile
861         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
862 }
863 run_test 20 "touch .../f ; ls -l ..."
864
865 test_21() {
866         test_mkdir $DIR/$tdir
867         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
868         ln -s dangle $DIR/$tdir/link
869         echo foo >> $DIR/$tdir/link
870         cat $DIR/$tdir/dangle
871         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
872         $CHECKSTAT -f -t file $DIR/$tdir/link ||
873                 error "$tdir/link not linked to a file"
874 }
875 run_test 21 "write to dangling link"
876
877 test_22() {
878         local wdir=$DIR/$tdir
879         test_mkdir $wdir
880         chown $RUNAS_ID:$RUNAS_GID $wdir
881         (cd $wdir || error "cd $wdir failed";
882                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
883                 $RUNAS tar xf -)
884         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
885         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
886         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
887                 error "checkstat -u failed"
888 }
889 run_test 22 "unpack tar archive as non-root user"
890
891 # was test_23
892 test_23a() {
893         test_mkdir $DIR/$tdir
894         local file=$DIR/$tdir/$tfile
895
896         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
897         openfile -f O_CREAT:O_EXCL $file &&
898                 error "$file recreate succeeded" || true
899 }
900 run_test 23a "O_CREAT|O_EXCL in subdir"
901
902 test_23b() { # bug 18988
903         test_mkdir $DIR/$tdir
904         local file=$DIR/$tdir/$tfile
905
906         rm -f $file
907         echo foo > $file || error "write filed"
908         echo bar >> $file || error "append filed"
909         $CHECKSTAT -s 8 $file || error "wrong size"
910         rm $file
911 }
912 run_test 23b "O_APPEND check"
913
914 # LU-9409, size with O_APPEND and tiny writes
915 test_23c() {
916         local file=$DIR/$tfile
917
918         # single dd
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
920         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
921         rm -f $file
922
923         # racing tiny writes
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
925         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
926         wait
927         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
928         rm -f $file
929
930         #racing tiny & normal writes
931         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
932         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
933         wait
934         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
935         rm -f $file
936
937         #racing tiny & normal writes 2, ugly numbers
938         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
939         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
940         wait
941         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
942         rm -f $file
943 }
944 run_test 23c "O_APPEND size checks for tiny writes"
945
946 # LU-11069 file offset is correct after appending writes
947 test_23d() {
948         local file=$DIR/$tfile
949         local offset
950
951         echo CentaurHauls > $file
952         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
953         if ((offset != 26)); then
954                 error "wrong offset, expected 26, got '$offset'"
955         fi
956 }
957 run_test 23d "file offset is correct after appending writes"
958
959 # rename sanity
960 test_24a() {
961         echo '-- same directory rename'
962         test_mkdir $DIR/$tdir
963         touch $DIR/$tdir/$tfile.1
964         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24a "rename file to non-existent target"
968
969 test_24b() {
970         test_mkdir $DIR/$tdir
971         touch $DIR/$tdir/$tfile.{1,2}
972         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
973         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
974         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
975 }
976 run_test 24b "rename file to existing target"
977
978 test_24c() {
979         test_mkdir $DIR/$tdir
980         test_mkdir $DIR/$tdir/d$testnum.1
981         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
982         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
983         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
984 }
985 run_test 24c "rename directory to non-existent target"
986
987 test_24d() {
988         test_mkdir -c1 $DIR/$tdir
989         test_mkdir -c1 $DIR/$tdir/d$testnum.1
990         test_mkdir -c1 $DIR/$tdir/d$testnum.2
991         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
992         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
993         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
994 }
995 run_test 24d "rename directory to existing target"
996
997 test_24e() {
998         echo '-- cross directory renames --'
999         test_mkdir $DIR/R5a
1000         test_mkdir $DIR/R5b
1001         touch $DIR/R5a/f
1002         mv $DIR/R5a/f $DIR/R5b/g
1003         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1004         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1005 }
1006 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1007
1008 test_24f() {
1009         test_mkdir $DIR/R6a
1010         test_mkdir $DIR/R6b
1011         touch $DIR/R6a/f $DIR/R6b/g
1012         mv $DIR/R6a/f $DIR/R6b/g
1013         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1014         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1015 }
1016 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1017
1018 test_24g() {
1019         test_mkdir $DIR/R7a
1020         test_mkdir $DIR/R7b
1021         test_mkdir $DIR/R7a/d
1022         mv $DIR/R7a/d $DIR/R7b/e
1023         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1024         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1025 }
1026 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1027
1028 test_24h() {
1029         test_mkdir -c1 $DIR/R8a
1030         test_mkdir -c1 $DIR/R8b
1031         test_mkdir -c1 $DIR/R8a/d
1032         test_mkdir -c1 $DIR/R8b/e
1033         mrename $DIR/R8a/d $DIR/R8b/e
1034         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1035         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1036 }
1037 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1038
1039 test_24i() {
1040         echo "-- rename error cases"
1041         test_mkdir $DIR/R9
1042         test_mkdir $DIR/R9/a
1043         touch $DIR/R9/f
1044         mrename $DIR/R9/f $DIR/R9/a
1045         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1046         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1047         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1048 }
1049 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1050
1051 test_24j() {
1052         test_mkdir $DIR/R10
1053         mrename $DIR/R10/f $DIR/R10/g
1054         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1055         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1056         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1057 }
1058 run_test 24j "source does not exist ============================"
1059
1060 test_24k() {
1061         test_mkdir $DIR/R11a
1062         test_mkdir $DIR/R11a/d
1063         touch $DIR/R11a/f
1064         mv $DIR/R11a/f $DIR/R11a/d
1065         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1066         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1067 }
1068 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1069
1070 # bug 2429 - rename foo foo foo creates invalid file
1071 test_24l() {
1072         f="$DIR/f24l"
1073         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1074 }
1075 run_test 24l "Renaming a file to itself ========================"
1076
1077 test_24m() {
1078         f="$DIR/f24m"
1079         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1080         # on ext3 this does not remove either the source or target files
1081         # though the "expected" operation would be to remove the source
1082         $CHECKSTAT -t file ${f} || error "${f} missing"
1083         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1084 }
1085 run_test 24m "Renaming a file to a hard link to itself ========="
1086
1087 test_24n() {
1088     f="$DIR/f24n"
1089     # this stats the old file after it was renamed, so it should fail
1090     touch ${f}
1091     $CHECKSTAT ${f} || error "${f} missing"
1092     mv ${f} ${f}.rename
1093     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1094     $CHECKSTAT -a ${f} || error "${f} exists"
1095 }
1096 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1097
1098 test_24o() {
1099         test_mkdir $DIR/$tdir
1100         rename_many -s random -v -n 10 $DIR/$tdir
1101 }
1102 run_test 24o "rename of files during htree split"
1103
1104 test_24p() {
1105         test_mkdir $DIR/R12a
1106         test_mkdir $DIR/R12b
1107         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1108         mrename $DIR/R12a $DIR/R12b
1109         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1110         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1111         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1112         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1113 }
1114 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1115
1116 cleanup_multiop_pause() {
1117         trap 0
1118         kill -USR1 $MULTIPID
1119 }
1120
1121 test_24q() {
1122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1123
1124         test_mkdir $DIR/R13a
1125         test_mkdir $DIR/R13b
1126         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1127         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1128         MULTIPID=$!
1129
1130         trap cleanup_multiop_pause EXIT
1131         mrename $DIR/R13a $DIR/R13b
1132         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1133         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1134         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1135         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1136         cleanup_multiop_pause
1137         wait $MULTIPID || error "multiop close failed"
1138 }
1139 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1140
1141 test_24r() { #bug 3789
1142         test_mkdir $DIR/R14a
1143         test_mkdir $DIR/R14a/b
1144         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1145         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1146         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1147 }
1148 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1149
1150 test_24s() {
1151         test_mkdir $DIR/R15a
1152         test_mkdir $DIR/R15a/b
1153         test_mkdir $DIR/R15a/b/c
1154         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1155         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1156         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1157 }
1158 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1159
1160 test_24t() {
1161         test_mkdir $DIR/R16a
1162         test_mkdir $DIR/R16a/b
1163         test_mkdir $DIR/R16a/b/c
1164         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1165         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1166         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1167 }
1168 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1169
1170 test_24u() { # bug12192
1171         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1172         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1173 }
1174 run_test 24u "create stripe file"
1175
1176 simple_cleanup_common() {
1177         local createmany=$1
1178         local rc=0
1179
1180         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1181
1182         local start=$SECONDS
1183
1184         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1185         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1186         rc=$?
1187         wait_delete_completed
1188         echo "cleanup time $((SECONDS - start))"
1189         return $rc
1190 }
1191
1192 max_pages_per_rpc() {
1193         local mdtname="$(printf "MDT%04x" ${1:-0})"
1194         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1195 }
1196
1197 test_24v() {
1198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1199
1200         local nrfiles=${COUNT:-100000}
1201         local fname="$DIR/$tdir/$tfile"
1202
1203         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1204         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1205
1206         test_mkdir "$(dirname $fname)"
1207         # assume MDT0000 has the fewest inodes
1208         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1209         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1210         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1211
1212         stack_trap "simple_cleanup_common $nrfiles"
1213
1214         createmany -m "$fname" $nrfiles
1215
1216         cancel_lru_locks mdc
1217         lctl set_param mdc.*.stats clear
1218
1219         # was previously test_24D: LU-6101
1220         # readdir() returns correct number of entries after cursor reload
1221         local num_ls=$(ls $DIR/$tdir | wc -l)
1222         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1223         local num_all=$(ls -a $DIR/$tdir | wc -l)
1224         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1225                 [ $num_all -ne $((nrfiles + 2)) ]; then
1226                         error "Expected $nrfiles files, got $num_ls " \
1227                                 "($num_uniq unique $num_all .&..)"
1228         fi
1229         # LU-5 large readdir
1230         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1231         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1232         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1233         # take into account of overhead in lu_dirpage header and end mark in
1234         # each page, plus one in rpc_num calculation.
1235         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1236         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1237         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1238         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1239         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1240         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1241         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1242         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1243                 error "large readdir doesn't take effect: " \
1244                       "$mds_readpage should be about $rpc_max"
1245 }
1246 run_test 24v "list large directory (test hash collision, b=17560)"
1247
1248 test_24w() { # bug21506
1249         SZ1=234852
1250         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1251         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1252         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1253         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1254         [[ "$SZ1" -eq "$SZ2" ]] ||
1255                 error "Error reading at the end of the file $tfile"
1256 }
1257 run_test 24w "Reading a file larger than 4Gb"
1258
1259 test_24x() {
1260         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1262         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1263                 skip "Need MDS version at least 2.7.56"
1264
1265         local MDTIDX=1
1266         local remote_dir=$DIR/$tdir/remote_dir
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $MDTIDX $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $DIR/$tdir/src_dir
1273         touch $DIR/$tdir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename dir cross MDT failed!"
1279
1280         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1281                 error "rename file cross MDT failed!"
1282
1283         touch $DIR/$tdir/ln_file
1284         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1285                 error "ln file cross MDT failed"
1286
1287         rm -rf $DIR/$tdir || error "Can not delete directories"
1288 }
1289 run_test 24x "cross MDT rename/link"
1290
1291 test_24y() {
1292         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1294
1295         local remote_dir=$DIR/$tdir/remote_dir
1296         local mdtidx=1
1297
1298         test_mkdir $DIR/$tdir
1299         $LFS mkdir -i $mdtidx $remote_dir ||
1300                 error "create remote directory failed"
1301
1302         test_mkdir $remote_dir/src_dir
1303         touch $remote_dir/src_file
1304         test_mkdir $remote_dir/tgt_dir
1305         touch $remote_dir/tgt_file
1306
1307         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1308                 error "rename subdir in the same remote dir failed!"
1309
1310         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1311                 error "rename files in the same remote dir failed!"
1312
1313         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1314                 error "link files in the same remote dir failed!"
1315
1316         rm -rf $DIR/$tdir || error "Can not delete directories"
1317 }
1318 run_test 24y "rename/link on the same dir should succeed"
1319
1320 test_24z() {
1321         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1322         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1323                 skip "Need MDS version at least 2.12.51"
1324
1325         local index
1326
1327         for index in 0 1; do
1328                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1329                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1330         done
1331
1332         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1333
1334         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1335         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1336
1337         local mdts=$(comma_list $(mdts_nodes))
1338
1339         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1340         stack_trap "do_nodes $mdts $LCTL \
1341                 set_param mdt.*.enable_remote_rename=1" EXIT
1342
1343         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1346         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1347 }
1348 run_test 24z "cross-MDT rename is done as cp"
1349
1350 test_24A() { # LU-3182
1351         local NFILES=5000
1352
1353         test_mkdir $DIR/$tdir
1354         stack_trap "simple_cleanup_common $NFILES"
1355         createmany -m $DIR/$tdir/$tfile $NFILES
1356         local t=$(ls $DIR/$tdir | wc -l)
1357         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1358         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1359
1360         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1361                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1362 }
1363 run_test 24A "readdir() returns correct number of entries."
1364
1365 test_24B() { # LU-4805
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         local count
1369
1370         test_mkdir $DIR/$tdir
1371         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1372                 error "create striped dir failed"
1373
1374         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1375         [ $count -eq 2 ] || error "Expected 2, got $count"
1376
1377         touch $DIR/$tdir/striped_dir/a
1378
1379         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1380         [ $count -eq 3 ] || error "Expected 3, got $count"
1381
1382         touch $DIR/$tdir/striped_dir/.f
1383
1384         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1385         [ $count -eq 4 ] || error "Expected 4, got $count"
1386
1387         rm -rf $DIR/$tdir || error "Can not delete directories"
1388 }
1389 run_test 24B "readdir for striped dir return correct number of entries"
1390
1391 test_24C() {
1392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1393
1394         mkdir $DIR/$tdir
1395         mkdir $DIR/$tdir/d0
1396         mkdir $DIR/$tdir/d1
1397
1398         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1399                 error "create striped dir failed"
1400
1401         cd $DIR/$tdir/d0/striped_dir
1402
1403         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1404         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1405         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1406
1407         [ "$d0_ino" = "$parent_ino" ] ||
1408                 error ".. wrong, expect $d0_ino, get $parent_ino"
1409
1410         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1411                 error "mv striped dir failed"
1412
1413         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1414
1415         [ "$d1_ino" = "$parent_ino" ] ||
1416                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1417 }
1418 run_test 24C "check .. in striped dir"
1419
1420 test_24E() {
1421         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1423
1424         mkdir -p $DIR/$tdir
1425         mkdir $DIR/$tdir/src_dir
1426         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1427                 error "create remote source failed"
1428
1429         touch $DIR/$tdir/src_dir/src_child/a
1430
1431         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1432                 error "create remote target dir failed"
1433
1434         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1435                 error "create remote target child failed"
1436
1437         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1438                 error "rename dir cross MDT failed!"
1439
1440         find $DIR/$tdir
1441
1442         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1443                 error "src_child still exists after rename"
1444
1445         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1446                 error "missing file(a) after rename"
1447
1448         rm -rf $DIR/$tdir || error "Can not delete directories"
1449 }
1450 run_test 24E "cross MDT rename/link"
1451
1452 test_24F () {
1453         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1454
1455         local repeats=1000
1456         [ "$SLOW" = "no" ] && repeats=100
1457
1458         mkdir -p $DIR/$tdir
1459
1460         echo "$repeats repeats"
1461         for ((i = 0; i < repeats; i++)); do
1462                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1463                 touch $DIR/$tdir/test/a || error "touch fails"
1464                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1465                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1466         done
1467
1468         true
1469 }
1470 run_test 24F "hash order vs readdir (LU-11330)"
1471
1472 test_24G () {
1473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1474
1475         local ino1
1476         local ino2
1477
1478         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1479         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1480         touch $DIR/$tdir-0/f1 || error "touch f1"
1481         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1482         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1483         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1484         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1485         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1486 }
1487 run_test 24G "migrate symlink in rename"
1488
1489 test_24H() {
1490         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1491         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1492                 skip "MDT1 should be on another node"
1493
1494         test_mkdir -i 1 -c 1 $DIR/$tdir
1495 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1496         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1497         touch $DIR/$tdir/$tfile || error "touch failed"
1498 }
1499 run_test 24H "repeat FLD_QUERY rpc"
1500
1501 test_25a() {
1502         echo '== symlink sanity ============================================='
1503
1504         test_mkdir $DIR/d25
1505         ln -s d25 $DIR/s25
1506         touch $DIR/s25/foo ||
1507                 error "File creation in symlinked directory failed"
1508 }
1509 run_test 25a "create file in symlinked directory ==============="
1510
1511 test_25b() {
1512         [ ! -d $DIR/d25 ] && test_25a
1513         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1514 }
1515 run_test 25b "lookup file in symlinked directory ==============="
1516
1517 test_26a() {
1518         test_mkdir $DIR/d26
1519         test_mkdir $DIR/d26/d26-2
1520         ln -s d26/d26-2 $DIR/s26
1521         touch $DIR/s26/foo || error "File creation failed"
1522 }
1523 run_test 26a "multiple component symlink ======================="
1524
1525 test_26b() {
1526         test_mkdir -p $DIR/$tdir/d26-2
1527         ln -s $tdir/d26-2/foo $DIR/s26-2
1528         touch $DIR/s26-2 || error "File creation failed"
1529 }
1530 run_test 26b "multiple component symlink at end of lookup ======"
1531
1532 test_26c() {
1533         test_mkdir $DIR/d26.2
1534         touch $DIR/d26.2/foo
1535         ln -s d26.2 $DIR/s26.2-1
1536         ln -s s26.2-1 $DIR/s26.2-2
1537         ln -s s26.2-2 $DIR/s26.2-3
1538         chmod 0666 $DIR/s26.2-3/foo
1539 }
1540 run_test 26c "chain of symlinks"
1541
1542 # recursive symlinks (bug 439)
1543 test_26d() {
1544         ln -s d26-3/foo $DIR/d26-3
1545 }
1546 run_test 26d "create multiple component recursive symlink"
1547
1548 test_26e() {
1549         [ ! -h $DIR/d26-3 ] && test_26d
1550         rm $DIR/d26-3
1551 }
1552 run_test 26e "unlink multiple component recursive symlink"
1553
1554 # recursive symlinks (bug 7022)
1555 test_26f() {
1556         test_mkdir $DIR/$tdir
1557         test_mkdir $DIR/$tdir/$tfile
1558         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1559         test_mkdir -p lndir/bar1
1560         test_mkdir $DIR/$tdir/$tfile/$tfile
1561         cd $tfile                || error "cd $tfile failed"
1562         ln -s .. dotdot          || error "ln dotdot failed"
1563         ln -s dotdot/lndir lndir || error "ln lndir failed"
1564         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1565         output=`ls $tfile/$tfile/lndir/bar1`
1566         [ "$output" = bar1 ] && error "unexpected output"
1567         rm -r $tfile             || error "rm $tfile failed"
1568         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1569 }
1570 run_test 26f "rm -r of a directory which has recursive symlink"
1571
1572 test_27a() {
1573         test_mkdir $DIR/$tdir
1574         $LFS getstripe $DIR/$tdir
1575         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1576         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1577         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1578 }
1579 run_test 27a "one stripe file"
1580
1581 test_27b() {
1582         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1583
1584         test_mkdir $DIR/$tdir
1585         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1586         $LFS getstripe -c $DIR/$tdir/$tfile
1587         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1588                 error "two-stripe file doesn't have two stripes"
1589
1590         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1591 }
1592 run_test 27b "create and write to two stripe file"
1593
1594 # 27c family tests specific striping, setstripe -o
1595 test_27ca() {
1596         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="1"
1599
1600         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1601         $LFS getstripe -i $DIR/$tdir/$tfile
1602         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1603                 error "stripe not on specified OST"
1604
1605         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1606 }
1607 run_test 27ca "one stripe on specified OST"
1608
1609 test_27cb() {
1610         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1611         test_mkdir -p $DIR/$tdir
1612         local osts="1,0"
1613         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1614         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1615         echo "$getstripe"
1616
1617         # Strip getstripe output to a space separated list of OSTs
1618         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1619                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1620         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1621                 error "stripes not on specified OSTs"
1622
1623         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1624 }
1625 run_test 27cb "two stripes on specified OSTs"
1626
1627 test_27cc() {
1628         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1629         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1630                 skip "server does not support overstriping"
1631
1632         test_mkdir -p $DIR/$tdir
1633         local osts="0,0"
1634         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1635         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1636         echo "$getstripe"
1637
1638         # Strip getstripe output to a space separated list of OSTs
1639         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1640                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1641         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1642                 error "stripes not on specified OSTs"
1643
1644         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1645 }
1646 run_test 27cc "two stripes on the same OST"
1647
1648 test_27cd() {
1649         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1650         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1651                 skip "server does not support overstriping"
1652         test_mkdir -p $DIR/$tdir
1653         local osts="0,1,1,0"
1654         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1655         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1656         echo "$getstripe"
1657
1658         # Strip getstripe output to a space separated list of OSTs
1659         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1660                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1661         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1662                 error "stripes not on specified OSTs"
1663
1664         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1665 }
1666 run_test 27cd "four stripes on two OSTs"
1667
1668 test_27ce() {
1669         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1670                 skip_env "too many osts, skipping"
1671         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1672                 skip "server does not support overstriping"
1673         # We do one more stripe than we have OSTs
1674         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1675                 skip_env "ea_inode feature disabled"
1676
1677         test_mkdir -p $DIR/$tdir
1678         local osts=""
1679         for i in $(seq 0 $OSTCOUNT);
1680         do
1681                 osts=$osts"0"
1682                 if [ $i -ne $OSTCOUNT ]; then
1683                         osts=$osts","
1684                 fi
1685         done
1686         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1687         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1688         echo "$getstripe"
1689
1690         # Strip getstripe output to a space separated list of OSTs
1691         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1692                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1693         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1694                 error "stripes not on specified OSTs"
1695
1696         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1697 }
1698 run_test 27ce "more stripes than OSTs with -o"
1699
1700 test_27cf() {
1701         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1702         local pid=0
1703
1704         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1705         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1706         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1707         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1708                 error "failed to set $osp_proc=0"
1709
1710         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1711         pid=$!
1712         sleep 1
1713         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1714         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1715                 error "failed to set $osp_proc=1"
1716         wait $pid
1717         [[ $pid -ne 0 ]] ||
1718                 error "should return error due to $osp_proc=0"
1719 }
1720 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1721
1722 test_27cg() {
1723         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1724                 skip "server does not support overstriping"
1725         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1726         large_xattr_enabled || skip_env "ea_inode feature disabled"
1727
1728         local osts="0"
1729
1730         for ((i=1;i<1000;i++)); do
1731                 osts+=",$((i % OSTCOUNT))"
1732         done
1733
1734         local mdts=$(comma_list $(mdts_nodes))
1735         local before=$(do_nodes $mdts \
1736                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1737                 awk '/many credits/{print $3}' |
1738                 calc_sum)
1739
1740         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1741         $LFS getstripe $DIR/$tfile | grep stripe
1742
1743         rm -f $DIR/$tfile || error "can't unlink"
1744
1745         after=$(do_nodes $mdts \
1746                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1747                 awk '/many credits/{print $3}' |
1748                 calc_sum)
1749
1750         (( before == after )) ||
1751                 error "too many credits happened: $after > $before"
1752 }
1753 run_test 27cg "1000 shouldn't cause too many credits"
1754
1755 test_27d() {
1756         test_mkdir $DIR/$tdir
1757         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1758                 error "setstripe failed"
1759         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1760         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1761 }
1762 run_test 27d "create file with default settings"
1763
1764 test_27e() {
1765         # LU-5839 adds check for existed layout before setting it
1766         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1767                 skip "Need MDS version at least 2.7.56"
1768
1769         test_mkdir $DIR/$tdir
1770         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1771         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1772         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1773 }
1774 run_test 27e "setstripe existing file (should return error)"
1775
1776 test_27f() {
1777         test_mkdir $DIR/$tdir
1778         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1779                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1780         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1781                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1782         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1783         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1784 }
1785 run_test 27f "setstripe with bad stripe size (should return error)"
1786
1787 test_27g() {
1788         test_mkdir $DIR/$tdir
1789         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1790         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1791                 error "$DIR/$tdir/$tfile has object"
1792 }
1793 run_test 27g "$LFS getstripe with no objects"
1794
1795 test_27ga() {
1796         test_mkdir $DIR/$tdir
1797         touch $DIR/$tdir/$tfile || error "touch failed"
1798         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1799         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1800         local rc=$?
1801         (( rc == 2 )) || error "getstripe did not return ENOENT"
1802 }
1803 run_test 27ga "$LFS getstripe with missing file (should return error)"
1804
1805 test_27i() {
1806         test_mkdir $DIR/$tdir
1807         touch $DIR/$tdir/$tfile || error "touch failed"
1808         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1809                 error "missing objects"
1810 }
1811 run_test 27i "$LFS getstripe with some objects"
1812
1813 test_27j() {
1814         test_mkdir $DIR/$tdir
1815         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1816                 error "setstripe failed" || true
1817 }
1818 run_test 27j "setstripe with bad stripe offset (should return error)"
1819
1820 test_27k() { # bug 2844
1821         test_mkdir $DIR/$tdir
1822         local file=$DIR/$tdir/$tfile
1823         local ll_max_blksize=$((4 * 1024 * 1024))
1824         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1825         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1826         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1827         dd if=/dev/zero of=$file bs=4k count=1
1828         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1829         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1830 }
1831 run_test 27k "limit i_blksize for broken user apps"
1832
1833 test_27l() {
1834         mcreate $DIR/$tfile || error "creating file"
1835         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1836                 error "setstripe should have failed" || true
1837 }
1838 run_test 27l "check setstripe permissions (should return error)"
1839
1840 test_27m() {
1841         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1842
1843         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1844                 skip_env "multiple clients -- skipping"
1845
1846         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1847                    head -n1)
1848         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1849                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1850         fi
1851         stack_trap simple_cleanup_common
1852         test_mkdir $DIR/$tdir
1853         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1854         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1855                 error "dd should fill OST0"
1856         i=2
1857         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1858                 i=$((i + 1))
1859                 [ $i -gt 256 ] && break
1860         done
1861         i=$((i + 1))
1862         touch $DIR/$tdir/$tfile.$i
1863         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1864             awk '{print $1}'| grep -w "0") ] &&
1865                 error "OST0 was full but new created file still use it"
1866         i=$((i + 1))
1867         touch $DIR/$tdir/$tfile.$i
1868         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1869             awk '{print $1}'| grep -w "0") ] &&
1870                 error "OST0 was full but new created file still use it" || true
1871 }
1872 run_test 27m "create file while OST0 was full"
1873
1874 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1875 # if the OST isn't full anymore.
1876 reset_enospc() {
1877         local ostidx=${1:-""}
1878         local delay
1879         local ready
1880         local get_prealloc
1881
1882         local list=$(comma_list $(osts_nodes))
1883         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1884
1885         do_nodes $list lctl set_param fail_loc=0
1886         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1887         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1888                 awk '{print $1 * 2;exit;}')
1889         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1890                         grep -v \"^0$\""
1891         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1892 }
1893
1894 test_27n() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_precreations 0 0x80000215
1903         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1904         touch $DIR/$tdir/$tfile || error "touch failed"
1905         $LFS getstripe $DIR/$tdir/$tfile
1906         reset_enospc
1907 }
1908 run_test 27n "create file with some full OSTs"
1909
1910 test_27o() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_all_precreations 0x215
1919
1920         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1921
1922         reset_enospc
1923         rm -rf $DIR/$tdir/*
1924 }
1925 run_test 27o "create file with all full OSTs (should error)"
1926
1927 function create_and_checktime() {
1928         local fname=$1
1929         local loops=$2
1930         local i
1931
1932         for ((i=0; i < $loops; i++)); do
1933                 local start=$SECONDS
1934                 multiop $fname-$i Oc
1935                 ((SECONDS-start < TIMEOUT)) ||
1936                         error "creation took " $((SECONDS-$start)) && return 1
1937         done
1938 }
1939
1940 test_27oo() {
1941         local mdts=$(comma_list $(mdts_nodes))
1942
1943         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1944                 skip "Need MDS version at least 2.13.57"
1945
1946         local f0=$DIR/${tfile}-0
1947         local f1=$DIR/${tfile}-1
1948
1949         wait_delete_completed
1950
1951         # refill precreated objects
1952         $LFS setstripe -i0 -c1 $f0
1953
1954         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1955         # force QoS allocation policy
1956         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1957         stack_trap "do_nodes $mdts $LCTL set_param \
1958                 lov.*.qos_threshold_rr=$saved" EXIT
1959         sleep_maxage
1960
1961         # one OST is unavailable, but still have few objects preallocated
1962         stop ost1
1963         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1964                 rm -rf $f1 $DIR/$tdir*" EXIT
1965
1966         for ((i=0; i < 7; i++)); do
1967                 mkdir $DIR/$tdir$i || error "can't create dir"
1968                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1969                         error "can't set striping"
1970         done
1971         for ((i=0; i < 7; i++)); do
1972                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1973         done
1974         wait
1975 }
1976 run_test 27oo "don't let few threads to reserve too many objects"
1977
1978 test_27p() {
1979         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1981         remote_mds_nodsh && skip "remote MDS with nodsh"
1982         remote_ost_nodsh && skip "remote OST with nodsh"
1983
1984         reset_enospc
1985         rm -f $DIR/$tdir/$tfile
1986         test_mkdir $DIR/$tdir
1987
1988         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1989         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1990         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1991
1992         exhaust_precreations 0 0x80000215
1993         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1994         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1995         $LFS getstripe $DIR/$tdir/$tfile
1996
1997         reset_enospc
1998 }
1999 run_test 27p "append to a truncated file with some full OSTs"
2000
2001 test_27q() {
2002         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2004         remote_mds_nodsh && skip "remote MDS with nodsh"
2005         remote_ost_nodsh && skip "remote OST with nodsh"
2006
2007         reset_enospc
2008         rm -f $DIR/$tdir/$tfile
2009
2010         mkdir_on_mdt0 $DIR/$tdir
2011         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2012         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2013                 error "truncate $DIR/$tdir/$tfile failed"
2014         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2015
2016         exhaust_all_precreations 0x215
2017
2018         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2019         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27q "append to truncated file with all OSTs full (should error)"
2024
2025 test_27r() {
2026         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2028         remote_mds_nodsh && skip "remote MDS with nodsh"
2029         remote_ost_nodsh && skip "remote OST with nodsh"
2030
2031         reset_enospc
2032         rm -f $DIR/$tdir/$tfile
2033         exhaust_precreations 0 0x80000215
2034
2035         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2040
2041 test_27s() { # bug 10725
2042         test_mkdir $DIR/$tdir
2043         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2044         local stripe_count=0
2045         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2046         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2047                 error "stripe width >= 2^32 succeeded" || true
2048
2049 }
2050 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2051
2052 test_27t() { # bug 10864
2053         WDIR=$(pwd)
2054         WLFS=$(which lfs)
2055         cd $DIR
2056         touch $tfile
2057         $WLFS getstripe $tfile
2058         cd $WDIR
2059 }
2060 run_test 27t "check that utils parse path correctly"
2061
2062 test_27u() { # bug 4900
2063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2064         remote_mds_nodsh && skip "remote MDS with nodsh"
2065
2066         local index
2067         local list=$(comma_list $(mdts_nodes))
2068
2069 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2070         do_nodes $list $LCTL set_param fail_loc=0x139
2071         test_mkdir -p $DIR/$tdir
2072         stack_trap "simple_cleanup_common 1000"
2073         createmany -o $DIR/$tdir/$tfile 1000
2074         do_nodes $list $LCTL set_param fail_loc=0
2075
2076         TLOG=$TMP/$tfile.getstripe
2077         $LFS getstripe $DIR/$tdir > $TLOG
2078         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2079         [[ $OBJS -gt 0 ]] &&
2080                 error "$OBJS objects created on OST-0. See $TLOG" ||
2081                 rm -f $TLOG
2082 }
2083 run_test 27u "skip object creation on OSC w/o objects"
2084
2085 test_27v() { # bug 4900
2086         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2088         remote_mds_nodsh && skip "remote MDS with nodsh"
2089         remote_ost_nodsh && skip "remote OST with nodsh"
2090
2091         exhaust_all_precreations 0x215
2092         reset_enospc
2093
2094         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2095
2096         touch $DIR/$tdir/$tfile
2097         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2098         # all except ost1
2099         for (( i=1; i < OSTCOUNT; i++ )); do
2100                 do_facet ost$i lctl set_param fail_loc=0x705
2101         done
2102         local START=`date +%s`
2103         createmany -o $DIR/$tdir/$tfile 32
2104
2105         local FINISH=`date +%s`
2106         local TIMEOUT=`lctl get_param -n timeout`
2107         local PROCESS=$((FINISH - START))
2108         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2109                error "$FINISH - $START >= $TIMEOUT / 2"
2110         sleep $((TIMEOUT / 2 - PROCESS))
2111         reset_enospc
2112 }
2113 run_test 27v "skip object creation on slow OST"
2114
2115 test_27w() { # bug 10997
2116         test_mkdir $DIR/$tdir
2117         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2118         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2119                 error "stripe size $size != 65536" || true
2120         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2121                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2122 }
2123 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2124
2125 test_27wa() {
2126         [[ $OSTCOUNT -lt 2 ]] &&
2127                 skip_env "skipping multiple stripe count/offset test"
2128
2129         test_mkdir $DIR/$tdir
2130         for i in $(seq 1 $OSTCOUNT); do
2131                 offset=$((i - 1))
2132                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2133                         error "setstripe -c $i -i $offset failed"
2134                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2135                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2136                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2137                 [ $index -ne $offset ] &&
2138                         error "stripe offset $index != $offset" || true
2139         done
2140 }
2141 run_test 27wa "check $LFS setstripe -c -i options"
2142
2143 test_27x() {
2144         remote_ost_nodsh && skip "remote OST with nodsh"
2145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2147
2148         OFFSET=$(($OSTCOUNT - 1))
2149         OSTIDX=0
2150         local OST=$(ostname_from_index $OSTIDX)
2151
2152         test_mkdir $DIR/$tdir
2153         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2154         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2155         sleep_maxage
2156         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2157         for i in $(seq 0 $OFFSET); do
2158                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2159                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2160                 error "OST0 was degraded but new created file still use it"
2161         done
2162         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2163 }
2164 run_test 27x "create files while OST0 is degraded"
2165
2166 test_27y() {
2167         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2168         remote_mds_nodsh && skip "remote MDS with nodsh"
2169         remote_ost_nodsh && skip "remote OST with nodsh"
2170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2171
2172         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2173         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2174                 osp.$mdtosc.prealloc_last_id)
2175         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2176                 osp.$mdtosc.prealloc_next_id)
2177         local fcount=$((last_id - next_id))
2178         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2179         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2180
2181         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2182                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2183         local OST_DEACTIVE_IDX=-1
2184         local OSC
2185         local OSTIDX
2186         local OST
2187
2188         for OSC in $MDS_OSCS; do
2189                 OST=$(osc_to_ost $OSC)
2190                 OSTIDX=$(index_from_ostuuid $OST)
2191                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2192                         OST_DEACTIVE_IDX=$OSTIDX
2193                 fi
2194                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2195                         echo $OSC "is Deactivated:"
2196                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2197                 fi
2198         done
2199
2200         OSTIDX=$(index_from_ostuuid $OST)
2201         test_mkdir $DIR/$tdir
2202         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2208                         echo $OST "is degraded:"
2209                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2210                                                 obdfilter.$OST.degraded=1
2211                 fi
2212         done
2213
2214         sleep_maxage
2215         createmany -o $DIR/$tdir/$tfile $fcount
2216
2217         for OSC in $MDS_OSCS; do
2218                 OST=$(osc_to_ost $OSC)
2219                 OSTIDX=$(index_from_ostuuid $OST)
2220                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2221                         echo $OST "is recovered from degraded:"
2222                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2223                                                 obdfilter.$OST.degraded=0
2224                 else
2225                         do_facet $SINGLEMDS lctl --device %$OSC activate
2226                 fi
2227         done
2228
2229         # all osp devices get activated, hence -1 stripe count restored
2230         local stripe_count=0
2231
2232         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2233         # devices get activated.
2234         sleep_maxage
2235         $LFS setstripe -c -1 $DIR/$tfile
2236         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2237         rm -f $DIR/$tfile
2238         [ $stripe_count -ne $OSTCOUNT ] &&
2239                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2240         return 0
2241 }
2242 run_test 27y "create files while OST0 is degraded and the rest inactive"
2243
2244 check_seq_oid()
2245 {
2246         log "check file $1"
2247
2248         lmm_count=$($LFS getstripe -c $1)
2249         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2250         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2251
2252         local old_ifs="$IFS"
2253         IFS=$'[:]'
2254         fid=($($LFS path2fid $1))
2255         IFS="$old_ifs"
2256
2257         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2258         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2259
2260         # compare lmm_seq and lu_fid->f_seq
2261         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2262         # compare lmm_object_id and lu_fid->oid
2263         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2264
2265         # check the trusted.fid attribute of the OST objects of the file
2266         local have_obdidx=false
2267         local stripe_nr=0
2268         $LFS getstripe $1 | while read obdidx oid hex seq; do
2269                 # skip lines up to and including "obdidx"
2270                 [ -z "$obdidx" ] && break
2271                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2272                 $have_obdidx || continue
2273
2274                 local ost=$((obdidx + 1))
2275                 local dev=$(ostdevname $ost)
2276                 local oid_hex
2277
2278                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2279
2280                 seq=$(echo $seq | sed -e "s/^0x//g")
2281                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2282                         oid_hex=$(echo $oid)
2283                 else
2284                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2285                 fi
2286                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2287
2288                 local ff=""
2289                 #
2290                 # Don't unmount/remount the OSTs if we don't need to do that.
2291                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2292                 # update too, until that use mount/ll_decode_filter_fid/mount.
2293                 # Re-enable when debugfs will understand new filter_fid.
2294                 #
2295                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2296                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2297                                 $dev 2>/dev/null" | grep "parent=")
2298                 fi
2299                 if [ -z "$ff" ]; then
2300                         stop ost$ost
2301                         mount_fstype ost$ost
2302                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2303                                 $(facet_mntpt ost$ost)/$obj_file)
2304                         unmount_fstype ost$ost
2305                         start ost$ost $dev $OST_MOUNT_OPTS
2306                         clients_up
2307                 fi
2308
2309                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2310
2311                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2312
2313                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2314                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2315                 #
2316                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2317                 #       stripe_size=1048576 component_id=1 component_start=0 \
2318                 #       component_end=33554432
2319                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2320                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2321                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2322                 local ff_pstripe
2323                 if grep -q 'stripe=' <<<$ff; then
2324                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2325                 else
2326                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2327                         # into f_ver in this case.  See comment on ff_parent.
2328                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2329                 fi
2330
2331                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2332                 [ $ff_pseq = $lmm_seq ] ||
2333                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2334                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2335                 [ $ff_poid = $lmm_oid ] ||
2336                         error "FF parent OID $ff_poid != $lmm_oid"
2337                 (($ff_pstripe == $stripe_nr)) ||
2338                         error "FF stripe $ff_pstripe != $stripe_nr"
2339
2340                 stripe_nr=$((stripe_nr + 1))
2341                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2342                         continue
2343                 if grep -q 'stripe_count=' <<<$ff; then
2344                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2345                                             -e 's/ .*//' <<<$ff)
2346                         [ $lmm_count = $ff_scnt ] ||
2347                                 error "FF stripe count $lmm_count != $ff_scnt"
2348                 fi
2349         done
2350 }
2351
2352 test_27z() {
2353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2354         remote_ost_nodsh && skip "remote OST with nodsh"
2355
2356         test_mkdir $DIR/$tdir
2357         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2358                 { error "setstripe -c -1 failed"; return 1; }
2359         # We need to send a write to every object to get parent FID info set.
2360         # This _should_ also work for setattr, but does not currently.
2361         # touch $DIR/$tdir/$tfile-1 ||
2362         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2363                 { error "dd $tfile-1 failed"; return 2; }
2364         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2365                 { error "setstripe -c -1 failed"; return 3; }
2366         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2367                 { error "dd $tfile-2 failed"; return 4; }
2368
2369         # make sure write RPCs have been sent to OSTs
2370         sync; sleep 5; sync
2371
2372         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2373         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2374 }
2375 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2376
2377 test_27A() { # b=19102
2378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2379
2380         save_layout_restore_at_exit $MOUNT
2381         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2382         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2383                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2384         local default_size=$($LFS getstripe -S $MOUNT)
2385         local default_offset=$($LFS getstripe -i $MOUNT)
2386         local dsize=$(do_facet $SINGLEMDS \
2387                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2388         [ $default_size -eq $dsize ] ||
2389                 error "stripe size $default_size != $dsize"
2390         [ $default_offset -eq -1 ] ||
2391                 error "stripe offset $default_offset != -1"
2392 }
2393 run_test 27A "check filesystem-wide default LOV EA values"
2394
2395 test_27B() { # LU-2523
2396         test_mkdir $DIR/$tdir
2397         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2398         touch $DIR/$tdir/f0
2399         # open f1 with O_LOV_DELAY_CREATE
2400         # rename f0 onto f1
2401         # call setstripe ioctl on open file descriptor for f1
2402         # close
2403         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2404                 $DIR/$tdir/f0
2405
2406         rm -f $DIR/$tdir/f1
2407         # open f1 with O_LOV_DELAY_CREATE
2408         # unlink f1
2409         # call setstripe ioctl on open file descriptor for f1
2410         # close
2411         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2412
2413         # Allow multiop to fail in imitation of NFS's busted semantics.
2414         true
2415 }
2416 run_test 27B "call setstripe on open unlinked file/rename victim"
2417
2418 # 27C family tests full striping and overstriping
2419 test_27Ca() { #LU-2871
2420         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2421
2422         declare -a ost_idx
2423         local index
2424         local found
2425         local i
2426         local j
2427
2428         test_mkdir $DIR/$tdir
2429         cd $DIR/$tdir
2430         for i in $(seq 0 $((OSTCOUNT - 1))); do
2431                 # set stripe across all OSTs starting from OST$i
2432                 $LFS setstripe -i $i -c -1 $tfile$i
2433                 # get striping information
2434                 ost_idx=($($LFS getstripe $tfile$i |
2435                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2436                 echo "OST Index: ${ost_idx[*]}"
2437
2438                 # check the layout
2439                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2440                         error "${#ost_idx[@]} != $OSTCOUNT"
2441
2442                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2443                         found=0
2444                         for j in "${ost_idx[@]}"; do
2445                                 if [ $index -eq $j ]; then
2446                                         found=1
2447                                         break
2448                                 fi
2449                         done
2450                         [ $found = 1 ] ||
2451                                 error "Can not find $index in ${ost_idx[*]}"
2452                 done
2453         done
2454 }
2455 run_test 27Ca "check full striping across all OSTs"
2456
2457 test_27Cb() {
2458         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2459                 skip "server does not support overstriping"
2460         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2461                 skip_env "too many osts, skipping"
2462
2463         test_mkdir -p $DIR/$tdir
2464         local setcount=$(($OSTCOUNT * 2))
2465         [ $setcount -lt 160 ] || large_xattr_enabled ||
2466                 skip_env "ea_inode feature disabled"
2467
2468         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2469                 error "setstripe failed"
2470
2471         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2472         [ $count -eq $setcount ] ||
2473                 error "stripe count $count, should be $setcount"
2474
2475         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2476                 error "overstriped should be set in pattern"
2477
2478         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2479                 error "dd failed"
2480 }
2481 run_test 27Cb "more stripes than OSTs with -C"
2482
2483 test_27Cc() {
2484         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2485                 skip "server does not support overstriping"
2486         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2487
2488         test_mkdir -p $DIR/$tdir
2489         local setcount=$(($OSTCOUNT - 1))
2490
2491         [ $setcount -lt 160 ] || large_xattr_enabled ||
2492                 skip_env "ea_inode feature disabled"
2493
2494         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2495                 error "setstripe failed"
2496
2497         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2498         [ $count -eq $setcount ] ||
2499                 error "stripe count $count, should be $setcount"
2500
2501         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2502                 error "overstriped should not be set in pattern"
2503
2504         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2505                 error "dd failed"
2506 }
2507 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2508
2509 test_27Cd() {
2510         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2511                 skip "server does not support overstriping"
2512         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2513         large_xattr_enabled || skip_env "ea_inode feature disabled"
2514
2515         test_mkdir -p $DIR/$tdir
2516         local setcount=$LOV_MAX_STRIPE_COUNT
2517
2518         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2519                 error "setstripe failed"
2520
2521         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2522         [ $count -eq $setcount ] ||
2523                 error "stripe count $count, should be $setcount"
2524
2525         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2526                 error "overstriped should be set in pattern"
2527
2528         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2529                 error "dd failed"
2530
2531         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2532 }
2533 run_test 27Cd "test maximum stripe count"
2534
2535 test_27Ce() {
2536         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2537                 skip "server does not support overstriping"
2538         test_mkdir -p $DIR/$tdir
2539
2540         pool_add $TESTNAME || error "Pool creation failed"
2541         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2542
2543         local setcount=8
2544
2545         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2546                 error "setstripe failed"
2547
2548         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2549         [ $count -eq $setcount ] ||
2550                 error "stripe count $count, should be $setcount"
2551
2552         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2553                 error "overstriped should be set in pattern"
2554
2555         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2556                 error "dd failed"
2557
2558         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2559 }
2560 run_test 27Ce "test pool with overstriping"
2561
2562 test_27Cf() {
2563         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2564                 skip "server does not support overstriping"
2565         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2566                 skip_env "too many osts, skipping"
2567
2568         test_mkdir -p $DIR/$tdir
2569
2570         local setcount=$(($OSTCOUNT * 2))
2571         [ $setcount -lt 160 ] || large_xattr_enabled ||
2572                 skip_env "ea_inode feature disabled"
2573
2574         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2575                 error "setstripe failed"
2576
2577         echo 1 > $DIR/$tdir/$tfile
2578
2579         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2580         [ $count -eq $setcount ] ||
2581                 error "stripe count $count, should be $setcount"
2582
2583         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2584                 error "overstriped should be set in pattern"
2585
2586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2587                 error "dd failed"
2588
2589         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2590 }
2591 run_test 27Cf "test default inheritance with overstriping"
2592
2593 test_27D() {
2594         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2595         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2596         remote_mds_nodsh && skip "remote MDS with nodsh"
2597
2598         local POOL=${POOL:-testpool}
2599         local first_ost=0
2600         local last_ost=$(($OSTCOUNT - 1))
2601         local ost_step=1
2602         local ost_list=$(seq $first_ost $ost_step $last_ost)
2603         local ost_range="$first_ost $last_ost $ost_step"
2604
2605         test_mkdir $DIR/$tdir
2606         pool_add $POOL || error "pool_add failed"
2607         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2608
2609         local skip27D
2610         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2611                 skip27D+="-s 29"
2612         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2613                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2614                         skip27D+=" -s 30,31"
2615         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2616           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2617                 skip27D+=" -s 32,33"
2618         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2619                 skip27D+=" -s 34"
2620         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2621                 error "llapi_layout_test failed"
2622
2623         destroy_test_pools || error "destroy test pools failed"
2624 }
2625 run_test 27D "validate llapi_layout API"
2626
2627 # Verify that default_easize is increased from its initial value after
2628 # accessing a widely striped file.
2629 test_27E() {
2630         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2631         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2632                 skip "client does not have LU-3338 fix"
2633
2634         # 72 bytes is the minimum space required to store striping
2635         # information for a file striped across one OST:
2636         # (sizeof(struct lov_user_md_v3) +
2637         #  sizeof(struct lov_user_ost_data_v1))
2638         local min_easize=72
2639         $LCTL set_param -n llite.*.default_easize $min_easize ||
2640                 error "lctl set_param failed"
2641         local easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -eq $min_easize ] ||
2644                 error "failed to set default_easize"
2645
2646         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2647                 error "setstripe failed"
2648         # In order to ensure stat() call actually talks to MDS we need to
2649         # do something drastic to this file to shake off all lock, e.g.
2650         # rename it (kills lookup lock forcing cache cleaning)
2651         mv $DIR/$tfile $DIR/${tfile}-1
2652         ls -l $DIR/${tfile}-1
2653         rm $DIR/${tfile}-1
2654
2655         easize=$($LCTL get_param -n llite.*.default_easize)
2656
2657         [ $easize -gt $min_easize ] ||
2658                 error "default_easize not updated"
2659 }
2660 run_test 27E "check that default extended attribute size properly increases"
2661
2662 test_27F() { # LU-5346/LU-7975
2663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2664         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2665         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2666                 skip "Need MDS version at least 2.8.51"
2667         remote_ost_nodsh && skip "remote OST with nodsh"
2668
2669         test_mkdir $DIR/$tdir
2670         rm -f $DIR/$tdir/f0
2671         $LFS setstripe -c 2 $DIR/$tdir
2672
2673         # stop all OSTs to reproduce situation for LU-7975 ticket
2674         for num in $(seq $OSTCOUNT); do
2675                 stop ost$num
2676         done
2677
2678         # open/create f0 with O_LOV_DELAY_CREATE
2679         # truncate f0 to a non-0 size
2680         # close
2681         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2682
2683         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2684         # open/write it again to force delayed layout creation
2685         cat /etc/hosts > $DIR/$tdir/f0 &
2686         catpid=$!
2687
2688         # restart OSTs
2689         for num in $(seq $OSTCOUNT); do
2690                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2691                         error "ost$num failed to start"
2692         done
2693
2694         wait $catpid || error "cat failed"
2695
2696         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2697         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2698                 error "wrong stripecount"
2699
2700 }
2701 run_test 27F "Client resend delayed layout creation with non-zero size"
2702
2703 test_27G() { #LU-10629
2704         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2705                 skip "Need MDS version at least 2.11.51"
2706         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2707         remote_mds_nodsh && skip "remote MDS with nodsh"
2708         local POOL=${POOL:-testpool}
2709         local ostrange="0 0 1"
2710
2711         test_mkdir $DIR/$tdir
2712         touch $DIR/$tdir/$tfile.nopool
2713         pool_add $POOL || error "pool_add failed"
2714         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2715         $LFS setstripe -p $POOL $DIR/$tdir
2716
2717         local pool=$($LFS getstripe -p $DIR/$tdir)
2718
2719         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2720         touch $DIR/$tdir/$tfile.default
2721         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2722         $LFS find $DIR/$tdir -type f --pool $POOL
2723         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2724         [[ "$found" == "2" ]] ||
2725                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2726
2727         $LFS setstripe -d $DIR/$tdir
2728
2729         pool=$($LFS getstripe -p -d $DIR/$tdir)
2730
2731         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2732 }
2733 run_test 27G "Clear OST pool from stripe"
2734
2735 test_27H() {
2736         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2737                 skip "Need MDS version newer than 2.11.54"
2738         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2739         test_mkdir $DIR/$tdir
2740         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2741         touch $DIR/$tdir/$tfile
2742         $LFS getstripe -c $DIR/$tdir/$tfile
2743         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2744                 error "two-stripe file doesn't have two stripes"
2745
2746         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2747         $LFS getstripe -y $DIR/$tdir/$tfile
2748         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2749              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2750                 error "expected l_ost_idx: [02]$ not matched"
2751
2752         # make sure ost list has been cleared
2753         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2754         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2755                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2756         touch $DIR/$tdir/f3
2757         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2758 }
2759 run_test 27H "Set specific OSTs stripe"
2760
2761 test_27I() {
2762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2763         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2764         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2765                 skip "Need MDS version newer than 2.12.52"
2766         local pool=$TESTNAME
2767         local ostrange="1 1 1"
2768
2769         save_layout_restore_at_exit $MOUNT
2770         $LFS setstripe -c 2 -i 0 $MOUNT
2771         pool_add $pool || error "pool_add failed"
2772         pool_add_targets $pool $ostrange ||
2773                 error "pool_add_targets failed"
2774         test_mkdir $DIR/$tdir
2775         $LFS setstripe -p $pool $DIR/$tdir
2776         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2777         $LFS getstripe $DIR/$tdir/$tfile
2778 }
2779 run_test 27I "check that root dir striping does not break parent dir one"
2780
2781 test_27J() {
2782         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2783                 skip "Need MDS version newer than 2.12.51"
2784
2785         test_mkdir $DIR/$tdir
2786         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2787         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2788
2789         # create foreign file (raw way)
2790         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2791                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2792
2793         ! $LFS setstripe --foreign --flags foo \
2794                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2795                         error "creating $tfile with '--flags foo' should fail"
2796
2797         ! $LFS setstripe --foreign --flags 0xffffffff \
2798                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2799                         error "creating $tfile w/ 0xffffffff flags should fail"
2800
2801         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2802                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2803
2804         # verify foreign file (raw way)
2805         parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2807                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2808         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2810         parse_foreign_file -f $DIR/$tdir/$tfile |
2811                 grep "lov_foreign_size: 73" ||
2812                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2813         parse_foreign_file -f $DIR/$tdir/$tfile |
2814                 grep "lov_foreign_type: 1" ||
2815                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2816         parse_foreign_file -f $DIR/$tdir/$tfile |
2817                 grep "lov_foreign_flags: 0x0000DA08" ||
2818                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2819         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2820                 grep "lov_foreign_value: 0x" |
2821                 sed -e 's/lov_foreign_value: 0x//')
2822         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2823         [[ $lov = ${lov2// /} ]] ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2825
2826         # create foreign file (lfs + API)
2827         $LFS setstripe --foreign=none --flags 0xda08 \
2828                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: create failed"
2830
2831         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2832                 grep "lfm_magic:.*0x0BD70BD0" ||
2833                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2834         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2835         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2836                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2837         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2838                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2839         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2840                 grep "lfm_flags:.*0x0000DA08" ||
2841                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2842         $LFS getstripe $DIR/$tdir/${tfile}2 |
2843                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2844                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2845
2846         # modify striping should fail
2847         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2848                 error "$DIR/$tdir/$tfile: setstripe should fail"
2849         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2850                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2851
2852         # R/W should fail
2853         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2854         cat $DIR/$tdir/${tfile}2 &&
2855                 error "$DIR/$tdir/${tfile}2: read should fail"
2856         cat /etc/passwd > $DIR/$tdir/$tfile &&
2857                 error "$DIR/$tdir/$tfile: write should fail"
2858         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2859                 error "$DIR/$tdir/${tfile}2: write should fail"
2860
2861         # chmod should work
2862         chmod 222 $DIR/$tdir/$tfile ||
2863                 error "$DIR/$tdir/$tfile: chmod failed"
2864         chmod 222 $DIR/$tdir/${tfile}2 ||
2865                 error "$DIR/$tdir/${tfile}2: chmod failed"
2866
2867         # chown should work
2868         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2869                 error "$DIR/$tdir/$tfile: chown failed"
2870         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2871                 error "$DIR/$tdir/${tfile}2: chown failed"
2872
2873         # rename should work
2874         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2875                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2876         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2877                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2878
2879         #remove foreign file
2880         rm $DIR/$tdir/${tfile}.new ||
2881                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2882         rm $DIR/$tdir/${tfile}2.new ||
2883                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2884 }
2885 run_test 27J "basic ops on file with foreign LOV"
2886
2887 test_27K() {
2888         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2889                 skip "Need MDS version newer than 2.12.49"
2890
2891         test_mkdir $DIR/$tdir
2892         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2893         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2894
2895         # create foreign dir (raw way)
2896         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2897                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2898
2899         ! $LFS setdirstripe --foreign --flags foo \
2900                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2901                         error "creating $tdir with '--flags foo' should fail"
2902
2903         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2904                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2905                         error "creating $tdir w/ 0xffffffff flags should fail"
2906
2907         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2908                 error "create_foreign_dir FAILED"
2909
2910         # verify foreign dir (raw way)
2911         parse_foreign_dir -d $DIR/$tdir/$tdir |
2912                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2913                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2914         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2915                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2916         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2917                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2918         parse_foreign_dir -d $DIR/$tdir/$tdir |
2919                 grep "lmv_foreign_flags: 55813$" ||
2920                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2921         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2922                 grep "lmv_foreign_value: 0x" |
2923                 sed 's/lmv_foreign_value: 0x//')
2924         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2925                 sed 's/ //g')
2926         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2927
2928         # create foreign dir (lfs + API)
2929         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2930                 $DIR/$tdir/${tdir}2 ||
2931                 error "$DIR/$tdir/${tdir}2: create failed"
2932
2933         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2934
2935         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2936                 grep "lfm_magic:.*0x0CD50CD0" ||
2937                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2938         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2939         # - sizeof(lfm_type) - sizeof(lfm_flags)
2940         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2941                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2942         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2943                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2944         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2945                 grep "lfm_flags:.*0x0000DA05" ||
2946                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2947         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2948                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2949                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2950
2951         # file create in dir should fail
2952         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2953         touch $DIR/$tdir/${tdir}2/$tfile &&
2954                 error "$DIR/${tdir}2: file create should fail"
2955
2956         # chmod should work
2957         chmod 777 $DIR/$tdir/$tdir ||
2958                 error "$DIR/$tdir: chmod failed"
2959         chmod 777 $DIR/$tdir/${tdir}2 ||
2960                 error "$DIR/${tdir}2: chmod failed"
2961
2962         # chown should work
2963         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2964                 error "$DIR/$tdir: chown failed"
2965         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2966                 error "$DIR/${tdir}2: chown failed"
2967
2968         # rename should work
2969         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2970                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2971         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2972                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2973
2974         #remove foreign dir
2975         rmdir $DIR/$tdir/${tdir}.new ||
2976                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2977         rmdir $DIR/$tdir/${tdir}2.new ||
2978                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2979 }
2980 run_test 27K "basic ops on dir with foreign LMV"
2981
2982 test_27L() {
2983         remote_mds_nodsh && skip "remote MDS with nodsh"
2984
2985         local POOL=${POOL:-$TESTNAME}
2986
2987         pool_add $POOL || error "pool_add failed"
2988
2989         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2990                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2991                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2992 }
2993 run_test 27L "lfs pool_list gives correct pool name"
2994
2995 test_27M() {
2996         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2997                 skip "Need MDS version >= than 2.12.57"
2998         remote_mds_nodsh && skip "remote MDS with nodsh"
2999         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3000
3001         # Set default striping on directory
3002         local setcount=4
3003         local stripe_opt
3004         local mdts=$(comma_list $(mdts_nodes))
3005
3006         # if we run against a 2.12 server which lacks overstring support
3007         # then the connect_flag will not report overstriping, even if client
3008         # is 2.14+
3009         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3010                 stripe_opt="-C $setcount"
3011         elif (( $OSTCOUNT >= $setcount )); then
3012                 stripe_opt="-c $setcount"
3013         else
3014                 skip "server does not support overstriping"
3015         fi
3016
3017         test_mkdir $DIR/$tdir
3018
3019         # Validate existing append_* params and ensure restore
3020         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3021         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3022         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3023
3024         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3025         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3026         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3027
3028         $LFS setstripe $stripe_opt $DIR/$tdir
3029
3030         echo 1 > $DIR/$tdir/${tfile}.1
3031         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3032         [ $count -eq $setcount ] ||
3033                 error "(1) stripe count $count, should be $setcount"
3034
3035         local appendcount=$orig_count
3036         echo 1 >> $DIR/$tdir/${tfile}.2_append
3037         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3038         [ $count -eq $appendcount ] ||
3039                 error "(2)stripe count $count, should be $appendcount for append"
3040
3041         # Disable O_APPEND striping, verify it works
3042         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3043
3044         # Should now get the default striping, which is 4
3045         setcount=4
3046         echo 1 >> $DIR/$tdir/${tfile}.3_append
3047         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3048         [ $count -eq $setcount ] ||
3049                 error "(3) stripe count $count, should be $setcount"
3050
3051         # Try changing the stripe count for append files
3052         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3053
3054         # Append striping is now 2 (directory default is still 4)
3055         appendcount=2
3056         echo 1 >> $DIR/$tdir/${tfile}.4_append
3057         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3058         [ $count -eq $appendcount ] ||
3059                 error "(4) stripe count $count, should be $appendcount for append"
3060
3061         # Test append stripe count of -1
3062         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3063         appendcount=$OSTCOUNT
3064         echo 1 >> $DIR/$tdir/${tfile}.5
3065         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3066         [ $count -eq $appendcount ] ||
3067                 error "(5) stripe count $count, should be $appendcount for append"
3068
3069         # Set append striping back to default of 1
3070         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3071
3072         # Try a new default striping, PFL + DOM
3073         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3074
3075         # Create normal DOM file, DOM returns stripe count == 0
3076         setcount=0
3077         touch $DIR/$tdir/${tfile}.6
3078         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3079         [ $count -eq $setcount ] ||
3080                 error "(6) stripe count $count, should be $setcount"
3081
3082         # Show
3083         appendcount=1
3084         echo 1 >> $DIR/$tdir/${tfile}.7_append
3085         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3086         [ $count -eq $appendcount ] ||
3087                 error "(7) stripe count $count, should be $appendcount for append"
3088
3089         # Clean up DOM layout
3090         $LFS setstripe -d $DIR/$tdir
3091
3092         save_layout_restore_at_exit $MOUNT
3093         # Now test that append striping works when layout is from root
3094         $LFS setstripe -c 2 $MOUNT
3095         # Make a special directory for this
3096         mkdir $DIR/${tdir}/${tdir}.2
3097
3098         # Verify for normal file
3099         setcount=2
3100         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3101         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3102         [ $count -eq $setcount ] ||
3103                 error "(8) stripe count $count, should be $setcount"
3104
3105         appendcount=1
3106         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3107         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3108         [ $count -eq $appendcount ] ||
3109                 error "(9) stripe count $count, should be $appendcount for append"
3110
3111         # Now test O_APPEND striping with pools
3112         pool_add $TESTNAME || error "pool creation failed"
3113         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3114         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3115
3116         echo 1 >> $DIR/$tdir/${tfile}.10_append
3117
3118         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3119         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3120
3121         # Check that count is still correct
3122         appendcount=1
3123         echo 1 >> $DIR/$tdir/${tfile}.11_append
3124         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3125         [ $count -eq $appendcount ] ||
3126                 error "(11) stripe count $count, should be $appendcount for append"
3127
3128         # Disable O_APPEND stripe count, verify pool works separately
3129         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3130
3131         echo 1 >> $DIR/$tdir/${tfile}.12_append
3132
3133         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3134         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3135
3136         # Remove pool setting, verify it's not applied
3137         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3138
3139         echo 1 >> $DIR/$tdir/${tfile}.13_append
3140
3141         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3142         [ "$pool" = "" ] || error "(13) pool found: $pool"
3143 }
3144 run_test 27M "test O_APPEND striping"
3145
3146 test_27N() {
3147         combined_mgs_mds && skip "needs separate MGS/MDT"
3148
3149         pool_add $TESTNAME || error "pool_add failed"
3150         do_facet mgs "$LCTL pool_list $FSNAME" |
3151                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3152                 error "lctl pool_list on MGS failed"
3153 }
3154 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3155
3156 clean_foreign_symlink() {
3157         trap 0
3158         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3159         for i in $DIR/$tdir/* ; do
3160                 $LFS unlink_foreign $i || true
3161         done
3162 }
3163
3164 test_27O() {
3165         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3166                 skip "Need MDS version newer than 2.12.51"
3167
3168         test_mkdir $DIR/$tdir
3169         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3170         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3171
3172         trap clean_foreign_symlink EXIT
3173
3174         # enable foreign_symlink behaviour
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3176
3177         # foreign symlink LOV format is a partial path by default
3178
3179         # create foreign file (lfs + API)
3180         $LFS setstripe --foreign=symlink --flags 0xda05 \
3181                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3182                 error "$DIR/$tdir/${tfile}: create failed"
3183
3184         $LFS getstripe -v $DIR/$tdir/${tfile} |
3185                 grep "lfm_magic:.*0x0BD70BD0" ||
3186                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3187         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3188                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3189         $LFS getstripe -v $DIR/$tdir/${tfile} |
3190                 grep "lfm_flags:.*0x0000DA05" ||
3191                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3192         $LFS getstripe $DIR/$tdir/${tfile} |
3193                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3194                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3195
3196         # modify striping should fail
3197         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3198                 error "$DIR/$tdir/$tfile: setstripe should fail"
3199
3200         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3201         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3202         cat /etc/passwd > $DIR/$tdir/$tfile &&
3203                 error "$DIR/$tdir/$tfile: write should fail"
3204
3205         # rename should succeed
3206         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/$tfile: rename has failed"
3208
3209         #remove foreign_symlink file should fail
3210         rm $DIR/$tdir/${tfile}.new &&
3211                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3212
3213         #test fake symlink
3214         mkdir /tmp/${uuid1} ||
3215                 error "/tmp/${uuid1}: mkdir has failed"
3216         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3217                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3218         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3219         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3220                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3221         #read should succeed now
3222         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3223                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3224         #write should succeed now
3225         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3226                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3227         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3228                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3229         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3230                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3231
3232         #check that getstripe still works
3233         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3234                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3235
3236         # chmod should still succeed
3237         chmod 644 $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3239
3240         # chown should still succeed
3241         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3242                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3243
3244         # rename should still succeed
3245         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3246                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3247
3248         #remove foreign_symlink file should still fail
3249         rm $DIR/$tdir/${tfile} &&
3250                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3251
3252         #use special ioctl() to unlink foreign_symlink file
3253         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3254                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3255
3256 }
3257 run_test 27O "basic ops on foreign file of symlink type"
3258
3259 test_27P() {
3260         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3261                 skip "Need MDS version newer than 2.12.49"
3262
3263         test_mkdir $DIR/$tdir
3264         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3265         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3266
3267         trap clean_foreign_symlink EXIT
3268
3269         # enable foreign_symlink behaviour
3270         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3271
3272         # foreign symlink LMV format is a partial path by default
3273
3274         # create foreign dir (lfs + API)
3275         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3276                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3277                 error "$DIR/$tdir/${tdir}: create failed"
3278
3279         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3280
3281         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3282                 grep "lfm_magic:.*0x0CD50CD0" ||
3283                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3284         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3285                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3286         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3287                 grep "lfm_flags:.*0x0000DA05" ||
3288                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3289         $LFS getdirstripe $DIR/$tdir/${tdir} |
3290                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3291                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3292
3293         # file create in dir should fail
3294         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3295         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3296
3297         # rename should succeed
3298         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3299                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3300
3301         #remove foreign_symlink dir should fail
3302         rmdir $DIR/$tdir/${tdir}.new &&
3303                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3304
3305         #test fake symlink
3306         mkdir -p /tmp/${uuid1}/${uuid2} ||
3307                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3308         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3309                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3310         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3311         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3312                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3313         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3314                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3315
3316         #check that getstripe fails now that foreign_symlink enabled
3317         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3318                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3319
3320         # file create in dir should work now
3321         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3322                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3323         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3324                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3325         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3326                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3327
3328         # chmod should still succeed
3329         chmod 755 $DIR/$tdir/${tdir}.new ||
3330                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3331
3332         # chown should still succeed
3333         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3334                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3335
3336         # rename should still succeed
3337         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3338                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3339
3340         #remove foreign_symlink dir should still fail
3341         rmdir $DIR/$tdir/${tdir} &&
3342                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3343
3344         #use special ioctl() to unlink foreign_symlink file
3345         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3346                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3347
3348         #created file should still exist
3349         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3350                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3351         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3352                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3353 }
3354 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3355
3356 test_27Q() {
3357         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3358         stack_trap "rm -f $TMP/$tfile*"
3359
3360         test_mkdir $DIR/$tdir-1
3361         test_mkdir $DIR/$tdir-2
3362
3363         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3364         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3365
3366         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3367         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3368
3369         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3370         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3371
3372         # Create some bad symlinks and ensure that we don't loop
3373         # forever or something. These should return ELOOP (40) and
3374         # ENOENT (2) but I don't want to test for that because there's
3375         # always some weirdo architecture that needs to ruin
3376         # everything by defining these error numbers differently.
3377
3378         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3379         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3380
3381         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3382         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3383
3384         return 0
3385 }
3386 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3387
3388 test_27R() {
3389         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3390                 skip "need MDS 2.14.55 or later"
3391         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3392
3393         local testdir="$DIR/$tdir"
3394         test_mkdir -p $testdir
3395         stack_trap "rm -rf $testdir"
3396         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3397
3398         local f1="$testdir/f1"
3399         touch $f1 || error "failed to touch $f1"
3400         local count=$($LFS getstripe -c $f1)
3401         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3402
3403         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3404         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3405
3406         local maxcount=$(($OSTCOUNT - 1))
3407         local mdts=$(comma_list $(mdts_nodes))
3408         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3409         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3410
3411         local f2="$testdir/f2"
3412         touch $f2 || error "failed to touch $f2"
3413         local count=$($LFS getstripe -c $f2)
3414         (( $count == $maxcount )) || error "wrong stripe count"
3415 }
3416 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3417
3418 test_27T() {
3419         [ $(facet_host client) == $(facet_host ost1) ] &&
3420                 skip "need ost1 and client on different nodes"
3421
3422 #define OBD_FAIL_OSC_NO_GRANT            0x411
3423         $LCTL set_param fail_loc=0x20000411 fail_val=1
3424 #define OBD_FAIL_OST_ENOSPC              0x215
3425         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3426         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3427         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3428                 error "multiop failed"
3429 }
3430 run_test 27T "no eio on close on partial write due to enosp"
3431
3432 test_27U() {
3433         local dir=$DIR/$tdir
3434         local file=$dir/$tfile
3435         local append_pool=${TESTNAME}-append
3436         local normal_pool=${TESTNAME}-normal
3437         local pool
3438         local stripe_count
3439         local stripe_count2
3440         local mdts=$(comma_list $(mdts_nodes))
3441
3442         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3443                 skip "Need MDS version at least 2.15.51 for append pool feature"
3444
3445         # Validate existing append_* params and ensure restore
3446         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3447         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3448         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3449
3450         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3451         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3452         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3453
3454         pool_add $append_pool || error "pool creation failed"
3455         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3456
3457         pool_add $normal_pool || error "pool creation failed"
3458         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3459
3460         test_mkdir $dir
3461         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3462
3463         echo XXX >> $file.1
3464         $LFS getstripe $file.1
3465
3466         pool=$($LFS getstripe -p $file.1)
3467         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3468
3469         stripe_count2=$($LFS getstripe -c $file.1)
3470         ((stripe_count2 == stripe_count)) ||
3471                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3472
3473         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3474
3475         echo XXX >> $file.2
3476         $LFS getstripe $file.2
3477
3478         pool=$($LFS getstripe -p $file.2)
3479         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3480
3481         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3482
3483         echo XXX >> $file.3
3484         $LFS getstripe $file.3
3485
3486         stripe_count2=$($LFS getstripe -c $file.3)
3487         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3488 }
3489 run_test 27U "append pool and stripe count work with composite default layout"
3490
3491 # createtest also checks that device nodes are created and
3492 # then visible correctly (#2091)
3493 test_28() { # bug 2091
3494         test_mkdir $DIR/d28
3495         $CREATETEST $DIR/d28/ct || error "createtest failed"
3496 }
3497 run_test 28 "create/mknod/mkdir with bad file types ============"
3498
3499 test_29() {
3500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3501
3502         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3503                 disable_opencache
3504                 stack_trap "restore_opencache"
3505         }
3506
3507         sync; sleep 1; sync # flush out any dirty pages from previous tests
3508         cancel_lru_locks
3509         test_mkdir $DIR/d29
3510         touch $DIR/d29/foo
3511         log 'first d29'
3512         ls -l $DIR/d29
3513
3514         declare -i LOCKCOUNTORIG=0
3515         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3516                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3517         done
3518         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3519
3520         declare -i LOCKUNUSEDCOUNTORIG=0
3521         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3522                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3523         done
3524
3525         log 'second d29'
3526         ls -l $DIR/d29
3527         log 'done'
3528
3529         declare -i LOCKCOUNTCURRENT=0
3530         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3531                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3532         done
3533
3534         declare -i LOCKUNUSEDCOUNTCURRENT=0
3535         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3536                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3537         done
3538
3539         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3540                 $LCTL set_param -n ldlm.dump_namespaces ""
3541                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3542                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3543                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3544                 return 2
3545         fi
3546         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3547                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3548                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3549                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3550                 return 3
3551         fi
3552 }
3553 run_test 29 "IT_GETATTR regression  ============================"
3554
3555 test_30a() { # was test_30
3556         cp $(which ls) $DIR || cp /bin/ls $DIR
3557         $DIR/ls / || error "Can't execute binary from lustre"
3558         rm $DIR/ls
3559 }
3560 run_test 30a "execute binary from Lustre (execve) =============="
3561
3562 test_30b() {
3563         cp `which ls` $DIR || cp /bin/ls $DIR
3564         chmod go+rx $DIR/ls
3565         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3566         rm $DIR/ls
3567 }
3568 run_test 30b "execute binary from Lustre as non-root ==========="
3569
3570 test_30c() { # b=22376
3571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3572
3573         cp $(which ls) $DIR || cp /bin/ls $DIR
3574         chmod a-rw $DIR/ls
3575         cancel_lru_locks mdc
3576         cancel_lru_locks osc
3577         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3578         rm -f $DIR/ls
3579 }
3580 run_test 30c "execute binary from Lustre without read perms ===="
3581
3582 test_30d() {
3583         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3584
3585         for i in {1..10}; do
3586                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3587                 local PID=$!
3588                 sleep 1
3589                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3590                 wait $PID || error "executing dd from Lustre failed"
3591                 rm -f $DIR/$tfile
3592         done
3593
3594         rm -f $DIR/dd
3595 }
3596 run_test 30d "execute binary from Lustre while clear locks"
3597
3598 test_31a() {
3599         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3600         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3601 }
3602 run_test 31a "open-unlink file =================================="
3603
3604 test_31b() {
3605         touch $DIR/f31 || error "touch $DIR/f31 failed"
3606         ln $DIR/f31 $DIR/f31b || error "ln failed"
3607         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3608         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3609 }
3610 run_test 31b "unlink file with multiple links while open ======="
3611
3612 test_31c() {
3613         touch $DIR/f31 || error "touch $DIR/f31 failed"
3614         ln $DIR/f31 $DIR/f31c || error "ln failed"
3615         multiop_bg_pause $DIR/f31 O_uc ||
3616                 error "multiop_bg_pause for $DIR/f31 failed"
3617         MULTIPID=$!
3618         $MULTIOP $DIR/f31c Ouc
3619         kill -USR1 $MULTIPID
3620         wait $MULTIPID
3621 }
3622 run_test 31c "open-unlink file with multiple links ============="
3623
3624 test_31d() {
3625         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3626         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3627 }
3628 run_test 31d "remove of open directory ========================="
3629
3630 test_31e() { # bug 2904
3631         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3632 }
3633 run_test 31e "remove of open non-empty directory ==============="
3634
3635 test_31f() { # bug 4554
3636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3637
3638         set -vx
3639         test_mkdir $DIR/d31f
3640         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3641         cp /etc/hosts $DIR/d31f
3642         ls -l $DIR/d31f
3643         $LFS getstripe $DIR/d31f/hosts
3644         multiop_bg_pause $DIR/d31f D_c || return 1
3645         MULTIPID=$!
3646
3647         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3648         test_mkdir $DIR/d31f
3649         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3650         cp /etc/hosts $DIR/d31f
3651         ls -l $DIR/d31f
3652         $LFS getstripe $DIR/d31f/hosts
3653         multiop_bg_pause $DIR/d31f D_c || return 1
3654         MULTIPID2=$!
3655
3656         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3657         wait $MULTIPID || error "first opendir $MULTIPID failed"
3658
3659         sleep 6
3660
3661         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3662         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3663         set +vx
3664 }
3665 run_test 31f "remove of open directory with open-unlink file ==="
3666
3667 test_31g() {
3668         echo "-- cross directory link --"
3669         test_mkdir -c1 $DIR/${tdir}ga
3670         test_mkdir -c1 $DIR/${tdir}gb
3671         touch $DIR/${tdir}ga/f
3672         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3673         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3674         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3675         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3676         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3677 }
3678 run_test 31g "cross directory link==============="
3679
3680 test_31h() {
3681         echo "-- cross directory link --"
3682         test_mkdir -c1 $DIR/${tdir}
3683         test_mkdir -c1 $DIR/${tdir}/dir
3684         touch $DIR/${tdir}/f
3685         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3686         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3687         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3688         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3689         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3690 }
3691 run_test 31h "cross directory link under child==============="
3692
3693 test_31i() {
3694         echo "-- cross directory link --"
3695         test_mkdir -c1 $DIR/$tdir
3696         test_mkdir -c1 $DIR/$tdir/dir
3697         touch $DIR/$tdir/dir/f
3698         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3699         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3700         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3701         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3702         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3703 }
3704 run_test 31i "cross directory link under parent==============="
3705
3706 test_31j() {
3707         test_mkdir -c1 -p $DIR/$tdir
3708         test_mkdir -c1 -p $DIR/$tdir/dir1
3709         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3710         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3711         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3712         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3713         return 0
3714 }
3715 run_test 31j "link for directory==============="
3716
3717 test_31k() {
3718         test_mkdir -c1 -p $DIR/$tdir
3719         touch $DIR/$tdir/s
3720         touch $DIR/$tdir/exist
3721         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3722         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3723         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3724         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3725         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3726         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3727         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3728         return 0
3729 }
3730 run_test 31k "link to file: the same, non-existing, dir==============="
3731
3732 test_31m() {
3733         mkdir $DIR/d31m
3734         touch $DIR/d31m/s
3735         mkdir $DIR/d31m2
3736         touch $DIR/d31m2/exist
3737         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3738         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3739         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3740         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3741         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3742         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3743         return 0
3744 }
3745 run_test 31m "link to file: the same, non-existing, dir==============="
3746
3747 test_31n() {
3748         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3749         nlink=$(stat --format=%h $DIR/$tfile)
3750         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3751         local fd=$(free_fd)
3752         local cmd="exec $fd<$DIR/$tfile"
3753         eval $cmd
3754         cmd="exec $fd<&-"
3755         trap "eval $cmd" EXIT
3756         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3757         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3758         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3759         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3760         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3761         eval $cmd
3762 }
3763 run_test 31n "check link count of unlinked file"
3764
3765 link_one() {
3766         local tempfile=$(mktemp $1_XXXXXX)
3767         mlink $tempfile $1 2> /dev/null &&
3768                 echo "$BASHPID: link $tempfile to $1 succeeded"
3769         munlink $tempfile
3770 }
3771
3772 test_31o() { # LU-2901
3773         test_mkdir $DIR/$tdir
3774         for LOOP in $(seq 100); do
3775                 rm -f $DIR/$tdir/$tfile*
3776                 for THREAD in $(seq 8); do
3777                         link_one $DIR/$tdir/$tfile.$LOOP &
3778                 done
3779                 wait
3780                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3781                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3782                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3783                         break || true
3784         done
3785 }
3786 run_test 31o "duplicate hard links with same filename"
3787
3788 test_31p() {
3789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3790
3791         test_mkdir $DIR/$tdir
3792         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3793         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3794
3795         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3796                 error "open unlink test1 failed"
3797         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3798                 error "open unlink test2 failed"
3799
3800         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3801                 error "test1 still exists"
3802         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3803                 error "test2 still exists"
3804 }
3805 run_test 31p "remove of open striped directory"
3806
3807 test_31q() {
3808         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3809
3810         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3811         index=$($LFS getdirstripe -i $DIR/$tdir)
3812         [ $index -eq 3 ] || error "first stripe index $index != 3"
3813         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3814         [ $index -eq 1 ] || error "second stripe index $index != 1"
3815
3816         # when "-c <stripe_count>" is set, the number of MDTs specified after
3817         # "-i" should equal to the stripe count
3818         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3819 }
3820 run_test 31q "create striped directory on specific MDTs"
3821
3822 #LU-14949
3823 test_31r() {
3824         touch $DIR/$tfile.target
3825         touch $DIR/$tfile.source
3826
3827         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3828         $LCTL set_param fail_loc=0x1419 fail_val=3
3829         cat $DIR/$tfile.target &
3830         CATPID=$!
3831
3832         # Guarantee open is waiting before we get here
3833         sleep 1
3834         mv $DIR/$tfile.source $DIR/$tfile.target
3835
3836         wait $CATPID
3837         RC=$?
3838         if [[ $RC -ne 0 ]]; then
3839                 error "open with cat failed, rc=$RC"
3840         fi
3841 }
3842 run_test 31r "open-rename(replace) race"
3843
3844 cleanup_test32_mount() {
3845         local rc=0
3846         trap 0
3847         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3848         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3849         losetup -d $loopdev || true
3850         rm -rf $DIR/$tdir
3851         return $rc
3852 }
3853
3854 test_32a() {
3855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3856
3857         echo "== more mountpoints and symlinks ================="
3858         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3859         trap cleanup_test32_mount EXIT
3860         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3861         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3862                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3863         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3864                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3865         cleanup_test32_mount
3866 }
3867 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3868
3869 test_32b() {
3870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3871
3872         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3873         trap cleanup_test32_mount EXIT
3874         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3875         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3876                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3877         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3878                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3879         cleanup_test32_mount
3880 }
3881 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3882
3883 test_32c() {
3884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3885
3886         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3887         trap cleanup_test32_mount EXIT
3888         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3889         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3890                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3891         test_mkdir -p $DIR/$tdir/d2/test_dir
3892         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3893                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3894         cleanup_test32_mount
3895 }
3896 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3897
3898 test_32d() {
3899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3900
3901         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3902         trap cleanup_test32_mount EXIT
3903         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3904         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3905                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3906         test_mkdir -p $DIR/$tdir/d2/test_dir
3907         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3908                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3909         cleanup_test32_mount
3910 }
3911 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3912
3913 test_32e() {
3914         rm -fr $DIR/$tdir
3915         test_mkdir -p $DIR/$tdir/tmp
3916         local tmp_dir=$DIR/$tdir/tmp
3917         ln -s $DIR/$tdir $tmp_dir/symlink11
3918         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3919         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3920         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3921 }
3922 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3923
3924 test_32f() {
3925         rm -fr $DIR/$tdir
3926         test_mkdir -p $DIR/$tdir/tmp
3927         local tmp_dir=$DIR/$tdir/tmp
3928         ln -s $DIR/$tdir $tmp_dir/symlink11
3929         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3930         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3931         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3932 }
3933 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3934
3935 test_32g() {
3936         local tmp_dir=$DIR/$tdir/tmp
3937         test_mkdir -p $tmp_dir
3938         test_mkdir $DIR/${tdir}2
3939         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3940         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3941         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3942         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3943         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3944         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3945 }
3946 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3947
3948 test_32h() {
3949         rm -fr $DIR/$tdir $DIR/${tdir}2
3950         tmp_dir=$DIR/$tdir/tmp
3951         test_mkdir -p $tmp_dir
3952         test_mkdir $DIR/${tdir}2
3953         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3954         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3955         ls $tmp_dir/symlink12 || error "listing symlink12"
3956         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3957 }
3958 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3959
3960 test_32i() {
3961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3962
3963         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3964         trap cleanup_test32_mount EXIT
3965         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3966         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3967                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3968         touch $DIR/$tdir/test_file
3969         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3970                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3971         cleanup_test32_mount
3972 }
3973 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3974
3975 test_32j() {
3976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3977
3978         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3979         trap cleanup_test32_mount EXIT
3980         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3981         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3982                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3983         touch $DIR/$tdir/test_file
3984         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3985                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3986         cleanup_test32_mount
3987 }
3988 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3989
3990 test_32k() {
3991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3992
3993         rm -fr $DIR/$tdir
3994         trap cleanup_test32_mount EXIT
3995         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3996         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3997                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3998         test_mkdir -p $DIR/$tdir/d2
3999         touch $DIR/$tdir/d2/test_file || error "touch failed"
4000         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4001                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4002         cleanup_test32_mount
4003 }
4004 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4005
4006 test_32l() {
4007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4008
4009         rm -fr $DIR/$tdir
4010         trap cleanup_test32_mount EXIT
4011         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4012         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4013                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4014         test_mkdir -p $DIR/$tdir/d2
4015         touch $DIR/$tdir/d2/test_file || error "touch failed"
4016         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4017                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4018         cleanup_test32_mount
4019 }
4020 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4021
4022 test_32m() {
4023         rm -fr $DIR/d32m
4024         test_mkdir -p $DIR/d32m/tmp
4025         TMP_DIR=$DIR/d32m/tmp
4026         ln -s $DIR $TMP_DIR/symlink11
4027         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4028         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4029                 error "symlink11 not a link"
4030         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4031                 error "symlink01 not a link"
4032 }
4033 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4034
4035 test_32n() {
4036         rm -fr $DIR/d32n
4037         test_mkdir -p $DIR/d32n/tmp
4038         TMP_DIR=$DIR/d32n/tmp
4039         ln -s $DIR $TMP_DIR/symlink11
4040         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4041         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4042         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4043 }
4044 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4045
4046 test_32o() {
4047         touch $DIR/$tfile
4048         test_mkdir -p $DIR/d32o/tmp
4049         TMP_DIR=$DIR/d32o/tmp
4050         ln -s $DIR/$tfile $TMP_DIR/symlink12
4051         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4052         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4053                 error "symlink12 not a link"
4054         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4055         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4056                 error "$DIR/d32o/tmp/symlink12 not file type"
4057         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4058                 error "$DIR/d32o/symlink02 not file type"
4059 }
4060 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4061
4062 test_32p() {
4063         log 32p_1
4064         rm -fr $DIR/d32p
4065         log 32p_2
4066         rm -f $DIR/$tfile
4067         log 32p_3
4068         touch $DIR/$tfile
4069         log 32p_4
4070         test_mkdir -p $DIR/d32p/tmp
4071         log 32p_5
4072         TMP_DIR=$DIR/d32p/tmp
4073         log 32p_6
4074         ln -s $DIR/$tfile $TMP_DIR/symlink12
4075         log 32p_7
4076         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4077         log 32p_8
4078         cat $DIR/d32p/tmp/symlink12 ||
4079                 error "Can't open $DIR/d32p/tmp/symlink12"
4080         log 32p_9
4081         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4082         log 32p_10
4083 }
4084 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4085
4086 test_32q() {
4087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4088
4089         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4090         trap cleanup_test32_mount EXIT
4091         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4092         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4093         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4094                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4095         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4096         cleanup_test32_mount
4097 }
4098 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4099
4100 test_32r() {
4101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4102
4103         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4104         trap cleanup_test32_mount EXIT
4105         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4106         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4107         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4108                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4109         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4110         cleanup_test32_mount
4111 }
4112 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4113
4114 test_33aa() {
4115         rm -f $DIR/$tfile
4116         touch $DIR/$tfile
4117         chmod 444 $DIR/$tfile
4118         chown $RUNAS_ID $DIR/$tfile
4119         log 33_1
4120         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4121         log 33_2
4122 }
4123 run_test 33aa "write file with mode 444 (should return error)"
4124
4125 test_33a() {
4126         rm -fr $DIR/$tdir
4127         test_mkdir $DIR/$tdir
4128         chown $RUNAS_ID $DIR/$tdir
4129         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4130                 error "$RUNAS create $tdir/$tfile failed"
4131         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4132                 error "open RDWR" || true
4133 }
4134 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4135
4136 test_33b() {
4137         rm -fr $DIR/$tdir
4138         test_mkdir $DIR/$tdir
4139         chown $RUNAS_ID $DIR/$tdir
4140         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4141 }
4142 run_test 33b "test open file with malformed flags (No panic)"
4143
4144 test_33c() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146         remote_ost_nodsh && skip "remote OST with nodsh"
4147
4148         local ostnum
4149         local ostname
4150         local write_bytes
4151         local all_zeros
4152
4153         all_zeros=true
4154         test_mkdir $DIR/$tdir
4155         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4156
4157         sync
4158         for ostnum in $(seq $OSTCOUNT); do
4159                 # test-framework's OST numbering is one-based, while Lustre's
4160                 # is zero-based
4161                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4162                 # check if at least some write_bytes stats are counted
4163                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4164                               obdfilter.$ostname.stats |
4165                               awk '/^write_bytes/ {print $7}' )
4166                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4167                 if (( ${write_bytes:-0} > 0 )); then
4168                         all_zeros=false
4169                         break
4170                 fi
4171         done
4172
4173         $all_zeros || return 0
4174
4175         # Write four bytes
4176         echo foo > $DIR/$tdir/bar
4177         # Really write them
4178         sync
4179
4180         # Total up write_bytes after writing.  We'd better find non-zeros.
4181         for ostnum in $(seq $OSTCOUNT); do
4182                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4183                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4184                               obdfilter/$ostname/stats |
4185                               awk '/^write_bytes/ {print $7}' )
4186                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4187                 if (( ${write_bytes:-0} > 0 )); then
4188                         all_zeros=false
4189                         break
4190                 fi
4191         done
4192
4193         if $all_zeros; then
4194                 for ostnum in $(seq $OSTCOUNT); do
4195                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4196                         echo "Check write_bytes is in obdfilter.*.stats:"
4197                         do_facet ost$ostnum lctl get_param -n \
4198                                 obdfilter.$ostname.stats
4199                 done
4200                 error "OST not keeping write_bytes stats (b=22312)"
4201         fi
4202 }
4203 run_test 33c "test write_bytes stats"
4204
4205 test_33d() {
4206         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4208
4209         local MDTIDX=1
4210         local remote_dir=$DIR/$tdir/remote_dir
4211
4212         test_mkdir $DIR/$tdir
4213         $LFS mkdir -i $MDTIDX $remote_dir ||
4214                 error "create remote directory failed"
4215
4216         touch $remote_dir/$tfile
4217         chmod 444 $remote_dir/$tfile
4218         chown $RUNAS_ID $remote_dir/$tfile
4219
4220         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4221
4222         chown $RUNAS_ID $remote_dir
4223         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4224                                         error "create" || true
4225         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4226                                     error "open RDWR" || true
4227         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4228 }
4229 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4230
4231 test_33e() {
4232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4233
4234         mkdir $DIR/$tdir
4235
4236         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4237         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4238         mkdir $DIR/$tdir/local_dir
4239
4240         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4241         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4242         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4243
4244         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4245                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4246
4247         rmdir $DIR/$tdir/* || error "rmdir failed"
4248
4249         umask 777
4250         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4251         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4252         mkdir $DIR/$tdir/local_dir
4253
4254         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4255         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4256         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4257
4258         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4259                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4260
4261         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4262
4263         umask 000
4264         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4265         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4266         mkdir $DIR/$tdir/local_dir
4267
4268         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4269         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4270         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4271
4272         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4273                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4274 }
4275 run_test 33e "mkdir and striped directory should have same mode"
4276
4277 cleanup_33f() {
4278         trap 0
4279         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4280 }
4281
4282 test_33f() {
4283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4284         remote_mds_nodsh && skip "remote MDS with nodsh"
4285
4286         mkdir $DIR/$tdir
4287         chmod go+rwx $DIR/$tdir
4288         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4289         trap cleanup_33f EXIT
4290
4291         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4292                 error "cannot create striped directory"
4293
4294         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4295                 error "cannot create files in striped directory"
4296
4297         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4298                 error "cannot remove files in striped directory"
4299
4300         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4301                 error "cannot remove striped directory"
4302
4303         cleanup_33f
4304 }
4305 run_test 33f "nonroot user can create, access, and remove a striped directory"
4306
4307 test_33g() {
4308         mkdir -p $DIR/$tdir/dir2
4309
4310         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4311         echo $err
4312         [[ $err =~ "exists" ]] || error "Not exists error"
4313 }
4314 run_test 33g "nonroot user create already existing root created file"
4315
4316 sub_33h() {
4317         local hash_type=$1
4318         local count=250
4319
4320         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4321                 error "lfs mkdir -H $hash_type $tdir failed"
4322         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4323
4324         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4325         local index2
4326         local fname
4327
4328         for fname in $DIR/$tdir/$tfile.bak \
4329                      $DIR/$tdir/$tfile.SAV \
4330                      $DIR/$tdir/$tfile.orig \
4331                      $DIR/$tdir/$tfile~; do
4332                 touch $fname || error "touch $fname failed"
4333                 index2=$($LFS getstripe -m $fname)
4334                 (( $index == $index2 )) ||
4335                         error "$fname MDT index mismatch $index != $index2"
4336         done
4337
4338         local failed=0
4339         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4340         local pattern
4341
4342         for pattern in ${patterns[*]}; do
4343                 echo "pattern $pattern"
4344                 fname=$DIR/$tdir/$pattern
4345                 for (( i = 0; i < $count; i++ )); do
4346                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4347                                 error "mktemp $DIR/$tdir/$pattern failed"
4348                         index2=$($LFS getstripe -m $fname)
4349                         (( $index == $index2 )) && continue
4350
4351                         failed=$((failed + 1))
4352                         echo "$fname MDT index mismatch $index != $index2"
4353                 done
4354         done
4355
4356         echo "$failed/$count MDT index mismatches, expect ~2-4"
4357         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4358
4359         local same=0
4360         local expect
4361
4362         # verify that "crush" is still broken with all files on same MDT,
4363         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4364         [[ "$hash_type" == "crush" ]] && expect=$count ||
4365                 expect=$((count / MDSCOUNT))
4366
4367         # crush2 doesn't put all-numeric suffixes on the same MDT,
4368         # filename like $tfile.12345678 should *not* be considered temp
4369         for pattern in ${patterns[*]}; do
4370                 local base=${pattern%%X*}
4371                 local suff=${pattern#$base}
4372
4373                 echo "pattern $pattern"
4374                 for (( i = 0; i < $count; i++ )); do
4375                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4376                         touch $fname || error "touch $fname failed"
4377                         index2=$($LFS getstripe -m $fname)
4378                         (( $index != $index2 )) && continue
4379
4380                         same=$((same + 1))
4381                 done
4382         done
4383
4384         # the number of "bad" hashes is random, as it depends on the random
4385         # filenames generated by "mktemp".  Allow some margin in the results.
4386         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4387         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4388            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4389                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4390         same=0
4391
4392         # crush2 doesn't put suffixes with special characters on the same MDT
4393         # filename like $tfile.txt.1234 should *not* be considered temp
4394         for pattern in ${patterns[*]}; do
4395                 local base=${pattern%%X*}
4396                 local suff=${pattern#$base}
4397
4398                 pattern=$base...${suff/XXX}
4399                 echo "pattern=$pattern"
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4402                                 error "touch $fname failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index != $index2 )) && continue
4405
4406                         same=$((same + 1))
4407                 done
4408         done
4409
4410         # the number of "bad" hashes is random, as it depends on the random
4411         # filenames generated by "mktemp".  Allow some margin in the results.
4412         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4413         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4414            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4415                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4416 }
4417
4418 test_33h() {
4419         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4420         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4421                 skip "Need MDS version at least 2.13.50"
4422
4423         sub_33h crush
4424 }
4425 run_test 33h "temp file is located on the same MDT as target (crush)"
4426
4427 test_33hh() {
4428         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4429         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4430         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4431                 skip "Need MDS version at least 2.15.0 for crush2"
4432
4433         sub_33h crush2
4434 }
4435 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4436
4437 test_33i()
4438 {
4439         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4440
4441         local FNAME=$(str_repeat 'f' 250)
4442
4443         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4444         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4445
4446         local count
4447         local total
4448
4449         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4450
4451         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4452
4453         lctl --device %$MDC deactivate
4454         stack_trap "lctl --device %$MDC activate"
4455         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4456         total=$(\ls -l $DIR/$tdir | wc -l)
4457         # "ls -l" will list total in the first line
4458         total=$((total - 1))
4459         (( total + count == 1000 )) ||
4460                 error "ls list $total files, $count files on MDT1"
4461 }
4462 run_test 33i "striped directory can be accessed when one MDT is down"
4463
4464 test_33j() {
4465         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4466
4467         mkdir -p $DIR/$tdir/
4468
4469         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4470                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4471
4472         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4473                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4474
4475         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4476                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4477
4478         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4479                 error "-D was not specified, but still failed"
4480 }
4481 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4482
4483 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4484 test_34a() {
4485         rm -f $DIR/f34
4486         $MCREATE $DIR/f34 || error "mcreate failed"
4487         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4488                 error "getstripe failed"
4489         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4490         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4491                 error "getstripe failed"
4492         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4493                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4494 }
4495 run_test 34a "truncate file that has not been opened ==========="
4496
4497 test_34b() {
4498         [ ! -f $DIR/f34 ] && test_34a
4499         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4500                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4501         $OPENFILE -f O_RDONLY $DIR/f34
4502         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4503                 error "getstripe failed"
4504         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4505                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4506 }
4507 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4508
4509 test_34c() {
4510         [ ! -f $DIR/f34 ] && test_34a
4511         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4512                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4513         $OPENFILE -f O_RDWR $DIR/f34
4514         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4515                 error "$LFS getstripe failed"
4516         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4517                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4518 }
4519 run_test 34c "O_RDWR opening file-with-size works =============="
4520
4521 test_34d() {
4522         [ ! -f $DIR/f34 ] && test_34a
4523         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4524                 error "dd failed"
4525         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4526                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4527         rm $DIR/f34
4528 }
4529 run_test 34d "write to sparse file ============================="
4530
4531 test_34e() {
4532         rm -f $DIR/f34e
4533         $MCREATE $DIR/f34e || error "mcreate failed"
4534         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4535         $CHECKSTAT -s 1000 $DIR/f34e ||
4536                 error "Size of $DIR/f34e not equal to 1000 bytes"
4537         $OPENFILE -f O_RDWR $DIR/f34e
4538         $CHECKSTAT -s 1000 $DIR/f34e ||
4539                 error "Size of $DIR/f34e not equal to 1000 bytes"
4540 }
4541 run_test 34e "create objects, some with size and some without =="
4542
4543 test_34f() { # bug 6242, 6243
4544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4545
4546         SIZE34F=48000
4547         rm -f $DIR/f34f
4548         $MCREATE $DIR/f34f || error "mcreate failed"
4549         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4550         dd if=$DIR/f34f of=$TMP/f34f
4551         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4552         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4553         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4554         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4555         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4556 }
4557 run_test 34f "read from a file with no objects until EOF ======="
4558
4559 test_34g() {
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4563                 error "dd failed"
4564         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4565         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4566                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4567         cancel_lru_locks osc
4568         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4569                 error "wrong size after lock cancel"
4570
4571         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4572         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4573                 error "expanding truncate failed"
4574         cancel_lru_locks osc
4575         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4576                 error "wrong expanded size after lock cancel"
4577 }
4578 run_test 34g "truncate long file ==============================="
4579
4580 test_34h() {
4581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4582
4583         local gid=10
4584         local sz=1000
4585
4586         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4587         sync # Flush the cache so that multiop below does not block on cache
4588              # flush when getting the group lock
4589         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4590         MULTIPID=$!
4591
4592         # Since just timed wait is not good enough, let's do a sync write
4593         # that way we are sure enough time for a roundtrip + processing
4594         # passed + 2 seconds of extra margin.
4595         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4596         rm $DIR/${tfile}-1
4597         sleep 2
4598
4599         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4600                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4601                 kill -9 $MULTIPID
4602         fi
4603         wait $MULTIPID
4604         local nsz=`stat -c %s $DIR/$tfile`
4605         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4606 }
4607 run_test 34h "ftruncate file under grouplock should not block"
4608
4609 test_35a() {
4610         cp /bin/sh $DIR/f35a
4611         chmod 444 $DIR/f35a
4612         chown $RUNAS_ID $DIR/f35a
4613         $RUNAS $DIR/f35a && error || true
4614         rm $DIR/f35a
4615 }
4616 run_test 35a "exec file with mode 444 (should return and not leak)"
4617
4618 test_36a() {
4619         rm -f $DIR/f36
4620         utime $DIR/f36 || error "utime failed for MDS"
4621 }
4622 run_test 36a "MDS utime check (mknod, utime)"
4623
4624 test_36b() {
4625         echo "" > $DIR/f36
4626         utime $DIR/f36 || error "utime failed for OST"
4627 }
4628 run_test 36b "OST utime check (open, utime)"
4629
4630 test_36c() {
4631         rm -f $DIR/d36/f36
4632         test_mkdir $DIR/d36
4633         chown $RUNAS_ID $DIR/d36
4634         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4635 }
4636 run_test 36c "non-root MDS utime check (mknod, utime)"
4637
4638 test_36d() {
4639         [ ! -d $DIR/d36 ] && test_36c
4640         echo "" > $DIR/d36/f36
4641         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4642 }
4643 run_test 36d "non-root OST utime check (open, utime)"
4644
4645 test_36e() {
4646         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4647
4648         test_mkdir $DIR/$tdir
4649         touch $DIR/$tdir/$tfile
4650         $RUNAS utime $DIR/$tdir/$tfile &&
4651                 error "utime worked, expected failure" || true
4652 }
4653 run_test 36e "utime on non-owned file (should return error)"
4654
4655 subr_36fh() {
4656         local fl="$1"
4657         local LANG_SAVE=$LANG
4658         local LC_LANG_SAVE=$LC_LANG
4659         export LANG=C LC_LANG=C # for date language
4660
4661         DATESTR="Dec 20  2000"
4662         test_mkdir $DIR/$tdir
4663         lctl set_param fail_loc=$fl
4664         date; date +%s
4665         cp /etc/hosts $DIR/$tdir/$tfile
4666         sync & # write RPC generated with "current" inode timestamp, but delayed
4667         sleep 1
4668         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4669         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4670         cancel_lru_locks $OSC
4671         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4672         date; date +%s
4673         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4674                 echo "BEFORE: $LS_BEFORE" && \
4675                 echo "AFTER : $LS_AFTER" && \
4676                 echo "WANT  : $DATESTR" && \
4677                 error "$DIR/$tdir/$tfile timestamps changed" || true
4678
4679         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4680 }
4681
4682 test_36f() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4686         subr_36fh "0x80000214"
4687 }
4688 run_test 36f "utime on file racing with OST BRW write =========="
4689
4690 test_36g() {
4691         remote_ost_nodsh && skip "remote OST with nodsh"
4692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4693         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4694                 skip "Need MDS version at least 2.12.51"
4695
4696         local fmd_max_age
4697         local fmd
4698         local facet="ost1"
4699         local tgt="obdfilter"
4700
4701         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4702
4703         test_mkdir $DIR/$tdir
4704         fmd_max_age=$(do_facet $facet \
4705                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4706                 head -n 1")
4707
4708         echo "FMD max age: ${fmd_max_age}s"
4709         touch $DIR/$tdir/$tfile
4710         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4711                 gawk '{cnt=cnt+$1}  END{print cnt}')
4712         echo "FMD before: $fmd"
4713         [[ $fmd == 0 ]] &&
4714                 error "FMD wasn't create by touch"
4715         sleep $((fmd_max_age + 12))
4716         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4717                 gawk '{cnt=cnt+$1}  END{print cnt}')
4718         echo "FMD after: $fmd"
4719         [[ $fmd == 0 ]] ||
4720                 error "FMD wasn't expired by ping"
4721 }
4722 run_test 36g "FMD cache expiry ====================="
4723
4724 test_36h() {
4725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4726
4727         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4728         subr_36fh "0x80000227"
4729 }
4730 run_test 36h "utime on file racing with OST BRW write =========="
4731
4732 test_36i() {
4733         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4734
4735         test_mkdir $DIR/$tdir
4736         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4737
4738         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4739         local new_mtime=$((mtime + 200))
4740
4741         #change Modify time of striped dir
4742         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4743                         error "change mtime failed"
4744
4745         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4746
4747         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4748 }
4749 run_test 36i "change mtime on striped directory"
4750
4751 # test_37 - duplicate with tests 32q 32r
4752
4753 test_38() {
4754         local file=$DIR/$tfile
4755         touch $file
4756         openfile -f O_DIRECTORY $file
4757         local RC=$?
4758         local ENOTDIR=20
4759         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4760         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4761 }
4762 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4763
4764 test_39a() { # was test_39
4765         touch $DIR/$tfile
4766         touch $DIR/${tfile}2
4767 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4768 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4769 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4770         sleep 2
4771         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4772         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4773                 echo "mtime"
4774                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4775                 echo "atime"
4776                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4777                 echo "ctime"
4778                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4779                 error "O_TRUNC didn't change timestamps"
4780         fi
4781 }
4782 run_test 39a "mtime changed on create"
4783
4784 test_39b() {
4785         test_mkdir -c1 $DIR/$tdir
4786         cp -p /etc/passwd $DIR/$tdir/fopen
4787         cp -p /etc/passwd $DIR/$tdir/flink
4788         cp -p /etc/passwd $DIR/$tdir/funlink
4789         cp -p /etc/passwd $DIR/$tdir/frename
4790         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4791
4792         sleep 1
4793         echo "aaaaaa" >> $DIR/$tdir/fopen
4794         echo "aaaaaa" >> $DIR/$tdir/flink
4795         echo "aaaaaa" >> $DIR/$tdir/funlink
4796         echo "aaaaaa" >> $DIR/$tdir/frename
4797
4798         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4799         local link_new=`stat -c %Y $DIR/$tdir/flink`
4800         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4801         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4802
4803         cat $DIR/$tdir/fopen > /dev/null
4804         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4805         rm -f $DIR/$tdir/funlink2
4806         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4807
4808         for (( i=0; i < 2; i++ )) ; do
4809                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4810                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4811                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4812                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4813
4814                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4815                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4816                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4817                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4818
4819                 cancel_lru_locks $OSC
4820                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4821         done
4822 }
4823 run_test 39b "mtime change on open, link, unlink, rename  ======"
4824
4825 # this should be set to past
4826 TEST_39_MTIME=`date -d "1 year ago" +%s`
4827
4828 # bug 11063
4829 test_39c() {
4830         touch $DIR1/$tfile
4831         sleep 2
4832         local mtime0=`stat -c %Y $DIR1/$tfile`
4833
4834         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4835         local mtime1=`stat -c %Y $DIR1/$tfile`
4836         [ "$mtime1" = $TEST_39_MTIME ] || \
4837                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4838
4839         local d1=`date +%s`
4840         echo hello >> $DIR1/$tfile
4841         local d2=`date +%s`
4842         local mtime2=`stat -c %Y $DIR1/$tfile`
4843         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4844                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4845
4846         mv $DIR1/$tfile $DIR1/$tfile-1
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4850                 [ "$mtime2" = "$mtime3" ] || \
4851                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4852
4853                 cancel_lru_locks $OSC
4854                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4855         done
4856 }
4857 run_test 39c "mtime change on rename ==========================="
4858
4859 # bug 21114
4860 test_39d() {
4861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4862
4863         touch $DIR1/$tfile
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4870
4871                 cancel_lru_locks $OSC
4872                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4873         done
4874 }
4875 run_test 39d "create, utime, stat =============================="
4876
4877 # bug 21114
4878 test_39e() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         touch $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4885
4886         for (( i=0; i < 2; i++ )) ; do
4887                 local mtime2=`stat -c %Y $DIR1/$tfile`
4888                 [ $mtime2 = $TEST_39_MTIME ] || \
4889                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4890
4891                 cancel_lru_locks $OSC
4892                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4893         done
4894 }
4895 run_test 39e "create, stat, utime, stat ========================"
4896
4897 # bug 21114
4898 test_39f() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         touch $DIR1/$tfile
4902         mtime1=`stat -c %Y $DIR1/$tfile`
4903
4904         sleep 2
4905         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4906
4907         for (( i=0; i < 2; i++ )) ; do
4908                 local mtime2=`stat -c %Y $DIR1/$tfile`
4909                 [ $mtime2 = $TEST_39_MTIME ] || \
4910                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4911
4912                 cancel_lru_locks $OSC
4913                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4914         done
4915 }
4916 run_test 39f "create, stat, sleep, utime, stat ================="
4917
4918 # bug 11063
4919 test_39g() {
4920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4921
4922         echo hello >> $DIR1/$tfile
4923         local mtime1=`stat -c %Y $DIR1/$tfile`
4924
4925         sleep 2
4926         chmod o+r $DIR1/$tfile
4927
4928         for (( i=0; i < 2; i++ )) ; do
4929                 local mtime2=`stat -c %Y $DIR1/$tfile`
4930                 [ "$mtime1" = "$mtime2" ] || \
4931                         error "lost mtime: $mtime2, should be $mtime1"
4932
4933                 cancel_lru_locks $OSC
4934                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4935         done
4936 }
4937 run_test 39g "write, chmod, stat ==============================="
4938
4939 # bug 11063
4940 test_39h() {
4941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4942
4943         touch $DIR1/$tfile
4944         sleep 1
4945
4946         local d1=`date`
4947         echo hello >> $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949
4950         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4951         local d2=`date`
4952         if [ "$d1" != "$d2" ]; then
4953                 echo "write and touch not within one second"
4954         else
4955                 for (( i=0; i < 2; i++ )) ; do
4956                         local mtime2=`stat -c %Y $DIR1/$tfile`
4957                         [ "$mtime2" = $TEST_39_MTIME ] || \
4958                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4959
4960                         cancel_lru_locks $OSC
4961                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4962                 done
4963         fi
4964 }
4965 run_test 39h "write, utime within one second, stat ============="
4966
4967 test_39i() {
4968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4969
4970         touch $DIR1/$tfile
4971         sleep 1
4972
4973         echo hello >> $DIR1/$tfile
4974         local mtime1=`stat -c %Y $DIR1/$tfile`
4975
4976         mv $DIR1/$tfile $DIR1/$tfile-1
4977
4978         for (( i=0; i < 2; i++ )) ; do
4979                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4980
4981                 [ "$mtime1" = "$mtime2" ] || \
4982                         error "lost mtime: $mtime2, should be $mtime1"
4983
4984                 cancel_lru_locks $OSC
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39i "write, rename, stat =============================="
4989
4990 test_39j() {
4991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4992
4993         start_full_debug_logging
4994         touch $DIR1/$tfile
4995         sleep 1
4996
4997         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4998         lctl set_param fail_loc=0x80000412
4999         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5000                 error "multiop failed"
5001         local multipid=$!
5002         local mtime1=`stat -c %Y $DIR1/$tfile`
5003
5004         mv $DIR1/$tfile $DIR1/$tfile-1
5005
5006         kill -USR1 $multipid
5007         wait $multipid || error "multiop close failed"
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5011                 [ "$mtime1" = "$mtime2" ] ||
5012                         error "mtime is lost on close: $mtime2, " \
5013                               "should be $mtime1"
5014
5015                 cancel_lru_locks
5016                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5017         done
5018         lctl set_param fail_loc=0
5019         stop_full_debug_logging
5020 }
5021 run_test 39j "write, rename, close, stat ======================="
5022
5023 test_39k() {
5024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5025
5026         touch $DIR1/$tfile
5027         sleep 1
5028
5029         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5030         local multipid=$!
5031         local mtime1=`stat -c %Y $DIR1/$tfile`
5032
5033         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5034
5035         kill -USR1 $multipid
5036         wait $multipid || error "multiop close failed"
5037
5038         for (( i=0; i < 2; i++ )) ; do
5039                 local mtime2=`stat -c %Y $DIR1/$tfile`
5040
5041                 [ "$mtime2" = $TEST_39_MTIME ] || \
5042                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5043
5044                 cancel_lru_locks
5045                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5046         done
5047 }
5048 run_test 39k "write, utime, close, stat ========================"
5049
5050 # this should be set to future
5051 TEST_39_ATIME=`date -d "1 year" +%s`
5052
5053 test_39l() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055         remote_mds_nodsh && skip "remote MDS with nodsh"
5056
5057         local atime_diff=$(do_facet $SINGLEMDS \
5058                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5059         rm -rf $DIR/$tdir
5060         mkdir_on_mdt0 $DIR/$tdir
5061
5062         # test setting directory atime to future
5063         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5064         local atime=$(stat -c %X $DIR/$tdir)
5065         [ "$atime" = $TEST_39_ATIME ] ||
5066                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5067
5068         # test setting directory atime from future to now
5069         local now=$(date +%s)
5070         touch -a -d @$now $DIR/$tdir
5071
5072         atime=$(stat -c %X $DIR/$tdir)
5073         [ "$atime" -eq "$now"  ] ||
5074                 error "atime is not updated from future: $atime, $now"
5075
5076         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5077         sleep 3
5078
5079         # test setting directory atime when now > dir atime + atime_diff
5080         local d1=$(date +%s)
5081         ls $DIR/$tdir
5082         local d2=$(date +%s)
5083         cancel_lru_locks mdc
5084         atime=$(stat -c %X $DIR/$tdir)
5085         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5086                 error "atime is not updated  : $atime, should be $d2"
5087
5088         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5089         sleep 3
5090
5091         # test not setting directory atime when now < dir atime + atime_diff
5092         ls $DIR/$tdir
5093         cancel_lru_locks mdc
5094         atime=$(stat -c %X $DIR/$tdir)
5095         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5096                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5097
5098         do_facet $SINGLEMDS \
5099                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5100 }
5101 run_test 39l "directory atime update ==========================="
5102
5103 test_39m() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105
5106         touch $DIR1/$tfile
5107         sleep 2
5108         local far_past_mtime=$(date -d "May 29 1953" +%s)
5109         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5110
5111         touch -m -d @$far_past_mtime $DIR1/$tfile
5112         touch -a -d @$far_past_atime $DIR1/$tfile
5113
5114         for (( i=0; i < 2; i++ )) ; do
5115                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5116                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5117                         error "atime or mtime set incorrectly"
5118
5119                 cancel_lru_locks $OSC
5120                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5121         done
5122 }
5123 run_test 39m "test atime and mtime before 1970"
5124
5125 test_39n() { # LU-3832
5126         remote_mds_nodsh && skip "remote MDS with nodsh"
5127
5128         local atime_diff=$(do_facet $SINGLEMDS \
5129                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5130         local atime0
5131         local atime1
5132         local atime2
5133
5134         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5135
5136         rm -rf $DIR/$tfile
5137         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5138         atime0=$(stat -c %X $DIR/$tfile)
5139
5140         sleep 5
5141         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5142         atime1=$(stat -c %X $DIR/$tfile)
5143
5144         sleep 5
5145         cancel_lru_locks mdc
5146         cancel_lru_locks osc
5147         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5148         atime2=$(stat -c %X $DIR/$tfile)
5149
5150         do_facet $SINGLEMDS \
5151                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5152
5153         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5154         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5155 }
5156 run_test 39n "check that O_NOATIME is honored"
5157
5158 test_39o() {
5159         TESTDIR=$DIR/$tdir/$tfile
5160         [ -e $TESTDIR ] && rm -rf $TESTDIR
5161         mkdir -p $TESTDIR
5162         cd $TESTDIR
5163         links1=2
5164         ls
5165         mkdir a b
5166         ls
5167         links2=$(stat -c %h .)
5168         [ $(($links1 + 2)) != $links2 ] &&
5169                 error "wrong links count $(($links1 + 2)) != $links2"
5170         rmdir b
5171         links3=$(stat -c %h .)
5172         [ $(($links1 + 1)) != $links3 ] &&
5173                 error "wrong links count $links1 != $links3"
5174         return 0
5175 }
5176 run_test 39o "directory cached attributes updated after create"
5177
5178 test_39p() {
5179         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5180
5181         local MDTIDX=1
5182         TESTDIR=$DIR/$tdir/$tdir
5183         [ -e $TESTDIR ] && rm -rf $TESTDIR
5184         test_mkdir -p $TESTDIR
5185         cd $TESTDIR
5186         links1=2
5187         ls
5188         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5189         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5190         ls
5191         links2=$(stat -c %h .)
5192         [ $(($links1 + 2)) != $links2 ] &&
5193                 error "wrong links count $(($links1 + 2)) != $links2"
5194         rmdir remote_dir2
5195         links3=$(stat -c %h .)
5196         [ $(($links1 + 1)) != $links3 ] &&
5197                 error "wrong links count $links1 != $links3"
5198         return 0
5199 }
5200 run_test 39p "remote directory cached attributes updated after create ========"
5201
5202 test_39r() {
5203         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5204                 skip "no atime update on old OST"
5205         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5206                 skip_env "ldiskfs only test"
5207         fi
5208
5209         local saved_adiff
5210         saved_adiff=$(do_facet ost1 \
5211                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5212         stack_trap "do_facet ost1 \
5213                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5214
5215         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5216
5217         $LFS setstripe -i 0 $DIR/$tfile
5218         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5219                 error "can't write initial file"
5220         cancel_lru_locks osc
5221
5222         # exceed atime_diff and access file
5223         sleep 10
5224         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5225                 error "can't udpate atime"
5226
5227         local atime_cli=$(stat -c %X $DIR/$tfile)
5228         echo "client atime: $atime_cli"
5229         # allow atime update to be written to device
5230         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5231         sleep 5
5232
5233         local ostdev=$(ostdevname 1)
5234         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5235         local seq=${fid[3]#0x}
5236         local oid=${fid[1]}
5237         local oid_hex
5238
5239         if [ $seq == 0 ]; then
5240                 oid_hex=${fid[1]}
5241         else
5242                 oid_hex=${fid[2]#0x}
5243         fi
5244         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5245         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5246
5247         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5248         local atime_ost=$(do_facet ost1 "$cmd" |&
5249                           awk -F'[: ]' '/atime:/ { print $4 }')
5250         (( atime_cli == atime_ost )) ||
5251                 error "atime on client $atime_cli != ost $atime_ost"
5252 }
5253 run_test 39r "lazy atime update on OST"
5254
5255 test_39q() { # LU-8041
5256         local testdir=$DIR/$tdir
5257         mkdir -p $testdir
5258         multiop_bg_pause $testdir D_c || error "multiop failed"
5259         local multipid=$!
5260         cancel_lru_locks mdc
5261         kill -USR1 $multipid
5262         local atime=$(stat -c %X $testdir)
5263         [ "$atime" -ne 0 ] || error "atime is zero"
5264 }
5265 run_test 39q "close won't zero out atime"
5266
5267 test_39s() {
5268         local atime0
5269         local atime1
5270         local atime2
5271         local atime3
5272         local atime4
5273
5274         umount_client $MOUNT
5275         mount_client $MOUNT relatime
5276
5277         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5278         atime0=$(stat -c %X $DIR/$tfile)
5279
5280         # First read updates atime
5281         sleep 1
5282         cat $DIR/$tfile >/dev/null
5283         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5284
5285         # Next reads do not update atime
5286         sleep 1
5287         cat $DIR/$tfile >/dev/null
5288         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5289
5290         # If mtime is greater than atime, atime is updated
5291         sleep 1
5292         touch -m $DIR/$tfile # (mtime = now)
5293         sleep 1
5294         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5295         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5296
5297         # Next reads do not update atime
5298         sleep 1
5299         cat $DIR/$tfile >/dev/null
5300         atime4=$(stat -c %X $DIR/$tfile)
5301
5302         # Remount the client to clear 'relatime' option
5303         remount_client $MOUNT
5304
5305         (( atime0 < atime1 )) ||
5306                 error "atime $atime0 should be smaller than $atime1"
5307         (( atime1 == atime2 )) ||
5308                 error "atime $atime1 was updated to $atime2"
5309         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5310         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5311 }
5312 run_test 39s "relatime is supported"
5313
5314 test_40() {
5315         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5316         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5317                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5318         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5319                 error "$tfile is not 4096 bytes in size"
5320 }
5321 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5322
5323 test_41() {
5324         # bug 1553
5325         small_write $DIR/f41 18
5326 }
5327 run_test 41 "test small file write + fstat ====================="
5328
5329 count_ost_writes() {
5330         lctl get_param -n ${OSC}.*.stats |
5331                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5332                         END { printf("%0.0f", writes) }'
5333 }
5334
5335 # decent default
5336 WRITEBACK_SAVE=500
5337 DIRTY_RATIO_SAVE=40
5338 MAX_DIRTY_RATIO=50
5339 BG_DIRTY_RATIO_SAVE=10
5340 MAX_BG_DIRTY_RATIO=25
5341
5342 start_writeback() {
5343         trap 0
5344         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5345         # dirty_ratio, dirty_background_ratio
5346         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5347                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5348                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5349                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5350         else
5351                 # if file not here, we are a 2.4 kernel
5352                 kill -CONT `pidof kupdated`
5353         fi
5354 }
5355
5356 stop_writeback() {
5357         # setup the trap first, so someone cannot exit the test at the
5358         # exact wrong time and mess up a machine
5359         trap start_writeback EXIT
5360         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5361         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5362                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5363                 sysctl -w vm.dirty_writeback_centisecs=0
5364                 sysctl -w vm.dirty_writeback_centisecs=0
5365                 # save and increase /proc/sys/vm/dirty_ratio
5366                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5367                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5368                 # save and increase /proc/sys/vm/dirty_background_ratio
5369                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5370                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5371         else
5372                 # if file not here, we are a 2.4 kernel
5373                 kill -STOP `pidof kupdated`
5374         fi
5375 }
5376
5377 # ensure that all stripes have some grant before we test client-side cache
5378 setup_test42() {
5379         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5380                 dd if=/dev/zero of=$i bs=4k count=1
5381                 rm $i
5382         done
5383 }
5384
5385 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5386 # file truncation, and file removal.
5387 test_42a() {
5388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5389
5390         setup_test42
5391         cancel_lru_locks $OSC
5392         stop_writeback
5393         sync; sleep 1; sync # just to be safe
5394         BEFOREWRITES=`count_ost_writes`
5395         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5396         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5397         AFTERWRITES=`count_ost_writes`
5398         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5399                 error "$BEFOREWRITES < $AFTERWRITES"
5400         start_writeback
5401 }
5402 run_test 42a "ensure that we don't flush on close"
5403
5404 test_42b() {
5405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5406
5407         setup_test42
5408         cancel_lru_locks $OSC
5409         stop_writeback
5410         sync
5411         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5412         BEFOREWRITES=$(count_ost_writes)
5413         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5414         AFTERWRITES=$(count_ost_writes)
5415         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5416                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5417         fi
5418         BEFOREWRITES=$(count_ost_writes)
5419         sync || error "sync: $?"
5420         AFTERWRITES=$(count_ost_writes)
5421         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5422                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5423         fi
5424         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5425         start_writeback
5426         return 0
5427 }
5428 run_test 42b "test destroy of file with cached dirty data ======"
5429
5430 # if these tests just want to test the effect of truncation,
5431 # they have to be very careful.  consider:
5432 # - the first open gets a {0,EOF}PR lock
5433 # - the first write conflicts and gets a {0, count-1}PW
5434 # - the rest of the writes are under {count,EOF}PW
5435 # - the open for truncate tries to match a {0,EOF}PR
5436 #   for the filesize and cancels the PWs.
5437 # any number of fixes (don't get {0,EOF} on open, match
5438 # composite locks, do smarter file size management) fix
5439 # this, but for now we want these tests to verify that
5440 # the cancellation with truncate intent works, so we
5441 # start the file with a full-file pw lock to match against
5442 # until the truncate.
5443 trunc_test() {
5444         test=$1
5445         file=$DIR/$test
5446         offset=$2
5447         cancel_lru_locks $OSC
5448         stop_writeback
5449         # prime the file with 0,EOF PW to match
5450         touch $file
5451         $TRUNCATE $file 0
5452         sync; sync
5453         # now the real test..
5454         dd if=/dev/zero of=$file bs=1024 count=100
5455         BEFOREWRITES=`count_ost_writes`
5456         $TRUNCATE $file $offset
5457         cancel_lru_locks $OSC
5458         AFTERWRITES=`count_ost_writes`
5459         start_writeback
5460 }
5461
5462 test_42c() {
5463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5464
5465         trunc_test 42c 1024
5466         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5467                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5468         rm $file
5469 }
5470 run_test 42c "test partial truncate of file with cached dirty data"
5471
5472 test_42d() {
5473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5474
5475         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5476         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5477         $LCTL set_param debug=+cache
5478
5479         trunc_test 42d 0
5480         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5481                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5482         rm $file
5483 }
5484 run_test 42d "test complete truncate of file with cached dirty data"
5485
5486 test_42e() { # bug22074
5487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5488
5489         local TDIR=$DIR/${tdir}e
5490         local pages=16 # hardcoded 16 pages, don't change it.
5491         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5492         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5493         local max_dirty_mb
5494         local warmup_files
5495
5496         test_mkdir $DIR/${tdir}e
5497         $LFS setstripe -c 1 $TDIR
5498         createmany -o $TDIR/f $files
5499
5500         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5501
5502         # we assume that with $OSTCOUNT files, at least one of them will
5503         # be allocated on OST0.
5504         warmup_files=$((OSTCOUNT * max_dirty_mb))
5505         createmany -o $TDIR/w $warmup_files
5506
5507         # write a large amount of data into one file and sync, to get good
5508         # avail_grant number from OST.
5509         for ((i=0; i<$warmup_files; i++)); do
5510                 idx=$($LFS getstripe -i $TDIR/w$i)
5511                 [ $idx -ne 0 ] && continue
5512                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5513                 break
5514         done
5515         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5516         sync
5517         $LCTL get_param $proc_osc0/cur_dirty_bytes
5518         $LCTL get_param $proc_osc0/cur_grant_bytes
5519
5520         # create as much dirty pages as we can while not to trigger the actual
5521         # RPCs directly. but depends on the env, VFS may trigger flush during this
5522         # period, hopefully we are good.
5523         for ((i=0; i<$warmup_files; i++)); do
5524                 idx=$($LFS getstripe -i $TDIR/w$i)
5525                 [ $idx -ne 0 ] && continue
5526                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5527         done
5528         $LCTL get_param $proc_osc0/cur_dirty_bytes
5529         $LCTL get_param $proc_osc0/cur_grant_bytes
5530
5531         # perform the real test
5532         $LCTL set_param $proc_osc0/rpc_stats 0
5533         for ((;i<$files; i++)); do
5534                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5535                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5536         done
5537         sync
5538         $LCTL get_param $proc_osc0/rpc_stats
5539
5540         local percent=0
5541         local have_ppr=false
5542         $LCTL get_param $proc_osc0/rpc_stats |
5543                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5544                         # skip lines until we are at the RPC histogram data
5545                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5546                         $have_ppr || continue
5547
5548                         # we only want the percent stat for < 16 pages
5549                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5550
5551                         percent=$((percent + WPCT))
5552                         if [[ $percent -gt 15 ]]; then
5553                                 error "less than 16-pages write RPCs" \
5554                                       "$percent% > 15%"
5555                                 break
5556                         fi
5557                 done
5558         rm -rf $TDIR
5559 }
5560 run_test 42e "verify sub-RPC writes are not done synchronously"
5561
5562 test_43A() { # was test_43
5563         test_mkdir $DIR/$tdir
5564         cp -p /bin/ls $DIR/$tdir/$tfile
5565         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5566         pid=$!
5567         # give multiop a chance to open
5568         sleep 1
5569
5570         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5571         kill -USR1 $pid
5572         # Wait for multiop to exit
5573         wait $pid
5574 }
5575 run_test 43A "execution of file opened for write should return -ETXTBSY"
5576
5577 test_43a() {
5578         test_mkdir $DIR/$tdir
5579         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5580         $DIR/$tdir/sleep 60 &
5581         SLEEP_PID=$!
5582         # Make sure exec of $tdir/sleep wins race with truncate
5583         sleep 1
5584         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5585         kill $SLEEP_PID
5586 }
5587 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5588
5589 test_43b() {
5590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5591
5592         test_mkdir $DIR/$tdir
5593         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5594         $DIR/$tdir/sleep 60 &
5595         SLEEP_PID=$!
5596         # Make sure exec of $tdir/sleep wins race with truncate
5597         sleep 1
5598         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5599         kill $SLEEP_PID
5600 }
5601 run_test 43b "truncate of file being executed should return -ETXTBSY"
5602
5603 test_43c() {
5604         local testdir="$DIR/$tdir"
5605         test_mkdir $testdir
5606         cp $SHELL $testdir/
5607         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5608                 ( cd $testdir && md5sum -c )
5609 }
5610 run_test 43c "md5sum of copy into lustre"
5611
5612 test_44A() { # was test_44
5613         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5614
5615         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5616         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5617 }
5618 run_test 44A "zero length read from a sparse stripe"
5619
5620 test_44a() {
5621         local nstripe=$($LFS getstripe -c -d $DIR)
5622         [ -z "$nstripe" ] && skip "can't get stripe info"
5623         [[ $nstripe -gt $OSTCOUNT ]] &&
5624                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5625
5626         local stride=$($LFS getstripe -S -d $DIR)
5627         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5628                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5629         fi
5630
5631         OFFSETS="0 $((stride/2)) $((stride-1))"
5632         for offset in $OFFSETS; do
5633                 for i in $(seq 0 $((nstripe-1))); do
5634                         local GLOBALOFFSETS=""
5635                         # size in Bytes
5636                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5637                         local myfn=$DIR/d44a-$size
5638                         echo "--------writing $myfn at $size"
5639                         ll_sparseness_write $myfn $size ||
5640                                 error "ll_sparseness_write"
5641                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5642                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5643                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5644
5645                         for j in $(seq 0 $((nstripe-1))); do
5646                                 # size in Bytes
5647                                 size=$((((j + $nstripe )*$stride + $offset)))
5648                                 ll_sparseness_write $myfn $size ||
5649                                         error "ll_sparseness_write"
5650                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5651                         done
5652                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5653                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5654                         rm -f $myfn
5655                 done
5656         done
5657 }
5658 run_test 44a "test sparse pwrite ==============================="
5659
5660 dirty_osc_total() {
5661         tot=0
5662         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5663                 tot=$(($tot + $d))
5664         done
5665         echo $tot
5666 }
5667 do_dirty_record() {
5668         before=`dirty_osc_total`
5669         echo executing "\"$*\""
5670         eval $*
5671         after=`dirty_osc_total`
5672         echo before $before, after $after
5673 }
5674 test_45() {
5675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5676
5677         f="$DIR/f45"
5678         # Obtain grants from OST if it supports it
5679         echo blah > ${f}_grant
5680         stop_writeback
5681         sync
5682         do_dirty_record "echo blah > $f"
5683         [[ $before -eq $after ]] && error "write wasn't cached"
5684         do_dirty_record "> $f"
5685         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5686         do_dirty_record "echo blah > $f"
5687         [[ $before -eq $after ]] && error "write wasn't cached"
5688         do_dirty_record "sync"
5689         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5690         do_dirty_record "echo blah > $f"
5691         [[ $before -eq $after ]] && error "write wasn't cached"
5692         do_dirty_record "cancel_lru_locks osc"
5693         [[ $before -gt $after ]] ||
5694                 error "lock cancellation didn't lower dirty count"
5695         start_writeback
5696 }
5697 run_test 45 "osc io page accounting ============================"
5698
5699 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5700 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5701 # objects offset and an assert hit when an rpc was built with 1023's mapped
5702 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5703 test_46() {
5704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5705
5706         f="$DIR/f46"
5707         stop_writeback
5708         sync
5709         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5710         sync
5711         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5712         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5713         sync
5714         start_writeback
5715 }
5716 run_test 46 "dirtying a previously written page ================"
5717
5718 # test_47 is removed "Device nodes check" is moved to test_28
5719
5720 test_48a() { # bug 2399
5721         [ "$mds1_FSTYPE" = "zfs" ] &&
5722         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5723                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5724
5725         test_mkdir $DIR/$tdir
5726         cd $DIR/$tdir
5727         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5728         test_mkdir $DIR/$tdir
5729         touch foo || error "'touch foo' failed after recreating cwd"
5730         test_mkdir bar
5731         touch .foo || error "'touch .foo' failed after recreating cwd"
5732         test_mkdir .bar
5733         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5734         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5735         cd . || error "'cd .' failed after recreating cwd"
5736         mkdir . && error "'mkdir .' worked after recreating cwd"
5737         rmdir . && error "'rmdir .' worked after recreating cwd"
5738         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5739         cd .. || error "'cd ..' failed after recreating cwd"
5740 }
5741 run_test 48a "Access renamed working dir (should return errors)="
5742
5743 test_48b() { # bug 2399
5744         rm -rf $DIR/$tdir
5745         test_mkdir $DIR/$tdir
5746         cd $DIR/$tdir
5747         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5748         touch foo && error "'touch foo' worked after removing cwd"
5749         mkdir foo && error "'mkdir foo' worked after removing cwd"
5750         touch .foo && error "'touch .foo' worked after removing cwd"
5751         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5752         ls . > /dev/null && error "'ls .' worked after removing cwd"
5753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5754         mkdir . && error "'mkdir .' worked after removing cwd"
5755         rmdir . && error "'rmdir .' worked after removing cwd"
5756         ln -s . foo && error "'ln -s .' worked after removing cwd"
5757         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5758 }
5759 run_test 48b "Access removed working dir (should return errors)="
5760
5761 test_48c() { # bug 2350
5762         #lctl set_param debug=-1
5763         #set -vx
5764         rm -rf $DIR/$tdir
5765         test_mkdir -p $DIR/$tdir/dir
5766         cd $DIR/$tdir/dir
5767         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5768         $TRACE touch foo && error "touch foo worked after removing cwd"
5769         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5770         touch .foo && error "touch .foo worked after removing cwd"
5771         mkdir .foo && error "mkdir .foo worked after removing cwd"
5772         $TRACE ls . && error "'ls .' worked after removing cwd"
5773         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5774         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5775         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5776         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5777         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5778 }
5779 run_test 48c "Access removed working subdir (should return errors)"
5780
5781 test_48d() { # bug 2350
5782         #lctl set_param debug=-1
5783         #set -vx
5784         rm -rf $DIR/$tdir
5785         test_mkdir -p $DIR/$tdir/dir
5786         cd $DIR/$tdir/dir
5787         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5788         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5789         $TRACE touch foo && error "'touch foo' worked after removing parent"
5790         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5791         touch .foo && error "'touch .foo' worked after removing parent"
5792         mkdir .foo && error "mkdir .foo worked after removing parent"
5793         $TRACE ls . && error "'ls .' worked after removing parent"
5794         $TRACE ls .. && error "'ls ..' worked after removing parent"
5795         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5796         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5797         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5798         true
5799 }
5800 run_test 48d "Access removed parent subdir (should return errors)"
5801
5802 test_48e() { # bug 4134
5803         #lctl set_param debug=-1
5804         #set -vx
5805         rm -rf $DIR/$tdir
5806         test_mkdir -p $DIR/$tdir/dir
5807         cd $DIR/$tdir/dir
5808         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5809         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5810         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5811         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5812         # On a buggy kernel addition of "touch foo" after cd .. will
5813         # produce kernel oops in lookup_hash_it
5814         touch ../foo && error "'cd ..' worked after recreate parent"
5815         cd $DIR
5816         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5817 }
5818 run_test 48e "Access to recreated parent subdir (should return errors)"
5819
5820 test_48f() {
5821         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5822                 skip "need MDS >= 2.13.55"
5823         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5824         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5825                 skip "needs different host for mdt1 mdt2"
5826         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5827
5828         $LFS mkdir -i0 $DIR/$tdir
5829         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5830
5831         for d in sub1 sub2 sub3; do
5832                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5833                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5834                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5835         done
5836
5837         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5838 }
5839 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5840
5841 test_49() { # LU-1030
5842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5843         remote_ost_nodsh && skip "remote OST with nodsh"
5844
5845         # get ost1 size - $FSNAME-OST0000
5846         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5847                 awk '{ print $4 }')
5848         # write 800M at maximum
5849         [[ $ost1_size -lt 2 ]] && ost1_size=2
5850         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5851
5852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5853         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5854         local dd_pid=$!
5855
5856         # change max_pages_per_rpc while writing the file
5857         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5858         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5859         # loop until dd process exits
5860         while ps ax -opid | grep -wq $dd_pid; do
5861                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5862                 sleep $((RANDOM % 5 + 1))
5863         done
5864         # restore original max_pages_per_rpc
5865         $LCTL set_param $osc1_mppc=$orig_mppc
5866         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5867 }
5868 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5869
5870 test_50() {
5871         # bug 1485
5872         test_mkdir $DIR/$tdir
5873         cd $DIR/$tdir
5874         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5875 }
5876 run_test 50 "special situations: /proc symlinks  ==============="
5877
5878 test_51a() {    # was test_51
5879         # bug 1516 - create an empty entry right after ".." then split dir
5880         test_mkdir -c1 $DIR/$tdir
5881         touch $DIR/$tdir/foo
5882         $MCREATE $DIR/$tdir/bar
5883         rm $DIR/$tdir/foo
5884         createmany -m $DIR/$tdir/longfile 201
5885         FNUM=202
5886         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5887                 $MCREATE $DIR/$tdir/longfile$FNUM
5888                 FNUM=$(($FNUM + 1))
5889                 echo -n "+"
5890         done
5891         echo
5892         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5893 }
5894 run_test 51a "special situations: split htree with empty entry =="
5895
5896 cleanup_print_lfs_df () {
5897         trap 0
5898         $LFS df
5899         $LFS df -i
5900 }
5901
5902 test_51b() {
5903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5904
5905         local dir=$DIR/$tdir
5906         local nrdirs=$((65536 + 100))
5907
5908         # cleanup the directory
5909         rm -fr $dir
5910
5911         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5912
5913         $LFS df
5914         $LFS df -i
5915         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5916         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5917         [[ $numfree -lt $nrdirs ]] &&
5918                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5919
5920         # need to check free space for the directories as well
5921         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5922         numfree=$(( blkfree / $(fs_inode_ksize) ))
5923         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5924
5925         trap cleanup_print_lfs_df EXIT
5926
5927         # create files
5928         createmany -d $dir/d $nrdirs || {
5929                 unlinkmany $dir/d $nrdirs
5930                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5931         }
5932
5933         # really created :
5934         nrdirs=$(ls -U $dir | wc -l)
5935
5936         # unlink all but 100 subdirectories, then check it still works
5937         local left=100
5938         local delete=$((nrdirs - left))
5939
5940         $LFS df
5941         $LFS df -i
5942
5943         # for ldiskfs the nlink count should be 1, but this is OSD specific
5944         # and so this is listed for informational purposes only
5945         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5946         unlinkmany -d $dir/d $delete ||
5947                 error "unlink of first $delete subdirs failed"
5948
5949         echo "nlink between: $(stat -c %h $dir)"
5950         local found=$(ls -U $dir | wc -l)
5951         [ $found -ne $left ] &&
5952                 error "can't find subdirs: found only $found, expected $left"
5953
5954         unlinkmany -d $dir/d $delete $left ||
5955                 error "unlink of second $left subdirs failed"
5956         # regardless of whether the backing filesystem tracks nlink accurately
5957         # or not, the nlink count shouldn't be more than "." and ".." here
5958         local after=$(stat -c %h $dir)
5959         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5960                 echo "nlink after: $after"
5961
5962         cleanup_print_lfs_df
5963 }
5964 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5965
5966 test_51d_sub() {
5967         local stripecount=$1
5968         local nfiles=$2
5969
5970         log "create files with stripecount=$stripecount"
5971         $LFS setstripe -C $stripecount $DIR/$tdir
5972         createmany -o $DIR/$tdir/t- $nfiles
5973         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5974         for ((n = 0; n < $OSTCOUNT; n++)); do
5975                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5976                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5977                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5978                             '($1 == '$n') { objs += 1 } \
5979                             END { printf("%0.0f", objs) }')
5980                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5981         done
5982         unlinkmany $DIR/$tdir/t- $nfiles
5983         rm  -f $TMP/$tfile
5984
5985         local nlast
5986         local min=4
5987         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5988
5989         # For some combinations of stripecount and OSTCOUNT current code
5990         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5991         # than others. Rather than skipping this test entirely, check that
5992         # and keep testing to ensure imbalance does not get worse. LU-15282
5993         (( (OSTCOUNT == 6 && stripecount == 4) ||
5994            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5995            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5996         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5997                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5998                         { $LFS df && $LFS df -i &&
5999                         error "stripecount=$stripecount: " \
6000                               "OST $n has fewer objects vs. OST $nlast " \
6001                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6002                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6003                         { $LFS df && $LFS df -i &&
6004                         error "stripecount=$stripecount: " \
6005                               "OST $n has more objects vs. OST $nlast " \
6006                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6007
6008                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6009                         { $LFS df && $LFS df -i &&
6010                         error "stripecount=$stripecount: " \
6011                               "OST $n has fewer #0 objects vs. OST $nlast " \
6012                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6013                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6014                         { $LFS df && $LFS df -i &&
6015                         error "stripecount=$stripecount: " \
6016                               "OST $n has more #0 objects vs. OST $nlast " \
6017                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6018         done
6019 }
6020
6021 test_51d() {
6022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6023         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6024
6025         local stripecount
6026         local per_ost=100
6027         local nfiles=$((per_ost * OSTCOUNT))
6028         local mdts=$(comma_list $(mdts_nodes))
6029         local param="osp.*.create_count"
6030         local qos_old=$(do_facet mds1 \
6031                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6032
6033         do_nodes $mdts \
6034                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6035         stack_trap "do_nodes $mdts \
6036                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6037
6038         test_mkdir $DIR/$tdir
6039         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6040         (( dirstripes > 0 )) || dirstripes=1
6041
6042         # Ensure enough OST objects precreated for tests to pass without
6043         # running out of objects.  This is an LOV r-r OST algorithm test,
6044         # not an OST object precreation test.
6045         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6046         (( old >= nfiles )) ||
6047         {
6048                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6049
6050                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6051                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6052
6053                 # trigger precreation from all MDTs for all OSTs
6054                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6055                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6056                 done
6057         }
6058
6059         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6060                 sleep 8  # allow object precreation to catch up
6061                 test_51d_sub $stripecount $nfiles
6062         done
6063 }
6064 run_test 51d "check LOV round-robin OST object distribution"
6065
6066 test_51e() {
6067         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6068                 skip_env "ldiskfs only test"
6069         fi
6070
6071         test_mkdir -c1 $DIR/$tdir
6072         test_mkdir -c1 $DIR/$tdir/d0
6073
6074         touch $DIR/$tdir/d0/foo
6075         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6076                 error "file exceed 65000 nlink limit!"
6077         unlinkmany $DIR/$tdir/d0/f- 65001
6078         return 0
6079 }
6080 run_test 51e "check file nlink limit"
6081
6082 test_51f() {
6083         test_mkdir $DIR/$tdir
6084
6085         local max=100000
6086         local ulimit_old=$(ulimit -n)
6087         local spare=20 # number of spare fd's for scripts/libraries, etc.
6088         local mdt=$($LFS getstripe -m $DIR/$tdir)
6089         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6090
6091         echo "MDT$mdt numfree=$numfree, max=$max"
6092         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6093         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6094                 while ! ulimit -n $((numfree + spare)); do
6095                         numfree=$((numfree * 3 / 4))
6096                 done
6097                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6098         else
6099                 echo "left ulimit at $ulimit_old"
6100         fi
6101
6102         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6103                 unlinkmany $DIR/$tdir/f $numfree
6104                 error "create+open $numfree files in $DIR/$tdir failed"
6105         }
6106         ulimit -n $ulimit_old
6107
6108         # if createmany exits at 120s there will be fewer than $numfree files
6109         unlinkmany $DIR/$tdir/f $numfree || true
6110 }
6111 run_test 51f "check many open files limit"
6112
6113 test_52a() {
6114         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6115         test_mkdir $DIR/$tdir
6116         touch $DIR/$tdir/foo
6117         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6118         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6119         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6120         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6121         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6122                                         error "link worked"
6123         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6124         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6125         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6126                                                      error "lsattr"
6127         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6128         cp -r $DIR/$tdir $TMP/
6129         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6130 }
6131 run_test 52a "append-only flag test (should return errors)"
6132
6133 test_52b() {
6134         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6135         test_mkdir $DIR/$tdir
6136         touch $DIR/$tdir/foo
6137         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6138         cat test > $DIR/$tdir/foo && error "cat test worked"
6139         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6140         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6141         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6142                                         error "link worked"
6143         echo foo >> $DIR/$tdir/foo && error "echo worked"
6144         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6145         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6146         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6147         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6148                                                         error "lsattr"
6149         chattr -i $DIR/$tdir/foo || error "chattr failed"
6150
6151         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6152 }
6153 run_test 52b "immutable flag test (should return errors) ======="
6154
6155 test_53() {
6156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6157         remote_mds_nodsh && skip "remote MDS with nodsh"
6158         remote_ost_nodsh && skip "remote OST with nodsh"
6159
6160         local param
6161         local param_seq
6162         local ostname
6163         local mds_last
6164         local mds_last_seq
6165         local ost_last
6166         local ost_last_seq
6167         local ost_last_id
6168         local ostnum
6169         local node
6170         local found=false
6171         local support_last_seq=true
6172
6173         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6174                 support_last_seq=false
6175
6176         # only test MDT0000
6177         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6178         local value
6179         for value in $(do_facet $SINGLEMDS \
6180                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6181                 param=$(echo ${value[0]} | cut -d "=" -f1)
6182                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6183
6184                 if $support_last_seq; then
6185                         param_seq=$(echo $param |
6186                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6187                         mds_last_seq=$(do_facet $SINGLEMDS \
6188                                        $LCTL get_param -n $param_seq)
6189                 fi
6190                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6191
6192                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6193                 node=$(facet_active_host ost$((ostnum+1)))
6194                 param="obdfilter.$ostname.last_id"
6195                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6196                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6197                         ost_last_id=$ost_last
6198
6199                         if $support_last_seq; then
6200                                 ost_last_id=$(echo $ost_last |
6201                                               awk -F':' '{print $2}' |
6202                                               sed -e "s/^0x//g")
6203                                 ost_last_seq=$(echo $ost_last |
6204                                                awk -F':' '{print $1}')
6205                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6206                         fi
6207
6208                         if [[ $ost_last_id != $mds_last ]]; then
6209                                 error "$ost_last_id != $mds_last"
6210                         else
6211                                 found=true
6212                                 break
6213                         fi
6214                 done
6215         done
6216         $found || error "can not match last_seq/last_id for $mdtosc"
6217         return 0
6218 }
6219 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6220
6221 test_54a() {
6222         perl -MSocket -e ';' || skip "no Socket perl module installed"
6223
6224         $SOCKETSERVER $DIR/socket ||
6225                 error "$SOCKETSERVER $DIR/socket failed: $?"
6226         $SOCKETCLIENT $DIR/socket ||
6227                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6228         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6229 }
6230 run_test 54a "unix domain socket test =========================="
6231
6232 test_54b() {
6233         f="$DIR/f54b"
6234         mknod $f c 1 3
6235         chmod 0666 $f
6236         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6237 }
6238 run_test 54b "char device works in lustre ======================"
6239
6240 find_loop_dev() {
6241         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6242         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6243         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6244
6245         for i in $(seq 3 7); do
6246                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6247                 LOOPDEV=$LOOPBASE$i
6248                 LOOPNUM=$i
6249                 break
6250         done
6251 }
6252
6253 cleanup_54c() {
6254         local rc=0
6255         loopdev="$DIR/loop54c"
6256
6257         trap 0
6258         $UMOUNT $DIR/$tdir || rc=$?
6259         losetup -d $loopdev || true
6260         losetup -d $LOOPDEV || true
6261         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6262         return $rc
6263 }
6264
6265 test_54c() {
6266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6267
6268         loopdev="$DIR/loop54c"
6269
6270         find_loop_dev
6271         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6272         trap cleanup_54c EXIT
6273         mknod $loopdev b 7 $LOOPNUM
6274         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6275         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6276         losetup $loopdev $DIR/$tfile ||
6277                 error "can't set up $loopdev for $DIR/$tfile"
6278         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6279         test_mkdir $DIR/$tdir
6280         mount -t ext2 $loopdev $DIR/$tdir ||
6281                 error "error mounting $loopdev on $DIR/$tdir"
6282         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6283                 error "dd write"
6284         df $DIR/$tdir
6285         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6286                 error "dd read"
6287         cleanup_54c
6288 }
6289 run_test 54c "block device works in lustre ====================="
6290
6291 test_54d() {
6292         local pipe="$DIR/$tfile.pipe"
6293         local string="aaaaaa"
6294
6295         mknod $pipe p
6296         echo -n "$string" > $pipe &
6297         local result=$(cat $pipe)
6298         [[ "$result" == "$string" ]] || error "$result != $string"
6299 }
6300 run_test 54d "fifo device works in lustre ======================"
6301
6302 test_54e() {
6303         f="$DIR/f54e"
6304         string="aaaaaa"
6305         cp -aL /dev/console $f
6306         echo $string > $f || error "echo $string to $f failed"
6307 }
6308 run_test 54e "console/tty device works in lustre ======================"
6309
6310 test_56a() {
6311         local numfiles=3
6312         local numdirs=2
6313         local dir=$DIR/$tdir
6314
6315         rm -rf $dir
6316         test_mkdir -p $dir/dir
6317         for i in $(seq $numfiles); do
6318                 touch $dir/file$i
6319                 touch $dir/dir/file$i
6320         done
6321
6322         local numcomp=$($LFS getstripe --component-count $dir)
6323
6324         [[ $numcomp == 0 ]] && numcomp=1
6325
6326         # test lfs getstripe with --recursive
6327         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6328
6329         [[ $filenum -eq $((numfiles * 2)) ]] ||
6330                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6331         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6332         [[ $filenum -eq $numfiles ]] ||
6333                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6334         echo "$LFS getstripe showed obdidx or l_ost_idx"
6335
6336         # test lfs getstripe with file instead of dir
6337         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6338         [[ $filenum -eq 1 ]] ||
6339                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6340         echo "$LFS getstripe file1 passed"
6341
6342         #test lfs getstripe with --verbose
6343         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6344         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6345                 error "$LFS getstripe --verbose $dir: "\
6346                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6347         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6348                 error "$LFS getstripe $dir: showed lmm_magic"
6349
6350         #test lfs getstripe with -v prints lmm_fid
6351         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6352         local countfids=$((numdirs + numfiles * numcomp))
6353         [[ $filenum -eq $countfids ]] ||
6354                 error "$LFS getstripe -v $dir: "\
6355                       "got $filenum want $countfids lmm_fid"
6356         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6357                 error "$LFS getstripe $dir: showed lmm_fid by default"
6358         echo "$LFS getstripe --verbose passed"
6359
6360         #check for FID information
6361         local fid1=$($LFS getstripe --fid $dir/file1)
6362         local fid2=$($LFS getstripe --verbose $dir/file1 |
6363                      awk '/lmm_fid: / { print $2; exit; }')
6364         local fid3=$($LFS path2fid $dir/file1)
6365
6366         [ "$fid1" != "$fid2" ] &&
6367                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6368         [ "$fid1" != "$fid3" ] &&
6369                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6370         echo "$LFS getstripe --fid passed"
6371
6372         #test lfs getstripe with --obd
6373         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6374                 error "$LFS getstripe --obd wrong_uuid: should return error"
6375
6376         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6377
6378         local ostidx=1
6379         local obduuid=$(ostuuid_from_index $ostidx)
6380         local found=$($LFS getstripe -r --obd $obduuid $dir |
6381                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6382
6383         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6384         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6385                 ((filenum--))
6386         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6387                 ((filenum--))
6388
6389         [[ $found -eq $filenum ]] ||
6390                 error "$LFS getstripe --obd: found $found expect $filenum"
6391         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6392                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6393                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6394                 error "$LFS getstripe --obd: should not show file on other obd"
6395         echo "$LFS getstripe --obd passed"
6396 }
6397 run_test 56a "check $LFS getstripe"
6398
6399 test_56b() {
6400         local dir=$DIR/$tdir
6401         local numdirs=3
6402
6403         test_mkdir $dir
6404         for i in $(seq $numdirs); do
6405                 test_mkdir $dir/dir$i
6406         done
6407
6408         # test lfs getdirstripe default mode is non-recursion, which is
6409         # different from lfs getstripe
6410         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6411
6412         [[ $dircnt -eq 1 ]] ||
6413                 error "$LFS getdirstripe: found $dircnt, not 1"
6414         dircnt=$($LFS getdirstripe --recursive $dir |
6415                 grep -c lmv_stripe_count)
6416         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6417                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6418 }
6419 run_test 56b "check $LFS getdirstripe"
6420
6421 test_56c() {
6422         remote_ost_nodsh && skip "remote OST with nodsh"
6423
6424         local ost_idx=0
6425         local ost_name=$(ostname_from_index $ost_idx)
6426         local old_status=$(ost_dev_status $ost_idx)
6427         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6428
6429         [[ -z "$old_status" ]] ||
6430                 skip_env "OST $ost_name is in $old_status status"
6431
6432         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6433         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6434                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6435         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6436                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6437                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6438         fi
6439
6440         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6441                 error "$LFS df -v showing inactive devices"
6442         sleep_maxage
6443
6444         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6445
6446         [[ "$new_status" =~ "D" ]] ||
6447                 error "$ost_name status is '$new_status', missing 'D'"
6448         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6449                 [[ "$new_status" =~ "N" ]] ||
6450                         error "$ost_name status is '$new_status', missing 'N'"
6451         fi
6452         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6453                 [[ "$new_status" =~ "f" ]] ||
6454                         error "$ost_name status is '$new_status', missing 'f'"
6455         fi
6456
6457         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6458         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6459                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6460         [[ -z "$p" ]] && restore_lustre_params < $p || true
6461         sleep_maxage
6462
6463         new_status=$(ost_dev_status $ost_idx)
6464         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6465                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6466         # can't check 'f' as devices may actually be on flash
6467 }
6468 run_test 56c "check 'lfs df' showing device status"
6469
6470 test_56d() {
6471         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6472         local osts=$($LFS df -v $MOUNT | grep -c OST)
6473
6474         $LFS df $MOUNT
6475
6476         (( mdts == MDSCOUNT )) ||
6477                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6478         (( osts == OSTCOUNT )) ||
6479                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6480 }
6481 run_test 56d "'lfs df -v' prints only configured devices"
6482
6483 test_56e() {
6484         err_enoent=2 # No such file or directory
6485         err_eopnotsupp=95 # Operation not supported
6486
6487         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6488         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6489
6490         # Check for handling of path not exists
6491         output=$($LFS df $enoent_mnt 2>&1)
6492         ret=$?
6493
6494         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6495         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6496                 error "expect failure $err_enoent, not $ret"
6497
6498         # Check for handling of non-Lustre FS
6499         output=$($LFS df $notsup_mnt)
6500         ret=$?
6501
6502         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6503         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6504                 error "expect success $err_eopnotsupp, not $ret"
6505
6506         # Check for multiple LustreFS argument
6507         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6508         ret=$?
6509
6510         [[ $output -eq 3 && $ret -eq 0 ]] ||
6511                 error "expect success 3, not $output, rc = $ret"
6512
6513         # Check for correct non-Lustre FS handling among multiple
6514         # LustreFS argument
6515         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6516                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6517         ret=$?
6518
6519         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6520                 error "expect success 2, not $output, rc = $ret"
6521 }
6522 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6523
6524 NUMFILES=3
6525 NUMDIRS=3
6526 setup_56() {
6527         local local_tdir="$1"
6528         local local_numfiles="$2"
6529         local local_numdirs="$3"
6530         local dir_params="$4"
6531         local dir_stripe_params="$5"
6532
6533         if [ ! -d "$local_tdir" ] ; then
6534                 test_mkdir -p $dir_stripe_params $local_tdir
6535                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6536                 for i in $(seq $local_numfiles) ; do
6537                         touch $local_tdir/file$i
6538                 done
6539                 for i in $(seq $local_numdirs) ; do
6540                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6541                         for j in $(seq $local_numfiles) ; do
6542                                 touch $local_tdir/dir$i/file$j
6543                         done
6544                 done
6545         fi
6546 }
6547
6548 setup_56_special() {
6549         local local_tdir=$1
6550         local local_numfiles=$2
6551         local local_numdirs=$3
6552
6553         setup_56 $local_tdir $local_numfiles $local_numdirs
6554
6555         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6556                 for i in $(seq $local_numfiles) ; do
6557                         mknod $local_tdir/loop${i}b b 7 $i
6558                         mknod $local_tdir/null${i}c c 1 3
6559                         ln -s $local_tdir/file1 $local_tdir/link${i}
6560                 done
6561                 for i in $(seq $local_numdirs) ; do
6562                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6563                         mknod $local_tdir/dir$i/null${i}c c 1 3
6564                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6565                 done
6566         fi
6567 }
6568
6569 test_56g() {
6570         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6571         local expected=$(($NUMDIRS + 2))
6572
6573         setup_56 $dir $NUMFILES $NUMDIRS
6574
6575         # test lfs find with -name
6576         for i in $(seq $NUMFILES) ; do
6577                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6578
6579                 [ $nums -eq $expected ] ||
6580                         error "lfs find -name '*$i' $dir wrong: "\
6581                               "found $nums, expected $expected"
6582         done
6583 }
6584 run_test 56g "check lfs find -name"
6585
6586 test_56h() {
6587         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6588         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6589
6590         setup_56 $dir $NUMFILES $NUMDIRS
6591
6592         # test lfs find with ! -name
6593         for i in $(seq $NUMFILES) ; do
6594                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6595
6596                 [ $nums -eq $expected ] ||
6597                         error "lfs find ! -name '*$i' $dir wrong: "\
6598                               "found $nums, expected $expected"
6599         done
6600 }
6601 run_test 56h "check lfs find ! -name"
6602
6603 test_56i() {
6604         local dir=$DIR/$tdir
6605
6606         test_mkdir $dir
6607
6608         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6609         local out=$($cmd)
6610
6611         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6612 }
6613 run_test 56i "check 'lfs find -ost UUID' skips directories"
6614
6615 test_56j() {
6616         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6617
6618         setup_56_special $dir $NUMFILES $NUMDIRS
6619
6620         local expected=$((NUMDIRS + 1))
6621         local cmd="$LFS find -type d $dir"
6622         local nums=$($cmd | wc -l)
6623
6624         [ $nums -eq $expected ] ||
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626 }
6627 run_test 56j "check lfs find -type d"
6628
6629 test_56k() {
6630         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6631
6632         setup_56_special $dir $NUMFILES $NUMDIRS
6633
6634         local expected=$(((NUMDIRS + 1) * NUMFILES))
6635         local cmd="$LFS find -type f $dir"
6636         local nums=$($cmd | wc -l)
6637
6638         [ $nums -eq $expected ] ||
6639                 error "'$cmd' wrong: found $nums, expected $expected"
6640 }
6641 run_test 56k "check lfs find -type f"
6642
6643 test_56l() {
6644         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6645
6646         setup_56_special $dir $NUMFILES $NUMDIRS
6647
6648         local expected=$((NUMDIRS + NUMFILES))
6649         local cmd="$LFS find -type b $dir"
6650         local nums=$($cmd | wc -l)
6651
6652         [ $nums -eq $expected ] ||
6653                 error "'$cmd' wrong: found $nums, expected $expected"
6654 }
6655 run_test 56l "check lfs find -type b"
6656
6657 test_56m() {
6658         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6659
6660         setup_56_special $dir $NUMFILES $NUMDIRS
6661
6662         local expected=$((NUMDIRS + NUMFILES))
6663         local cmd="$LFS find -type c $dir"
6664         local nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] ||
6666                 error "'$cmd' wrong: found $nums, expected $expected"
6667 }
6668 run_test 56m "check lfs find -type c"
6669
6670 test_56n() {
6671         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6672         setup_56_special $dir $NUMFILES $NUMDIRS
6673
6674         local expected=$((NUMDIRS + NUMFILES))
6675         local cmd="$LFS find -type l $dir"
6676         local nums=$($cmd | wc -l)
6677
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680 }
6681 run_test 56n "check lfs find -type l"
6682
6683 test_56o() {
6684         local dir=$DIR/$tdir
6685
6686         setup_56 $dir $NUMFILES $NUMDIRS
6687         utime $dir/file1 > /dev/null || error "utime (1)"
6688         utime $dir/file2 > /dev/null || error "utime (2)"
6689         utime $dir/dir1 > /dev/null || error "utime (3)"
6690         utime $dir/dir2 > /dev/null || error "utime (4)"
6691         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6692         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6693
6694         local expected=4
6695         local nums=$($LFS find -mtime +0 $dir | wc -l)
6696
6697         [ $nums -eq $expected ] ||
6698                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6699
6700         expected=12
6701         cmd="$LFS find -mtime 0 $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] ||
6704                 error "'$cmd' wrong: found $nums, expected $expected"
6705 }
6706 run_test 56o "check lfs find -mtime for old files"
6707
6708 test_56ob() {
6709         local dir=$DIR/$tdir
6710         local expected=1
6711         local count=0
6712
6713         # just to make sure there is something that won't be found
6714         test_mkdir $dir
6715         touch $dir/$tfile.now
6716
6717         for age in year week day hour min; do
6718                 count=$((count + 1))
6719
6720                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6721                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6722                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6723
6724                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6725                 local nums=$($cmd | wc -l)
6726                 [ $nums -eq $expected ] ||
6727                         error "'$cmd' wrong: found $nums, expected $expected"
6728
6729                 cmd="$LFS find $dir -atime $count${age:0:1}"
6730                 nums=$($cmd | wc -l)
6731                 [ $nums -eq $expected ] ||
6732                         error "'$cmd' wrong: found $nums, expected $expected"
6733         done
6734
6735         sleep 2
6736         cmd="$LFS find $dir -ctime +1s -type f"
6737         nums=$($cmd | wc -l)
6738         (( $nums == $count * 2 + 1)) ||
6739                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6740 }
6741 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6742
6743 test_newerXY_base() {
6744         local x=$1
6745         local y=$2
6746         local dir=$DIR/$tdir
6747         local ref
6748         local negref
6749
6750         if [ $y == "t" ]; then
6751                 if [ $x == "b" ]; then
6752                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6753                 else
6754                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6755                 fi
6756         else
6757                 ref=$DIR/$tfile.newer.$x$y
6758                 touch $ref || error "touch $ref failed"
6759         fi
6760
6761         echo "before = $ref"
6762         sleep 2
6763         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6764         sleep 2
6765         if [ $y == "t" ]; then
6766                 if [ $x == "b" ]; then
6767                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6768                 else
6769                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6770                 fi
6771         else
6772                 negref=$DIR/$tfile.negnewer.$x$y
6773                 touch $negref || error "touch $negref failed"
6774         fi
6775
6776         echo "after = $negref"
6777         local cmd="$LFS find $dir -newer$x$y $ref"
6778         local nums=$(eval $cmd | wc -l)
6779         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6780
6781         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6782                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6783
6784         cmd="$LFS find $dir ! -newer$x$y $negref"
6785         nums=$(eval $cmd | wc -l)
6786         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6787                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6788
6789         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6790         nums=$(eval $cmd | wc -l)
6791         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6792                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6793
6794         rm -rf $DIR/*
6795 }
6796
6797 test_56oc() {
6798         test_newerXY_base "a" "a"
6799         test_newerXY_base "a" "m"
6800         test_newerXY_base "a" "c"
6801         test_newerXY_base "m" "a"
6802         test_newerXY_base "m" "m"
6803         test_newerXY_base "m" "c"
6804         test_newerXY_base "c" "a"
6805         test_newerXY_base "c" "m"
6806         test_newerXY_base "c" "c"
6807
6808         test_newerXY_base "a" "t"
6809         test_newerXY_base "m" "t"
6810         test_newerXY_base "c" "t"
6811
6812         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6813            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6814                 ! btime_supported && echo "btime unsupported" && return 0
6815
6816         test_newerXY_base "b" "b"
6817         test_newerXY_base "b" "t"
6818 }
6819 run_test 56oc "check lfs find -newerXY work"
6820
6821 btime_supported() {
6822         local dir=$DIR/$tdir
6823         local rc
6824
6825         mkdir -p $dir
6826         touch $dir/$tfile
6827         $LFS find $dir -btime -1d -type f
6828         rc=$?
6829         rm -rf $dir
6830         return $rc
6831 }
6832
6833 test_56od() {
6834         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6835                 ! btime_supported && skip "btime unsupported on MDS"
6836
6837         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6838                 ! btime_supported && skip "btime unsupported on clients"
6839
6840         local dir=$DIR/$tdir
6841         local ref=$DIR/$tfile.ref
6842         local negref=$DIR/$tfile.negref
6843
6844         mkdir $dir || error "mkdir $dir failed"
6845         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6846         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6847         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6848         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6849         touch $ref || error "touch $ref failed"
6850         # sleep 3 seconds at least
6851         sleep 3
6852
6853         local before=$(do_facet mds1 date +%s)
6854         local skew=$(($(date +%s) - before + 1))
6855
6856         if (( skew < 0 && skew > -5 )); then
6857                 sleep $((0 - skew + 1))
6858                 skew=0
6859         fi
6860
6861         # Set the dir stripe params to limit files all on MDT0,
6862         # otherwise we need to calc the max clock skew between
6863         # the client and MDTs.
6864         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6865         sleep 2
6866         touch $negref || error "touch $negref failed"
6867
6868         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6869         local nums=$($cmd | wc -l)
6870         local expected=$(((NUMFILES + 1) * NUMDIRS))
6871
6872         [ $nums -eq $expected ] ||
6873                 error "'$cmd' wrong: found $nums, expected $expected"
6874
6875         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6876         nums=$($cmd | wc -l)
6877         expected=$((NUMFILES + 1))
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880
6881         [ $skew -lt 0 ] && return
6882
6883         local after=$(do_facet mds1 date +%s)
6884         local age=$((after - before + 1 + skew))
6885
6886         cmd="$LFS find $dir -btime -${age}s -type f"
6887         nums=$($cmd | wc -l)
6888         expected=$(((NUMFILES + 1) * NUMDIRS))
6889
6890         echo "Clock skew between client and server: $skew, age:$age"
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         expected=$(($NUMDIRS + 1))
6895         cmd="$LFS find $dir -btime -${age}s -type d"
6896         nums=$($cmd | wc -l)
6897         [ $nums -eq $expected ] ||
6898                 error "'$cmd' wrong: found $nums, expected $expected"
6899         rm -f $ref $negref || error "Failed to remove $ref $negref"
6900 }
6901 run_test 56od "check lfs find -btime with units"
6902
6903 test_56p() {
6904         [ $RUNAS_ID -eq $UID ] &&
6905                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6906
6907         local dir=$DIR/$tdir
6908
6909         setup_56 $dir $NUMFILES $NUMDIRS
6910         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6911
6912         local expected=$NUMFILES
6913         local cmd="$LFS find -uid $RUNAS_ID $dir"
6914         local nums=$($cmd | wc -l)
6915
6916         [ $nums -eq $expected ] ||
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918
6919         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6920         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6921         nums=$($cmd | wc -l)
6922         [ $nums -eq $expected ] ||
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924 }
6925 run_test 56p "check lfs find -uid and ! -uid"
6926
6927 test_56q() {
6928         [ $RUNAS_ID -eq $UID ] &&
6929                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6930
6931         local dir=$DIR/$tdir
6932
6933         setup_56 $dir $NUMFILES $NUMDIRS
6934         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6935
6936         local expected=$NUMFILES
6937         local cmd="$LFS find -gid $RUNAS_GID $dir"
6938         local nums=$($cmd | wc -l)
6939
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6944         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6945         nums=$($cmd | wc -l)
6946         [ $nums -eq $expected ] ||
6947                 error "'$cmd' wrong: found $nums, expected $expected"
6948 }
6949 run_test 56q "check lfs find -gid and ! -gid"
6950
6951 test_56r() {
6952         local dir=$DIR/$tdir
6953
6954         setup_56 $dir $NUMFILES $NUMDIRS
6955
6956         local expected=12
6957         local cmd="$LFS find -size 0 -type f -lazy $dir"
6958         local nums=$($cmd | wc -l)
6959
6960         [ $nums -eq $expected ] ||
6961                 error "'$cmd' wrong: found $nums, expected $expected"
6962         cmd="$LFS find -size 0 -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966
6967         expected=0
6968         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6969         nums=$($cmd | wc -l)
6970         [ $nums -eq $expected ] ||
6971                 error "'$cmd' wrong: found $nums, expected $expected"
6972         cmd="$LFS find ! -size 0 -type f $dir"
6973         nums=$($cmd | wc -l)
6974         [ $nums -eq $expected ] ||
6975                 error "'$cmd' wrong: found $nums, expected $expected"
6976
6977         echo "test" > $dir/$tfile
6978         echo "test2" > $dir/$tfile.2 && sync
6979         expected=1
6980         cmd="$LFS find -size 5 -type f -lazy $dir"
6981         nums=$($cmd | wc -l)
6982         [ $nums -eq $expected ] ||
6983                 error "'$cmd' wrong: found $nums, expected $expected"
6984         cmd="$LFS find -size 5 -type f $dir"
6985         nums=$($cmd | wc -l)
6986         [ $nums -eq $expected ] ||
6987                 error "'$cmd' wrong: found $nums, expected $expected"
6988
6989         expected=1
6990         cmd="$LFS find -size +5 -type f -lazy $dir"
6991         nums=$($cmd | wc -l)
6992         [ $nums -eq $expected ] ||
6993                 error "'$cmd' wrong: found $nums, expected $expected"
6994         cmd="$LFS find -size +5 -type f $dir"
6995         nums=$($cmd | wc -l)
6996         [ $nums -eq $expected ] ||
6997                 error "'$cmd' wrong: found $nums, expected $expected"
6998
6999         expected=2
7000         cmd="$LFS find -size +0 -type f -lazy $dir"
7001         nums=$($cmd | wc -l)
7002         [ $nums -eq $expected ] ||
7003                 error "'$cmd' wrong: found $nums, expected $expected"
7004         cmd="$LFS find -size +0 -type f $dir"
7005         nums=$($cmd | wc -l)
7006         [ $nums -eq $expected ] ||
7007                 error "'$cmd' wrong: found $nums, expected $expected"
7008
7009         expected=2
7010         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7011         nums=$($cmd | wc -l)
7012         [ $nums -eq $expected ] ||
7013                 error "'$cmd' wrong: found $nums, expected $expected"
7014         cmd="$LFS find ! -size -5 -type f $dir"
7015         nums=$($cmd | wc -l)
7016         [ $nums -eq $expected ] ||
7017                 error "'$cmd' wrong: found $nums, expected $expected"
7018
7019         expected=12
7020         cmd="$LFS find -size -5 -type f -lazy $dir"
7021         nums=$($cmd | wc -l)
7022         [ $nums -eq $expected ] ||
7023                 error "'$cmd' wrong: found $nums, expected $expected"
7024         cmd="$LFS find -size -5 -type f $dir"
7025         nums=$($cmd | wc -l)
7026         [ $nums -eq $expected ] ||
7027                 error "'$cmd' wrong: found $nums, expected $expected"
7028 }
7029 run_test 56r "check lfs find -size works"
7030
7031 test_56ra_sub() {
7032         local expected=$1
7033         local glimpses=$2
7034         local cmd="$3"
7035
7036         cancel_lru_locks $OSC
7037
7038         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7039         local nums=$($cmd | wc -l)
7040
7041         [ $nums -eq $expected ] ||
7042                 error "'$cmd' wrong: found $nums, expected $expected"
7043
7044         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7045
7046         if (( rpcs_before + glimpses != rpcs_after )); then
7047                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7048                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7049
7050                 if [[ $glimpses == 0 ]]; then
7051                         error "'$cmd' should not send glimpse RPCs to OST"
7052                 else
7053                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7054                 fi
7055         fi
7056 }
7057
7058 test_56ra() {
7059         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7060                 skip "MDS < 2.12.58 doesn't return LSOM data"
7061         local dir=$DIR/$tdir
7062         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7063
7064         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7065
7066         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7067         $LCTL set_param -n llite.*.statahead_agl=0
7068         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7069
7070         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7071         # open and close all files to ensure LSOM is updated
7072         cancel_lru_locks $OSC
7073         find $dir -type f | xargs cat > /dev/null
7074
7075         #   expect_found  glimpse_rpcs  command_to_run
7076         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7077         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7078         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7079         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7080
7081         echo "test" > $dir/$tfile
7082         echo "test2" > $dir/$tfile.2 && sync
7083         cancel_lru_locks $OSC
7084         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7085
7086         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7087         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7088         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7089         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7090
7091         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7092         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7093         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7094         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7095         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7096         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7097 }
7098 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7099
7100 test_56rb() {
7101         local dir=$DIR/$tdir
7102         local tmp=$TMP/$tfile.log
7103         local mdt_idx;
7104
7105         test_mkdir -p $dir || error "failed to mkdir $dir"
7106         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7107                 error "failed to setstripe $dir/$tfile"
7108         mdt_idx=$($LFS getdirstripe -i $dir)
7109         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7110
7111         stack_trap "rm -f $tmp" EXIT
7112         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7113         ! grep -q obd_uuid $tmp ||
7114                 error "failed to find --size +100K --ost 0 $dir"
7115         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7116         ! grep -q obd_uuid $tmp ||
7117                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7118 }
7119 run_test 56rb "check lfs find --size --ost/--mdt works"
7120
7121 test_56rc() {
7122         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7123         local dir=$DIR/$tdir
7124         local found
7125
7126         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7127         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7128         (( $MDSCOUNT > 2 )) &&
7129                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7130         mkdir $dir/$tdir-{1..10}
7131         touch $dir/$tfile-{1..10}
7132
7133         found=$($LFS find $dir --mdt-count 2 | wc -l)
7134         expect=11
7135         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7136
7137         found=$($LFS find $dir -T +1 | wc -l)
7138         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7139         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7140
7141         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7142         expect=11
7143         (( $found == $expect )) || error "found $found all_char, expect $expect"
7144
7145         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7146         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7147         (( $found == $expect )) || error "found $found all_char, expect $expect"
7148 }
7149 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7150
7151 test_56s() { # LU-611 #LU-9369
7152         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7153
7154         local dir=$DIR/$tdir
7155         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7156
7157         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7158         for i in $(seq $NUMDIRS); do
7159                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7160         done
7161
7162         local expected=$NUMDIRS
7163         local cmd="$LFS find -c $OSTCOUNT $dir"
7164         local nums=$($cmd | wc -l)
7165
7166         [ $nums -eq $expected ] || {
7167                 $LFS getstripe -R $dir
7168                 error "'$cmd' wrong: found $nums, expected $expected"
7169         }
7170
7171         expected=$((NUMDIRS + onestripe))
7172         cmd="$LFS find -stripe-count +0 -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] || {
7175                 $LFS getstripe -R $dir
7176                 error "'$cmd' wrong: found $nums, expected $expected"
7177         }
7178
7179         expected=$onestripe
7180         cmd="$LFS find -stripe-count 1 -type f $dir"
7181         nums=$($cmd | wc -l)
7182         [ $nums -eq $expected ] || {
7183                 $LFS getstripe -R $dir
7184                 error "'$cmd' wrong: found $nums, expected $expected"
7185         }
7186
7187         cmd="$LFS find -stripe-count -2 -type f $dir"
7188         nums=$($cmd | wc -l)
7189         [ $nums -eq $expected ] || {
7190                 $LFS getstripe -R $dir
7191                 error "'$cmd' wrong: found $nums, expected $expected"
7192         }
7193
7194         expected=0
7195         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7196         nums=$($cmd | wc -l)
7197         [ $nums -eq $expected ] || {
7198                 $LFS getstripe -R $dir
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200         }
7201 }
7202 run_test 56s "check lfs find -stripe-count works"
7203
7204 test_56t() { # LU-611 #LU-9369
7205         local dir=$DIR/$tdir
7206
7207         setup_56 $dir 0 $NUMDIRS
7208         for i in $(seq $NUMDIRS); do
7209                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7210         done
7211
7212         local expected=$NUMDIRS
7213         local cmd="$LFS find -S 8M $dir"
7214         local nums=$($cmd | wc -l)
7215
7216         [ $nums -eq $expected ] || {
7217                 $LFS getstripe -R $dir
7218                 error "'$cmd' wrong: found $nums, expected $expected"
7219         }
7220         rm -rf $dir
7221
7222         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7223
7224         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7225
7226         expected=$(((NUMDIRS + 1) * NUMFILES))
7227         cmd="$LFS find -stripe-size 512k -type f $dir"
7228         nums=$($cmd | wc -l)
7229         [ $nums -eq $expected ] ||
7230                 error "'$cmd' wrong: found $nums, expected $expected"
7231
7232         cmd="$LFS find -stripe-size +320k -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] ||
7235                 error "'$cmd' wrong: found $nums, expected $expected"
7236
7237         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7238         cmd="$LFS find -stripe-size +200k -type f $dir"
7239         nums=$($cmd | wc -l)
7240         [ $nums -eq $expected ] ||
7241                 error "'$cmd' wrong: found $nums, expected $expected"
7242
7243         cmd="$LFS find -stripe-size -640k -type f $dir"
7244         nums=$($cmd | wc -l)
7245         [ $nums -eq $expected ] ||
7246                 error "'$cmd' wrong: found $nums, expected $expected"
7247
7248         expected=4
7249         cmd="$LFS find -stripe-size 256k -type f $dir"
7250         nums=$($cmd | wc -l)
7251         [ $nums -eq $expected ] ||
7252                 error "'$cmd' wrong: found $nums, expected $expected"
7253
7254         cmd="$LFS find -stripe-size -320k -type f $dir"
7255         nums=$($cmd | wc -l)
7256         [ $nums -eq $expected ] ||
7257                 error "'$cmd' wrong: found $nums, expected $expected"
7258
7259         expected=0
7260         cmd="$LFS find -stripe-size 1024k -type f $dir"
7261         nums=$($cmd | wc -l)
7262         [ $nums -eq $expected ] ||
7263                 error "'$cmd' wrong: found $nums, expected $expected"
7264 }
7265 run_test 56t "check lfs find -stripe-size works"
7266
7267 test_56u() { # LU-611
7268         local dir=$DIR/$tdir
7269
7270         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7271
7272         if [[ $OSTCOUNT -gt 1 ]]; then
7273                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7274                 onestripe=4
7275         else
7276                 onestripe=0
7277         fi
7278
7279         local expected=$(((NUMDIRS + 1) * NUMFILES))
7280         local cmd="$LFS find -stripe-index 0 -type f $dir"
7281         local nums=$($cmd | wc -l)
7282
7283         [ $nums -eq $expected ] ||
7284                 error "'$cmd' wrong: found $nums, expected $expected"
7285
7286         expected=$onestripe
7287         cmd="$LFS find -stripe-index 1 -type f $dir"
7288         nums=$($cmd | wc -l)
7289         [ $nums -eq $expected ] ||
7290                 error "'$cmd' wrong: found $nums, expected $expected"
7291
7292         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7293         nums=$($cmd | wc -l)
7294         [ $nums -eq $expected ] ||
7295                 error "'$cmd' wrong: found $nums, expected $expected"
7296
7297         expected=0
7298         # This should produce an error and not return any files
7299         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7300         nums=$($cmd 2>/dev/null | wc -l)
7301         [ $nums -eq $expected ] ||
7302                 error "'$cmd' wrong: found $nums, expected $expected"
7303
7304         if [[ $OSTCOUNT -gt 1 ]]; then
7305                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7306                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7307                 nums=$($cmd | wc -l)
7308                 [ $nums -eq $expected ] ||
7309                         error "'$cmd' wrong: found $nums, expected $expected"
7310         fi
7311 }
7312 run_test 56u "check lfs find -stripe-index works"
7313
7314 test_56v() {
7315         local mdt_idx=0
7316         local dir=$DIR/$tdir
7317
7318         setup_56 $dir $NUMFILES $NUMDIRS
7319
7320         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7321         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7322
7323         for file in $($LFS find -m $UUID $dir); do
7324                 file_midx=$($LFS getstripe -m $file)
7325                 [ $file_midx -eq $mdt_idx ] ||
7326                         error "lfs find -m $UUID != getstripe -m $file_midx"
7327         done
7328 }
7329 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7330
7331 test_56wa() {
7332         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7334
7335         local dir=$DIR/$tdir
7336
7337         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7338
7339         local stripe_size=$($LFS getstripe -S -d $dir) ||
7340                 error "$LFS getstripe -S -d $dir failed"
7341         stripe_size=${stripe_size%% *}
7342
7343         local file_size=$((stripe_size * OSTCOUNT))
7344         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7345         local required_space=$((file_num * file_size))
7346         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7347                            head -n1)
7348         (( free_space >= required_space / 1024 )) ||
7349                 skip_env "need $required_space, have $free_space kbytes"
7350
7351         local dd_bs=65536
7352         local dd_count=$((file_size / dd_bs))
7353
7354         # write data into the files
7355         local i
7356         local j
7357         local file
7358
7359         for ((i = 1; i <= NUMFILES; i++ )); do
7360                 file=$dir/file$i
7361                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7362                         error "write data into $file failed"
7363         done
7364         for ((i = 1; i <= NUMDIRS; i++ )); do
7365                 for ((j = 1; j <= NUMFILES; j++ )); do
7366                         file=$dir/dir$i/file$j
7367                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7368                                 error "write data into $file failed"
7369                 done
7370         done
7371
7372         # $LFS_MIGRATE will fail if hard link migration is unsupported
7373         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7374                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7375                         error "creating links to $dir/dir1/file1 failed"
7376         fi
7377
7378         local expected=-1
7379
7380         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7381
7382         # lfs_migrate file
7383         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7384
7385         echo "$cmd"
7386         eval $cmd || error "$cmd failed"
7387
7388         check_stripe_count $dir/file1 $expected
7389
7390         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7391                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7392                 # OST 1 if it is on OST 0. This file is small enough to
7393                 # be on only one stripe.
7394                 file=$dir/migr_1_ost
7395                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7396                         error "write data into $file failed"
7397                 local obdidx=$($LFS getstripe -i $file)
7398                 local oldmd5=$(md5sum $file)
7399                 local newobdidx=0
7400
7401                 (( obdidx != 0 )) || newobdidx=1
7402                 cmd="$LFS migrate -i $newobdidx $file"
7403                 echo $cmd
7404                 eval $cmd || error "$cmd failed"
7405
7406                 local realobdix=$($LFS getstripe -i $file)
7407                 local newmd5=$(md5sum $file)
7408
7409                 (( $newobdidx == $realobdix )) ||
7410                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7411                 [[ "$oldmd5" == "$newmd5" ]] ||
7412                         error "md5sum differ: $oldmd5, $newmd5"
7413         fi
7414
7415         # lfs_migrate dir
7416         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7417         echo "$cmd"
7418         eval $cmd || error "$cmd failed"
7419
7420         for (( j = 1; j <= NUMFILES; j++ )); do
7421                 check_stripe_count $dir/dir1/file$j $expected
7422         done
7423
7424         # lfs_migrate works with lfs find
7425         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7426              $LFS_MIGRATE -y -c $expected"
7427         echo "$cmd"
7428         eval $cmd || error "$cmd failed"
7429
7430         for (( i = 2; i <= NUMFILES; i++ )); do
7431                 check_stripe_count $dir/file$i $expected
7432         done
7433         for (( i = 2; i <= NUMDIRS; i++ )); do
7434                 for (( j = 1; j <= NUMFILES; j++ )); do
7435                         check_stripe_count $dir/dir$i/file$j $expected
7436                 done
7437         done
7438 }
7439 run_test 56wa "check lfs_migrate -c stripe_count works"
7440
7441 test_56wb() {
7442         local file1=$DIR/$tdir/file1
7443         local create_pool=false
7444         local initial_pool=$($LFS getstripe -p $DIR)
7445         local pool_list=()
7446         local pool=""
7447
7448         echo -n "Creating test dir..."
7449         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7450         echo "done."
7451
7452         echo -n "Creating test file..."
7453         touch $file1 || error "cannot create file"
7454         echo "done."
7455
7456         echo -n "Detecting existing pools..."
7457         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7458
7459         if [ ${#pool_list[@]} -gt 0 ]; then
7460                 echo "${pool_list[@]}"
7461                 for thispool in "${pool_list[@]}"; do
7462                         if [[ -z "$initial_pool" ||
7463                               "$initial_pool" != "$thispool" ]]; then
7464                                 pool="$thispool"
7465                                 echo "Using existing pool '$pool'"
7466                                 break
7467                         fi
7468                 done
7469         else
7470                 echo "none detected."
7471         fi
7472         if [ -z "$pool" ]; then
7473                 pool=${POOL:-testpool}
7474                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7475                 echo -n "Creating pool '$pool'..."
7476                 create_pool=true
7477                 pool_add $pool &> /dev/null ||
7478                         error "pool_add failed"
7479                 echo "done."
7480
7481                 echo -n "Adding target to pool..."
7482                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7483                         error "pool_add_targets failed"
7484                 echo "done."
7485         fi
7486
7487         echo -n "Setting pool using -p option..."
7488         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7489                 error "migrate failed rc = $?"
7490         echo "done."
7491
7492         echo -n "Verifying test file is in pool after migrating..."
7493         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7494                 error "file was not migrated to pool $pool"
7495         echo "done."
7496
7497         echo -n "Removing test file from pool '$pool'..."
7498         # "lfs migrate $file" won't remove the file from the pool
7499         # until some striping information is changed.
7500         $LFS migrate -c 1 $file1 &> /dev/null ||
7501                 error "cannot remove from pool"
7502         [ "$($LFS getstripe -p $file1)" ] &&
7503                 error "pool still set"
7504         echo "done."
7505
7506         echo -n "Setting pool using --pool option..."
7507         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7508                 error "migrate failed rc = $?"
7509         echo "done."
7510
7511         # Clean up
7512         rm -f $file1
7513         if $create_pool; then
7514                 destroy_test_pools 2> /dev/null ||
7515                         error "destroy test pools failed"
7516         fi
7517 }
7518 run_test 56wb "check lfs_migrate pool support"
7519
7520 test_56wc() {
7521         local file1="$DIR/$tdir/$tfile"
7522         local md5
7523         local parent_ssize
7524         local parent_scount
7525         local cur_ssize
7526         local cur_scount
7527         local orig_ssize
7528         local new_scount
7529         local cur_comp
7530
7531         echo -n "Creating test dir..."
7532         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7533         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7534                 error "cannot set stripe by '-S 1M -c 1'"
7535         echo "done"
7536
7537         echo -n "Setting initial stripe for test file..."
7538         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7539                 error "cannot set stripe"
7540         cur_ssize=$($LFS getstripe -S "$file1")
7541         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7542         echo "done."
7543
7544         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7545         stack_trap "rm -f $file1"
7546         md5="$(md5sum $file1)"
7547
7548         # File currently set to -S 512K -c 1
7549
7550         # Ensure -c and -S options are rejected when -R is set
7551         echo -n "Verifying incompatible options are detected..."
7552         $LFS_MIGRATE -R -c 1 "$file1" &&
7553                 error "incompatible -R and -c options not detected"
7554         $LFS_MIGRATE -R -S 1M "$file1" &&
7555                 error "incompatible -R and -S options not detected"
7556         $LFS_MIGRATE -R -p pool "$file1" &&
7557                 error "incompatible -R and -p options not detected"
7558         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7559                 error "incompatible -R and -E options not detected"
7560         $LFS_MIGRATE -R -A "$file1" &&
7561                 error "incompatible -R and -A options not detected"
7562         $LFS_MIGRATE -A -c 1 "$file1" &&
7563                 error "incompatible -A and -c options not detected"
7564         $LFS_MIGRATE -A -S 1M "$file1" &&
7565                 error "incompatible -A and -S options not detected"
7566         $LFS_MIGRATE -A -p pool "$file1" &&
7567                 error "incompatible -A and -p options not detected"
7568         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7569                 error "incompatible -A and -E options not detected"
7570         echo "done."
7571
7572         # Ensure unrecognized options are passed through to 'lfs migrate'
7573         echo -n "Verifying -S option is passed through to lfs migrate..."
7574         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7575         cur_ssize=$($LFS getstripe -S "$file1")
7576         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7577         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7578         echo "done."
7579
7580         # File currently set to -S 1M -c 1
7581
7582         # Ensure long options are supported
7583         echo -n "Verifying long options supported..."
7584         $LFS_MIGRATE --non-block "$file1" ||
7585                 error "long option without argument not supported"
7586         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7587                 error "long option with argument not supported"
7588         cur_ssize=$($LFS getstripe -S "$file1")
7589         (( cur_ssize == 524288 )) ||
7590                 error "migrate --stripe-size $cur_ssize != 524288"
7591         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7592         echo "done."
7593
7594         # File currently set to -S 512K -c 1
7595
7596         if (( OSTCOUNT > 1 )); then
7597                 echo -n "Verifying explicit stripe count can be set..."
7598                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7599                 cur_scount=$($LFS getstripe -c "$file1")
7600                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7601                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7602                         error "file data has changed (3)"
7603                 echo "done."
7604         fi
7605
7606         # File currently set to -S 512K -c 1 or -S 512K -c 2
7607
7608         # Ensure parent striping is used if -R is set, and no stripe
7609         # count or size is specified
7610         echo -n "Setting stripe for parent directory..."
7611         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7612                 error "cannot set stripe '-S 2M -c 1'"
7613         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7614         echo "done."
7615
7616         echo -n "Verifying restripe option uses parent stripe settings..."
7617         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7618         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7619         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7620         cur_ssize=$($LFS getstripe -S "$file1")
7621         (( cur_ssize == parent_ssize )) ||
7622                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7623         cur_scount=$($LFS getstripe -c "$file1")
7624         (( cur_scount == parent_scount )) ||
7625                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7626         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7627         echo "done."
7628
7629         # File currently set to -S 1M -c 1
7630
7631         # Ensure striping is preserved if -R is not set, and no stripe
7632         # count or size is specified
7633         echo -n "Verifying striping size preserved when not specified..."
7634         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7635         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7636                 error "cannot set stripe on parent directory"
7637         $LFS_MIGRATE "$file1" || error "migrate failed"
7638         cur_ssize=$($LFS getstripe -S "$file1")
7639         (( cur_ssize == orig_ssize )) ||
7640                 error "migrate by default $cur_ssize != $orig_ssize"
7641         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7642         echo "done."
7643
7644         # Ensure file name properly detected when final option has no argument
7645         echo -n "Verifying file name properly detected..."
7646         $LFS_MIGRATE "$file1" ||
7647                 error "file name interpreted as option argument"
7648         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7649         echo "done."
7650
7651         # Ensure PFL arguments are passed through properly
7652         echo -n "Verifying PFL options passed through..."
7653         new_scount=$(((OSTCOUNT + 1) / 2))
7654         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7655                 error "migrate PFL arguments failed"
7656         cur_comp=$($LFS getstripe --comp-count $file1)
7657         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7658         cur_scount=$($LFS getstripe --stripe-count $file1)
7659         (( cur_scount == new_scount)) ||
7660                 error "PFL stripe count $cur_scount != $new_scount"
7661         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7662         echo "done."
7663 }
7664 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7665
7666 test_56wd() {
7667         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7668
7669         local file1=$DIR/$tdir/$tfile
7670
7671         echo -n "Creating test dir..."
7672         test_mkdir $DIR/$tdir || error "cannot create dir"
7673         echo "done."
7674
7675         echo -n "Creating test file..."
7676         echo "$tfile" > $file1
7677         echo "done."
7678
7679         # Ensure 'lfs migrate' will fail by using a non-existent option,
7680         # and make sure rsync is not called to recover
7681         echo -n "Make sure --no-rsync option works..."
7682         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7683                 grep -q 'refusing to fall back to rsync' ||
7684                 error "rsync was called with --no-rsync set"
7685         echo "done."
7686
7687         # Ensure rsync is called without trying 'lfs migrate' first
7688         echo -n "Make sure --rsync option works..."
7689         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7690                 grep -q 'falling back to rsync' &&
7691                 error "lfs migrate was called with --rsync set"
7692         echo "done."
7693 }
7694 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7695
7696 test_56we() {
7697         local td=$DIR/$tdir
7698         local tf=$td/$tfile
7699
7700         test_mkdir $td || error "cannot create $td"
7701         touch $tf || error "cannot touch $tf"
7702
7703         echo -n "Make sure --non-direct|-D works..."
7704         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7705                 grep -q "lfs migrate --non-direct" ||
7706                 error "--non-direct option cannot work correctly"
7707         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7708                 grep -q "lfs migrate -D" ||
7709                 error "-D option cannot work correctly"
7710         echo "done."
7711 }
7712 run_test 56we "check lfs_migrate --non-direct|-D support"
7713
7714 test_56x() {
7715         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7716         check_swap_layouts_support
7717
7718         local dir=$DIR/$tdir
7719         local ref1=/etc/passwd
7720         local file1=$dir/file1
7721
7722         test_mkdir $dir || error "creating dir $dir"
7723         $LFS setstripe -c 2 $file1
7724         cp $ref1 $file1
7725         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7726         stripe=$($LFS getstripe -c $file1)
7727         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7728         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7729
7730         # clean up
7731         rm -f $file1
7732 }
7733 run_test 56x "lfs migration support"
7734
7735 test_56xa() {
7736         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7737         check_swap_layouts_support
7738
7739         local dir=$DIR/$tdir/$testnum
7740
7741         test_mkdir -p $dir
7742
7743         local ref1=/etc/passwd
7744         local file1=$dir/file1
7745
7746         $LFS setstripe -c 2 $file1
7747         cp $ref1 $file1
7748         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7749
7750         local stripe=$($LFS getstripe -c $file1)
7751
7752         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7753         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7754
7755         # clean up
7756         rm -f $file1
7757 }
7758 run_test 56xa "lfs migration --block support"
7759
7760 check_migrate_links() {
7761         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7762         local dir="$1"
7763         local file1="$dir/file1"
7764         local begin="$2"
7765         local count="$3"
7766         local runas="$4"
7767         local total_count=$(($begin + $count - 1))
7768         local symlink_count=10
7769         local uniq_count=10
7770
7771         if [ ! -f "$file1" ]; then
7772                 echo -n "creating initial file..."
7773                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7774                         error "cannot setstripe initial file"
7775                 echo "done"
7776
7777                 echo -n "creating symlinks..."
7778                 for s in $(seq 1 $symlink_count); do
7779                         ln -s "$file1" "$dir/slink$s" ||
7780                                 error "cannot create symlinks"
7781                 done
7782                 echo "done"
7783
7784                 echo -n "creating nonlinked files..."
7785                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7786                         error "cannot create nonlinked files"
7787                 echo "done"
7788         fi
7789
7790         # create hard links
7791         if [ ! -f "$dir/file$total_count" ]; then
7792                 echo -n "creating hard links $begin:$total_count..."
7793                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7794                         /dev/null || error "cannot create hard links"
7795                 echo "done"
7796         fi
7797
7798         echo -n "checking number of hard links listed in xattrs..."
7799         local fid=$($LFS getstripe -F "$file1")
7800         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7801
7802         echo "${#paths[*]}"
7803         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7804                         skip "hard link list has unexpected size, skipping test"
7805         fi
7806         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7807                         error "link names should exceed xattrs size"
7808         fi
7809
7810         echo -n "migrating files..."
7811         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7812         local rc=$?
7813         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7814         echo "done"
7815
7816         # make sure all links have been properly migrated
7817         echo -n "verifying files..."
7818         fid=$($LFS getstripe -F "$file1") ||
7819                 error "cannot get fid for file $file1"
7820         for i in $(seq 2 $total_count); do
7821                 local fid2=$($LFS getstripe -F $dir/file$i)
7822
7823                 [ "$fid2" == "$fid" ] ||
7824                         error "migrated hard link has mismatched FID"
7825         done
7826
7827         # make sure hard links were properly detected, and migration was
7828         # performed only once for the entire link set; nonlinked files should
7829         # also be migrated
7830         local actual=$(grep -c 'done' <<< "$migrate_out")
7831         local expected=$(($uniq_count + 1))
7832
7833         [ "$actual" -eq  "$expected" ] ||
7834                 error "hard links individually migrated ($actual != $expected)"
7835
7836         # make sure the correct number of hard links are present
7837         local hardlinks=$(stat -c '%h' "$file1")
7838
7839         [ $hardlinks -eq $total_count ] ||
7840                 error "num hard links $hardlinks != $total_count"
7841         echo "done"
7842
7843         return 0
7844 }
7845
7846 test_56xb() {
7847         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7848                 skip "Need MDS version at least 2.10.55"
7849
7850         local dir="$DIR/$tdir"
7851
7852         test_mkdir "$dir" || error "cannot create dir $dir"
7853
7854         echo "testing lfs migrate mode when all links fit within xattrs"
7855         check_migrate_links "$dir" 2 99
7856
7857         echo "testing rsync mode when all links fit within xattrs"
7858         check_migrate_links --rsync "$dir" 2 99
7859
7860         echo "testing lfs migrate mode when all links do not fit within xattrs"
7861         check_migrate_links "$dir" 101 100
7862
7863         echo "testing rsync mode when all links do not fit within xattrs"
7864         check_migrate_links --rsync "$dir" 101 100
7865
7866         chown -R $RUNAS_ID $dir
7867         echo "testing non-root lfs migrate mode when not all links are in xattr"
7868         check_migrate_links "$dir" 101 100 "$RUNAS"
7869
7870         # clean up
7871         rm -rf $dir
7872 }
7873 run_test 56xb "lfs migration hard link support"
7874
7875 test_56xc() {
7876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7877
7878         local dir="$DIR/$tdir"
7879
7880         test_mkdir "$dir" || error "cannot create dir $dir"
7881
7882         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7883         echo -n "Setting initial stripe for 20MB test file..."
7884         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7885                 error "cannot setstripe 20MB file"
7886         echo "done"
7887         echo -n "Sizing 20MB test file..."
7888         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7889         echo "done"
7890         echo -n "Verifying small file autostripe count is 1..."
7891         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7892                 error "cannot migrate 20MB file"
7893         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7894                 error "cannot get stripe for $dir/20mb"
7895         [ $stripe_count -eq 1 ] ||
7896                 error "unexpected stripe count $stripe_count for 20MB file"
7897         rm -f "$dir/20mb"
7898         echo "done"
7899
7900         # Test 2: File is small enough to fit within the available space on
7901         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7902         # have at least an additional 1KB for each desired stripe for test 3
7903         echo -n "Setting stripe for 1GB test file..."
7904         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7905         echo "done"
7906         echo -n "Sizing 1GB test file..."
7907         # File size is 1GB + 3KB
7908         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7909         echo "done"
7910
7911         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7912         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7913         if (( avail > 524288 * OSTCOUNT )); then
7914                 echo -n "Migrating 1GB file..."
7915                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7916                         error "cannot migrate 1GB file"
7917                 echo "done"
7918                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7919                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7920                         error "cannot getstripe for 1GB file"
7921                 [ $stripe_count -eq 2 ] ||
7922                         error "unexpected stripe count $stripe_count != 2"
7923                 echo "done"
7924         fi
7925
7926         # Test 3: File is too large to fit within the available space on
7927         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7928         if [ $OSTCOUNT -ge 3 ]; then
7929                 # The required available space is calculated as
7930                 # file size (1GB + 3KB) / OST count (3).
7931                 local kb_per_ost=349526
7932
7933                 echo -n "Migrating 1GB file with limit..."
7934                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7935                         error "cannot migrate 1GB file with limit"
7936                 echo "done"
7937
7938                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7939                 echo -n "Verifying 1GB autostripe count with limited space..."
7940                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7941                         error "unexpected stripe count $stripe_count (min 3)"
7942                 echo "done"
7943         fi
7944
7945         # clean up
7946         rm -rf $dir
7947 }
7948 run_test 56xc "lfs migration autostripe"
7949
7950 test_56xd() {
7951         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7952
7953         local dir=$DIR/$tdir
7954         local f_mgrt=$dir/$tfile.mgrt
7955         local f_yaml=$dir/$tfile.yaml
7956         local f_copy=$dir/$tfile.copy
7957         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7958         local layout_copy="-c 2 -S 2M -i 1"
7959         local yamlfile=$dir/yamlfile
7960         local layout_before;
7961         local layout_after;
7962
7963         test_mkdir "$dir" || error "cannot create dir $dir"
7964         $LFS setstripe $layout_yaml $f_yaml ||
7965                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7966         $LFS getstripe --yaml $f_yaml > $yamlfile
7967         $LFS setstripe $layout_copy $f_copy ||
7968                 error "cannot setstripe $f_copy with layout $layout_copy"
7969         touch $f_mgrt
7970         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7971
7972         # 1. test option --yaml
7973         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7974                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7975         layout_before=$(get_layout_param $f_yaml)
7976         layout_after=$(get_layout_param $f_mgrt)
7977         [ "$layout_after" == "$layout_before" ] ||
7978                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7979
7980         # 2. test option --copy
7981         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7982                 error "cannot migrate $f_mgrt with --copy $f_copy"
7983         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
7984         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
7985         [ "$layout_after" == "$layout_before" ] ||
7986                 error "lfs_migrate --copy: $layout_after != $layout_before"
7987 }
7988 run_test 56xd "check lfs_migrate --yaml and --copy support"
7989
7990 test_56xe() {
7991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7992
7993         local dir=$DIR/$tdir
7994         local f_comp=$dir/$tfile
7995         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7996         local layout_before=""
7997         local layout_after=""
7998
7999         test_mkdir "$dir" || error "cannot create dir $dir"
8000         $LFS setstripe $layout $f_comp ||
8001                 error "cannot setstripe $f_comp with layout $layout"
8002         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8003         dd if=/dev/zero of=$f_comp bs=1M count=4
8004
8005         # 1. migrate a comp layout file by lfs_migrate
8006         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8007         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8008         [ "$layout_before" == "$layout_after" ] ||
8009                 error "lfs_migrate: $layout_before != $layout_after"
8010
8011         # 2. migrate a comp layout file by lfs migrate
8012         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8013         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8014         [ "$layout_before" == "$layout_after" ] ||
8015                 error "lfs migrate: $layout_before != $layout_after"
8016 }
8017 run_test 56xe "migrate a composite layout file"
8018
8019 test_56xf() {
8020         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8021
8022         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8023                 skip "Need server version at least 2.13.53"
8024
8025         local dir=$DIR/$tdir
8026         local f_comp=$dir/$tfile
8027         local layout="-E 1M -c1 -E -1 -c2"
8028         local fid_before=""
8029         local fid_after=""
8030
8031         test_mkdir "$dir" || error "cannot create dir $dir"
8032         $LFS setstripe $layout $f_comp ||
8033                 error "cannot setstripe $f_comp with layout $layout"
8034         fid_before=$($LFS getstripe --fid $f_comp)
8035         dd if=/dev/zero of=$f_comp bs=1M count=4
8036
8037         # 1. migrate a comp layout file to a comp layout
8038         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8039         fid_after=$($LFS getstripe --fid $f_comp)
8040         [ "$fid_before" == "$fid_after" ] ||
8041                 error "comp-to-comp migrate: $fid_before != $fid_after"
8042
8043         # 2. migrate a comp layout file to a plain layout
8044         $LFS migrate -c2 $f_comp ||
8045                 error "cannot migrate $f_comp by lfs migrate"
8046         fid_after=$($LFS getstripe --fid $f_comp)
8047         [ "$fid_before" == "$fid_after" ] ||
8048                 error "comp-to-plain migrate: $fid_before != $fid_after"
8049
8050         # 3. migrate a plain layout file to a comp layout
8051         $LFS migrate $layout $f_comp ||
8052                 error "cannot migrate $f_comp by lfs migrate"
8053         fid_after=$($LFS getstripe --fid $f_comp)
8054         [ "$fid_before" == "$fid_after" ] ||
8055                 error "plain-to-comp migrate: $fid_before != $fid_after"
8056 }
8057 run_test 56xf "FID is not lost during migration of a composite layout file"
8058
8059 check_file_ost_range() {
8060         local file="$1"
8061         shift
8062         local range="$*"
8063         local -a file_range
8064         local idx
8065
8066         file_range=($($LFS getstripe -y "$file" |
8067                 awk '/l_ost_idx:/ { print $NF }'))
8068
8069         if [[ "${#file_range[@]}" = 0 ]]; then
8070                 echo "No osts found for $file"
8071                 return 1
8072         fi
8073
8074         for idx in "${file_range[@]}"; do
8075                 [[ " $range " =~ " $idx " ]] ||
8076                         return 1
8077         done
8078
8079         return 0
8080 }
8081
8082 sub_test_56xg() {
8083         local stripe_opt="$1"
8084         local pool="$2"
8085         shift 2
8086         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8087
8088         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8089                 error "Fail to migrate $tfile on $pool"
8090         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8091                 error "$tfile is not in pool $pool"
8092         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8093                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8094 }
8095
8096 test_56xg() {
8097         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8098         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8099         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8100                 skip "Need MDS version newer than 2.14.52"
8101
8102         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8103         local -a pool_ranges=("0 0" "1 1" "0 1")
8104
8105         # init pools
8106         for i in "${!pool_names[@]}"; do
8107                 pool_add ${pool_names[$i]} ||
8108                         error "pool_add failed (pool: ${pool_names[$i]})"
8109                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8110                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8111         done
8112
8113         # init the file to migrate
8114         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8115                 error "Unable to create $tfile on OST1"
8116         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8117                 error "Unable to write on $tfile"
8118
8119         echo "1. migrate $tfile on pool ${pool_names[0]}"
8120         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8121
8122         echo "2. migrate $tfile on pool ${pool_names[2]}"
8123         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8124
8125         echo "3. migrate $tfile on pool ${pool_names[1]}"
8126         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8127
8128         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8129         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8130         echo
8131
8132         # Clean pools
8133         destroy_test_pools ||
8134                 error "pool_destroy failed"
8135 }
8136 run_test 56xg "lfs migrate pool support"
8137
8138 test_56xh() {
8139         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8140
8141         local size_mb=25
8142         local file1=$DIR/$tfile
8143         local tmp1=$TMP/$tfile.tmp
8144
8145         $LFS setstripe -c 2 $file1
8146
8147         stack_trap "rm -f $file1 $tmp1"
8148         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8149                         error "error creating $tmp1"
8150         ls -lsh $tmp1
8151         cp $tmp1 $file1
8152
8153         local start=$SECONDS
8154
8155         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8156                 error "migrate failed rc = $?"
8157
8158         local elapsed=$((SECONDS - start))
8159
8160         # with 1MB/s, elapsed should equal size_mb
8161         (( elapsed >= size_mb * 95 / 100 )) ||
8162                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8163
8164         (( elapsed <= size_mb * 120 / 100 )) ||
8165                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8166
8167         (( elapsed <= size_mb * 150 / 100 )) ||
8168                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8169
8170         stripe=$($LFS getstripe -c $file1)
8171         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8172         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8173
8174         # Clean up file (since it is multiple MB)
8175         rm -f $file1 $tmp1
8176 }
8177 run_test 56xh "lfs migrate bandwidth limitation support"
8178
8179 test_56xi() {
8180         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8181         verify_yaml_available || skip_env "YAML verification not installed"
8182
8183         local size_mb=5
8184         local file1=$DIR/$tfile.1
8185         local file2=$DIR/$tfile.2
8186         local file3=$DIR/$tfile.3
8187         local output_file=$DIR/$tfile.out
8188         local tmp1=$TMP/$tfile.tmp
8189
8190         $LFS setstripe -c 2 $file1
8191         $LFS setstripe -c 2 $file2
8192         $LFS setstripe -c 2 $file3
8193
8194         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8195         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8196                         error "error creating $tmp1"
8197         ls -lsh $tmp1
8198         cp $tmp1 $file1
8199         cp $tmp1 $file2
8200         cp $tmp1 $file3
8201
8202         $LFS migrate --stats --stats-interval=1 \
8203                 -c 1 $file1 $file2 $file3 1> $output_file ||
8204                 error "migrate failed rc = $?"
8205
8206         cat $output_file
8207         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8208
8209         # Clean up file (since it is multiple MB)
8210         rm -f $file1 $file2 $file3 $tmp1 $output_file
8211 }
8212 run_test 56xi "lfs migrate stats support"
8213
8214 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8215         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8216
8217         local file=$DIR/$tfile
8218         local linkdir=$DIR/$tdir
8219
8220         test_mkdir $linkdir || error "fail to create $linkdir"
8221         $LFS setstripe -i 0 -c 1 -S1M $file
8222         dd if=/dev/urandom of=$file bs=1M count=10 ||
8223                 error "fail to create $file"
8224
8225         # Create file links
8226         local cpts
8227         local threads_max
8228         local nlinks
8229
8230         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8231         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8232         (( nlinks = thread_max * 3 / 2 / cpts))
8233
8234         echo "create $nlinks hard links of $file"
8235         createmany -l $file $linkdir/link $nlinks
8236
8237         # Parallel migrates (should not block)
8238         local i
8239         for ((i = 0; i < nlinks; i++)); do
8240                 echo $linkdir/link$i
8241         done | xargs -n1 -P $nlinks $LFS migrate -c2
8242
8243         local stripe_count
8244         stripe_count=$($LFS getstripe -c $file) ||
8245                 error "fail to get stripe count on $file"
8246
8247         ((stripe_count == 2)) ||
8248                 error "fail to migrate $file (stripe_count = $stripe_count)"
8249 }
8250 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8251
8252 test_56y() {
8253         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8254                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8255
8256         local res=""
8257         local dir=$DIR/$tdir
8258         local f1=$dir/file1
8259         local f2=$dir/file2
8260
8261         test_mkdir -p $dir || error "creating dir $dir"
8262         touch $f1 || error "creating std file $f1"
8263         $MULTIOP $f2 H2c || error "creating released file $f2"
8264
8265         # a directory can be raid0, so ask only for files
8266         res=$($LFS find $dir -L raid0 -type f | wc -l)
8267         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8268
8269         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8270         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8271
8272         # only files can be released, so no need to force file search
8273         res=$($LFS find $dir -L released)
8274         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8275
8276         res=$($LFS find $dir -type f \! -L released)
8277         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8278 }
8279 run_test 56y "lfs find -L raid0|released"
8280
8281 test_56z() { # LU-4824
8282         # This checks to make sure 'lfs find' continues after errors
8283         # There are two classes of errors that should be caught:
8284         # - If multiple paths are provided, all should be searched even if one
8285         #   errors out
8286         # - If errors are encountered during the search, it should not terminate
8287         #   early
8288         local dir=$DIR/$tdir
8289         local i
8290
8291         test_mkdir $dir
8292         for i in d{0..9}; do
8293                 test_mkdir $dir/$i
8294                 touch $dir/$i/$tfile
8295         done
8296         $LFS find $DIR/non_existent_dir $dir &&
8297                 error "$LFS find did not return an error"
8298         # Make a directory unsearchable. This should NOT be the last entry in
8299         # directory order.  Arbitrarily pick the 6th entry
8300         chmod 700 $($LFS find $dir -type d | sed '6!d')
8301
8302         $RUNAS $LFS find $DIR/non_existent $dir
8303         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8304
8305         # The user should be able to see 10 directories and 9 files
8306         (( count == 19 )) ||
8307                 error "$LFS find found $count != 19 entries after error"
8308 }
8309 run_test 56z "lfs find should continue after an error"
8310
8311 test_56aa() { # LU-5937
8312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8313
8314         local dir=$DIR/$tdir
8315
8316         mkdir $dir
8317         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8318
8319         createmany -o $dir/striped_dir/${tfile}- 1024
8320         local dirs=$($LFS find --size +8k $dir/)
8321
8322         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8323 }
8324 run_test 56aa "lfs find --size under striped dir"
8325
8326 test_56ab() { # LU-10705
8327         test_mkdir $DIR/$tdir
8328         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8329         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8330         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8331         # Flush writes to ensure valid blocks.  Need to be more thorough for
8332         # ZFS, since blocks are not allocated/returned to client immediately.
8333         sync_all_data
8334         wait_zfs_commit ost1 2
8335         cancel_lru_locks osc
8336         ls -ls $DIR/$tdir
8337
8338         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8339
8340         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8341
8342         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8343         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8344
8345         rm -f $DIR/$tdir/$tfile.[123]
8346 }
8347 run_test 56ab "lfs find --blocks"
8348
8349 # LU-11188
8350 test_56aca() {
8351         local dir="$DIR/$tdir"
8352         local perms=(001 002 003 004 005 006 007
8353                      010 020 030 040 050 060 070
8354                      100 200 300 400 500 600 700
8355                      111 222 333 444 555 666 777)
8356         local perm_minus=(8 8 4 8 4 4 2
8357                           8 8 4 8 4 4 2
8358                           8 8 4 8 4 4 2
8359                           4 4 2 4 2 2 1)
8360         local perm_slash=(8  8 12  8 12 12 14
8361                           8  8 12  8 12 12 14
8362                           8  8 12  8 12 12 14
8363                          16 16 24 16 24 24 28)
8364
8365         test_mkdir "$dir"
8366         for perm in ${perms[*]}; do
8367                 touch "$dir/$tfile.$perm"
8368                 chmod $perm "$dir/$tfile.$perm"
8369         done
8370
8371         for ((i = 0; i < ${#perms[*]}; i++)); do
8372                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8373                 (( $num == 1 )) ||
8374                         error "lfs find -perm ${perms[i]}:"\
8375                               "$num != 1"
8376
8377                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8378                 (( $num == ${perm_minus[i]} )) ||
8379                         error "lfs find -perm -${perms[i]}:"\
8380                               "$num != ${perm_minus[i]}"
8381
8382                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8383                 (( $num == ${perm_slash[i]} )) ||
8384                         error "lfs find -perm /${perms[i]}:"\
8385                               "$num != ${perm_slash[i]}"
8386         done
8387 }
8388 run_test 56aca "check lfs find -perm with octal representation"
8389
8390 test_56acb() {
8391         local dir=$DIR/$tdir
8392         # p is the permission of write and execute for user, group and other
8393         # without the umask. It is used to test +wx.
8394         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8395         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8396         local symbolic=(+t  a+t u+t g+t o+t
8397                         g+s u+s o+s +s o+sr
8398                         o=r,ug+o,u+w
8399                         u+ g+ o+ a+ ugo+
8400                         u- g- o- a- ugo-
8401                         u= g= o= a= ugo=
8402                         o=r,ug+o,u+w u=r,a+u,u+w
8403                         g=r,ugo=g,u+w u+x,+X +X
8404                         u+x,u+X u+X u+x,g+X o+r,+X
8405                         u+x,go+X +wx +rwx)
8406
8407         test_mkdir $dir
8408         for perm in ${perms[*]}; do
8409                 touch "$dir/$tfile.$perm"
8410                 chmod $perm "$dir/$tfile.$perm"
8411         done
8412
8413         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8414                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8415
8416                 (( $num == 1 )) ||
8417                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8418         done
8419 }
8420 run_test 56acb "check lfs find -perm with symbolic representation"
8421
8422 test_56acc() {
8423         local dir=$DIR/$tdir
8424         local tests="17777 787 789 abcd
8425                 ug=uu ug=a ug=gu uo=ou urw
8426                 u+xg+x a=r,u+x,"
8427
8428         test_mkdir $dir
8429         for err in $tests; do
8430                 if $LFS find $dir -perm $err 2>/dev/null; then
8431                         error "lfs find -perm $err: parsing should have failed"
8432                 fi
8433         done
8434 }
8435 run_test 56acc "check parsing error for lfs find -perm"
8436
8437 test_56ba() {
8438         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8439                 skip "Need MDS version at least 2.10.50"
8440
8441         # Create composite files with one component
8442         local dir=$DIR/$tdir
8443
8444         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8445         # Create composite files with three components
8446         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8447         # Create non-composite files
8448         createmany -o $dir/${tfile}- 10
8449
8450         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8451
8452         [[ $nfiles == 10 ]] ||
8453                 error "lfs find -E 1M found $nfiles != 10 files"
8454
8455         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8456         [[ $nfiles == 25 ]] ||
8457                 error "lfs find ! -E 1M found $nfiles != 25 files"
8458
8459         # All files have a component that starts at 0
8460         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8461         [[ $nfiles == 35 ]] ||
8462                 error "lfs find --component-start 0 - $nfiles != 35 files"
8463
8464         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8465         [[ $nfiles == 15 ]] ||
8466                 error "lfs find --component-start 2M - $nfiles != 15 files"
8467
8468         # All files created here have a componenet that does not starts at 2M
8469         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8470         [[ $nfiles == 35 ]] ||
8471                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8472
8473         # Find files with a specified number of components
8474         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8475         [[ $nfiles == 15 ]] ||
8476                 error "lfs find --component-count 3 - $nfiles != 15 files"
8477
8478         # Remember non-composite files have a component count of zero
8479         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8480         [[ $nfiles == 10 ]] ||
8481                 error "lfs find --component-count 0 - $nfiles != 10 files"
8482
8483         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8484         [[ $nfiles == 20 ]] ||
8485                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8486
8487         # All files have a flag called "init"
8488         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8489         [[ $nfiles == 35 ]] ||
8490                 error "lfs find --component-flags init - $nfiles != 35 files"
8491
8492         # Multi-component files will have a component not initialized
8493         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8494         [[ $nfiles == 15 ]] ||
8495                 error "lfs find !--component-flags init - $nfiles != 15 files"
8496
8497         rm -rf $dir
8498
8499 }
8500 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8501
8502 test_56ca() {
8503         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8504                 skip "Need MDS version at least 2.10.57"
8505
8506         local td=$DIR/$tdir
8507         local tf=$td/$tfile
8508         local dir
8509         local nfiles
8510         local cmd
8511         local i
8512         local j
8513
8514         # create mirrored directories and mirrored files
8515         mkdir $td || error "mkdir $td failed"
8516         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8517         createmany -o $tf- 10 || error "create $tf- failed"
8518
8519         for i in $(seq 2); do
8520                 dir=$td/dir$i
8521                 mkdir $dir || error "mkdir $dir failed"
8522                 $LFS mirror create -N$((3 + i)) $dir ||
8523                         error "create mirrored dir $dir failed"
8524                 createmany -o $dir/$tfile- 10 ||
8525                         error "create $dir/$tfile- failed"
8526         done
8527
8528         # change the states of some mirrored files
8529         echo foo > $tf-6
8530         for i in $(seq 2); do
8531                 dir=$td/dir$i
8532                 for j in $(seq 4 9); do
8533                         echo foo > $dir/$tfile-$j
8534                 done
8535         done
8536
8537         # find mirrored files with specific mirror count
8538         cmd="$LFS find --mirror-count 3 --type f $td"
8539         nfiles=$($cmd | wc -l)
8540         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8541
8542         cmd="$LFS find ! --mirror-count 3 --type f $td"
8543         nfiles=$($cmd | wc -l)
8544         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8545
8546         cmd="$LFS find --mirror-count +2 --type f $td"
8547         nfiles=$($cmd | wc -l)
8548         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8549
8550         cmd="$LFS find --mirror-count -6 --type f $td"
8551         nfiles=$($cmd | wc -l)
8552         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8553
8554         # find mirrored files with specific file state
8555         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8556         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8557
8558         cmd="$LFS find --mirror-state=ro --type f $td"
8559         nfiles=$($cmd | wc -l)
8560         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8561
8562         cmd="$LFS find ! --mirror-state=ro --type f $td"
8563         nfiles=$($cmd | wc -l)
8564         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8565
8566         cmd="$LFS find --mirror-state=wp --type f $td"
8567         nfiles=$($cmd | wc -l)
8568         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8569
8570         cmd="$LFS find ! --mirror-state=sp --type f $td"
8571         nfiles=$($cmd | wc -l)
8572         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8573 }
8574 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8575
8576 test_56da() { # LU-14179
8577         local path=$DIR/$tdir
8578
8579         test_mkdir $path
8580         cd $path
8581
8582         local longdir=$(str_repeat 'a' 255)
8583
8584         for i in {1..15}; do
8585                 path=$path/$longdir
8586                 test_mkdir $longdir
8587                 cd $longdir
8588         done
8589
8590         local len=${#path}
8591         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8592
8593         test_mkdir $lastdir
8594         cd $lastdir
8595         # PATH_MAX-1
8596         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8597
8598         # NAME_MAX
8599         touch $(str_repeat 'f' 255)
8600
8601         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8602                 error "lfs find reported an error"
8603
8604         rm -rf $DIR/$tdir
8605 }
8606 run_test 56da "test lfs find with long paths"
8607
8608 test_56ea() { #LU-10378
8609         local path=$DIR/$tdir
8610         local pool=$TESTNAME
8611
8612         # Create ost pool
8613         pool_add $pool || error "pool_add $pool failed"
8614         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8615                 error "adding targets to $pool failed"
8616
8617         # Set default pool on directory before creating file
8618         mkdir $path || error "mkdir $path failed"
8619         $LFS setstripe -p $pool $path ||
8620                 error "set OST pool on $pool failed"
8621         touch $path/$tfile || error "touch $path/$tfile failed"
8622
8623         # Compare basic file attributes from -printf and stat
8624         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8625         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8626
8627         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8628                 error "Attrs from lfs find and stat don't match"
8629
8630         # Compare Lustre attributes from lfs find and lfs getstripe
8631         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8632         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8633         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8634         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8635         local fpool=$($LFS getstripe --pool $path/$tfile)
8636         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8637
8638         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8639                 error "Attrs from lfs find and lfs getstripe don't match"
8640
8641         # Verify behavior for unknown escape/format sequences
8642         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8643
8644         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8645                 error "Escape/format codes don't match"
8646 }
8647 run_test 56ea "test lfs find -printf option"
8648
8649 test_56eb() {
8650         local dir=$DIR/$tdir
8651         local subdir_1=$dir/subdir_1
8652
8653         test_mkdir -p $subdir_1
8654         ln -s subdir_1 $dir/link_1
8655
8656         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8657                 error "symlink is not followed"
8658
8659         $LFS getstripe --no-follow $dir |
8660                 grep "^$dir/link_1 has no stripe info$" ||
8661                 error "symlink should not have stripe info"
8662
8663         touch $dir/testfile
8664         ln -s testfile $dir/file_link_2
8665
8666         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8667                 error "symlink is not followed"
8668
8669         $LFS getstripe --no-follow $dir |
8670                 grep "^$dir/file_link_2 has no stripe info$" ||
8671                 error "symlink should not have stripe info"
8672 }
8673 run_test 56eb "check lfs getstripe on symlink"
8674
8675 test_57a() {
8676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8677         # note test will not do anything if MDS is not local
8678         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8679                 skip_env "ldiskfs only test"
8680         fi
8681         remote_mds_nodsh && skip "remote MDS with nodsh"
8682
8683         local MNTDEV="osd*.*MDT*.mntdev"
8684         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8685         [ -z "$DEV" ] && error "can't access $MNTDEV"
8686         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8687                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8688                         error "can't access $DEV"
8689                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8690                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8691                 rm $TMP/t57a.dump
8692         done
8693 }
8694 run_test 57a "verify MDS filesystem created with large inodes =="
8695
8696 test_57b() {
8697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8698         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8699                 skip_env "ldiskfs only test"
8700         fi
8701         remote_mds_nodsh && skip "remote MDS with nodsh"
8702
8703         local dir=$DIR/$tdir
8704         local filecount=100
8705         local file1=$dir/f1
8706         local fileN=$dir/f$filecount
8707
8708         rm -rf $dir || error "removing $dir"
8709         test_mkdir -c1 $dir
8710         local mdtidx=$($LFS getstripe -m $dir)
8711         local mdtname=MDT$(printf %04x $mdtidx)
8712         local facet=mds$((mdtidx + 1))
8713
8714         echo "mcreating $filecount files"
8715         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8716
8717         # verify that files do not have EAs yet
8718         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8719                 error "$file1 has an EA"
8720         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8721                 error "$fileN has an EA"
8722
8723         sync
8724         sleep 1
8725         df $dir  #make sure we get new statfs data
8726         local mdsfree=$(do_facet $facet \
8727                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8728         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8729         local file
8730
8731         echo "opening files to create objects/EAs"
8732         for file in $(seq -f $dir/f%g 1 $filecount); do
8733                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8734                         error "opening $file"
8735         done
8736
8737         # verify that files have EAs now
8738         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8739         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8740
8741         sleep 1  #make sure we get new statfs data
8742         df $dir
8743         local mdsfree2=$(do_facet $facet \
8744                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8745         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8746
8747         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8748                 if [ "$mdsfree" != "$mdsfree2" ]; then
8749                         error "MDC before $mdcfree != after $mdcfree2"
8750                 else
8751                         echo "MDC before $mdcfree != after $mdcfree2"
8752                         echo "unable to confirm if MDS has large inodes"
8753                 fi
8754         fi
8755         rm -rf $dir
8756 }
8757 run_test 57b "default LOV EAs are stored inside large inodes ==="
8758
8759 test_58() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761         [ -z "$(which wiretest 2>/dev/null)" ] &&
8762                         skip_env "could not find wiretest"
8763
8764         wiretest
8765 }
8766 run_test 58 "verify cross-platform wire constants =============="
8767
8768 test_59() {
8769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8770
8771         echo "touch 130 files"
8772         createmany -o $DIR/f59- 130
8773         echo "rm 130 files"
8774         unlinkmany $DIR/f59- 130
8775         sync
8776         # wait for commitment of removal
8777         wait_delete_completed
8778 }
8779 run_test 59 "verify cancellation of llog records async ========="
8780
8781 TEST60_HEAD="test_60 run $RANDOM"
8782 test_60a() {
8783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8784         remote_mgs_nodsh && skip "remote MGS with nodsh"
8785         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8786                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8787                         skip_env "missing subtest run-llog.sh"
8788
8789         log "$TEST60_HEAD - from kernel mode"
8790         do_facet mgs "$LCTL dk > /dev/null"
8791         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8792         do_facet mgs $LCTL dk > $TMP/$tfile
8793
8794         # LU-6388: test llog_reader
8795         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8796         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8797         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8798                         skip_env "missing llog_reader"
8799         local fstype=$(facet_fstype mgs)
8800         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8801                 skip_env "Only for ldiskfs or zfs type mgs"
8802
8803         local mntpt=$(facet_mntpt mgs)
8804         local mgsdev=$(mgsdevname 1)
8805         local fid_list
8806         local fid
8807         local rec_list
8808         local rec
8809         local rec_type
8810         local obj_file
8811         local path
8812         local seq
8813         local oid
8814         local pass=true
8815
8816         #get fid and record list
8817         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8818                 tail -n 4))
8819         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8820                 tail -n 4))
8821         #remount mgs as ldiskfs or zfs type
8822         stop mgs || error "stop mgs failed"
8823         mount_fstype mgs || error "remount mgs failed"
8824         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8825                 fid=${fid_list[i]}
8826                 rec=${rec_list[i]}
8827                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8828                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8829                 oid=$((16#$oid))
8830
8831                 case $fstype in
8832                         ldiskfs )
8833                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8834                         zfs )
8835                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8836                 esac
8837                 echo "obj_file is $obj_file"
8838                 do_facet mgs $llog_reader $obj_file
8839
8840                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8841                         awk '{ print $3 }' | sed -e "s/^type=//g")
8842                 if [ $rec_type != $rec ]; then
8843                         echo "FAILED test_60a wrong record type $rec_type," \
8844                               "should be $rec"
8845                         pass=false
8846                         break
8847                 fi
8848
8849                 #check obj path if record type is LLOG_LOGID_MAGIC
8850                 if [ "$rec" == "1064553b" ]; then
8851                         path=$(do_facet mgs $llog_reader $obj_file |
8852                                 grep "path=" | awk '{ print $NF }' |
8853                                 sed -e "s/^path=//g")
8854                         if [ $obj_file != $mntpt/$path ]; then
8855                                 echo "FAILED test_60a wrong obj path" \
8856                                       "$montpt/$path, should be $obj_file"
8857                                 pass=false
8858                                 break
8859                         fi
8860                 fi
8861         done
8862         rm -f $TMP/$tfile
8863         #restart mgs before "error", otherwise it will block the next test
8864         stop mgs || error "stop mgs failed"
8865         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8866         $pass || error "test failed, see FAILED test_60a messages for specifics"
8867 }
8868 run_test 60a "llog_test run from kernel module and test llog_reader"
8869
8870 test_60b() { # bug 6411
8871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8872
8873         dmesg > $DIR/$tfile
8874         LLOG_COUNT=$(do_facet mgs dmesg |
8875                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8876                           /llog_[a-z]*.c:[0-9]/ {
8877                                 if (marker)
8878                                         from_marker++
8879                                 from_begin++
8880                           }
8881                           END {
8882                                 if (marker)
8883                                         print from_marker
8884                                 else
8885                                         print from_begin
8886                           }")
8887
8888         [[ $LLOG_COUNT -gt 120 ]] &&
8889                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8890 }
8891 run_test 60b "limit repeated messages from CERROR/CWARN"
8892
8893 test_60c() {
8894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8895
8896         echo "create 5000 files"
8897         createmany -o $DIR/f60c- 5000
8898 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8899         lctl set_param fail_loc=0x80000137
8900         unlinkmany $DIR/f60c- 5000
8901         lctl set_param fail_loc=0
8902 }
8903 run_test 60c "unlink file when mds full"
8904
8905 test_60d() {
8906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8907
8908         SAVEPRINTK=$(lctl get_param -n printk)
8909         # verify "lctl mark" is even working"
8910         MESSAGE="test message ID $RANDOM $$"
8911         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8912         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8913
8914         lctl set_param printk=0 || error "set lnet.printk failed"
8915         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8916         MESSAGE="new test message ID $RANDOM $$"
8917         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8918         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8919         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8920
8921         lctl set_param -n printk="$SAVEPRINTK"
8922 }
8923 run_test 60d "test printk console message masking"
8924
8925 test_60e() {
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         remote_mds_nodsh && skip "remote MDS with nodsh"
8928
8929         touch $DIR/$tfile
8930 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8931         do_facet mds1 lctl set_param fail_loc=0x15b
8932         rm $DIR/$tfile
8933 }
8934 run_test 60e "no space while new llog is being created"
8935
8936 test_60f() {
8937         local old_path=$($LCTL get_param -n debug_path)
8938
8939         stack_trap "$LCTL set_param debug_path=$old_path"
8940         stack_trap "rm -f $TMP/$tfile*"
8941         rm -f $TMP/$tfile* 2> /dev/null
8942         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8943         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8944         test_mkdir $DIR/$tdir
8945         # retry in case the open is cached and not released
8946         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8947                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8948                 sleep 0.1
8949         done
8950         ls $TMP/$tfile*
8951         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8952 }
8953 run_test 60f "change debug_path works"
8954
8955 test_60g() {
8956         local pid
8957         local i
8958
8959         test_mkdir -c $MDSCOUNT $DIR/$tdir
8960
8961         (
8962                 local index=0
8963                 while true; do
8964                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8965                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8966                                 2>/dev/null
8967                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8968                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8969                         index=$((index + 1))
8970                 done
8971         ) &
8972
8973         pid=$!
8974
8975         for i in {0..100}; do
8976                 # define OBD_FAIL_OSD_TXN_START    0x19a
8977                 local index=$((i % MDSCOUNT + 1))
8978
8979                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8980                         > /dev/null
8981                 sleep 0.01
8982         done
8983
8984         kill -9 $pid
8985
8986         for i in $(seq $MDSCOUNT); do
8987                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8988         done
8989
8990         mkdir $DIR/$tdir/new || error "mkdir failed"
8991         rmdir $DIR/$tdir/new || error "rmdir failed"
8992
8993         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8994                 -t namespace
8995         for i in $(seq $MDSCOUNT); do
8996                 wait_update_facet mds$i "$LCTL get_param -n \
8997                         mdd.$(facet_svc mds$i).lfsck_namespace |
8998                         awk '/^status/ { print \\\$2 }'" "completed"
8999         done
9000
9001         ls -R $DIR/$tdir
9002         rm -rf $DIR/$tdir || error "rmdir failed"
9003 }
9004 run_test 60g "transaction abort won't cause MDT hung"
9005
9006 test_60h() {
9007         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9008                 skip "Need MDS version at least 2.12.52"
9009         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9010
9011         local f
9012
9013         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9014         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9015         for fail_loc in 0x80000188 0x80000189; do
9016                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9017                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9018                         error "mkdir $dir-$fail_loc failed"
9019                 for i in {0..10}; do
9020                         # create may fail on missing stripe
9021                         echo $i > $DIR/$tdir-$fail_loc/$i
9022                 done
9023                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9024                         error "getdirstripe $tdir-$fail_loc failed"
9025                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9026                         error "migrate $tdir-$fail_loc failed"
9027                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9028                         error "getdirstripe $tdir-$fail_loc failed"
9029                 pushd $DIR/$tdir-$fail_loc
9030                 for f in *; do
9031                         echo $f | cmp $f - || error "$f data mismatch"
9032                 done
9033                 popd
9034                 rm -rf $DIR/$tdir-$fail_loc
9035         done
9036 }
9037 run_test 60h "striped directory with missing stripes can be accessed"
9038
9039 function t60i_load() {
9040         mkdir $DIR/$tdir
9041         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9042         $LCTL set_param fail_loc=0x131c fail_val=1
9043         for ((i=0; i<5000; i++)); do
9044                 touch $DIR/$tdir/f$i
9045         done
9046 }
9047
9048 test_60i() {
9049         changelog_register || error "changelog_register failed"
9050         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9051         changelog_users $SINGLEMDS | grep -q $cl_user ||
9052                 error "User $cl_user not found in changelog_users"
9053         changelog_chmask "ALL"
9054         t60i_load &
9055         local PID=$!
9056         for((i=0; i<100; i++)); do
9057                 changelog_dump >/dev/null ||
9058                         error "can't read changelog"
9059         done
9060         kill $PID
9061         wait $PID
9062         changelog_deregister || error "changelog_deregister failed"
9063         $LCTL set_param fail_loc=0
9064 }
9065 run_test 60i "llog: new record vs reader race"
9066
9067 test_60j() {
9068         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9069                 skip "need MDS version at least 2.15.50"
9070         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9071         remote_mds_nodsh && skip "remote MDS with nodsh"
9072         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9073
9074         changelog_users $SINGLEMDS | grep "^cl" &&
9075                 skip "active changelog user"
9076
9077         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9078
9079         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9080                 skip_env "missing llog_reader"
9081
9082         mkdir_on_mdt0 $DIR/$tdir
9083
9084         local f=$DIR/$tdir/$tfile
9085         local mdt_dev
9086         local tmpfile
9087         local plain
9088
9089         changelog_register || error "cannot register changelog user"
9090
9091         # set changelog_mask to ALL
9092         changelog_chmask "ALL"
9093         changelog_clear
9094
9095         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9096         unlinkmany ${f}- 100 || error "unlinkmany failed"
9097
9098         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9099         mdt_dev=$(facet_device $SINGLEMDS)
9100
9101         do_facet $SINGLEMDS sync
9102         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9103                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9104                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9105
9106         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9107
9108         # if $tmpfile is not on EXT3 filesystem for some reason
9109         [[ ${plain:0:1} == 'O' ]] ||
9110                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9111
9112         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9113                 $mdt_dev; stat -c %s $tmpfile")
9114         echo "Truncate llog from $size to $((size - size % 8192))"
9115         size=$((size - size % 8192))
9116         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9117         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9118                 grep -c 'in bitmap only')
9119         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9120
9121         size=$((size - 9000))
9122         echo "Corrupt llog in the middle at $size"
9123         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9124                 count=333 conv=notrunc
9125         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9126                 grep -c 'next chunk')
9127         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9128 }
9129 run_test 60j "llog_reader reports corruptions"
9130
9131 test_61a() {
9132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9133
9134         f="$DIR/f61"
9135         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9136         cancel_lru_locks osc
9137         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9138         sync
9139 }
9140 run_test 61a "mmap() writes don't make sync hang ================"
9141
9142 test_61b() {
9143         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9144 }
9145 run_test 61b "mmap() of unstriped file is successful"
9146
9147 # bug 2330 - insufficient obd_match error checking causes LBUG
9148 test_62() {
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150
9151         f="$DIR/f62"
9152         echo foo > $f
9153         cancel_lru_locks osc
9154         lctl set_param fail_loc=0x405
9155         cat $f && error "cat succeeded, expect -EIO"
9156         lctl set_param fail_loc=0
9157 }
9158 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9159 # match every page all of the time.
9160 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9161
9162 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9163 # Though this test is irrelevant anymore, it helped to reveal some
9164 # other grant bugs (LU-4482), let's keep it.
9165 test_63a() {   # was test_63
9166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9167
9168         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9169
9170         for i in `seq 10` ; do
9171                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9172                 sleep 5
9173                 kill $!
9174                 sleep 1
9175         done
9176
9177         rm -f $DIR/f63 || true
9178 }
9179 run_test 63a "Verify oig_wait interruption does not crash ======="
9180
9181 # bug 2248 - async write errors didn't return to application on sync
9182 # bug 3677 - async write errors left page locked
9183 test_63b() {
9184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9185
9186         debugsave
9187         lctl set_param debug=-1
9188
9189         # ensure we have a grant to do async writes
9190         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9191         rm $DIR/$tfile
9192
9193         sync    # sync lest earlier test intercept the fail_loc
9194
9195         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9196         lctl set_param fail_loc=0x80000406
9197         $MULTIOP $DIR/$tfile Owy && \
9198                 error "sync didn't return ENOMEM"
9199         sync; sleep 2; sync     # do a real sync this time to flush page
9200         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9201                 error "locked page left in cache after async error" || true
9202         debugrestore
9203 }
9204 run_test 63b "async write errors should be returned to fsync ==="
9205
9206 test_64a () {
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208
9209         lfs df $DIR
9210         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9211 }
9212 run_test 64a "verify filter grant calculations (in kernel) ====="
9213
9214 test_64b () {
9215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9216
9217         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9218 }
9219 run_test 64b "check out-of-space detection on client"
9220
9221 test_64c() {
9222         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9223 }
9224 run_test 64c "verify grant shrink"
9225
9226 import_param() {
9227         local tgt=$1
9228         local param=$2
9229
9230         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9231 }
9232
9233 # this does exactly what osc_request.c:osc_announce_cached() does in
9234 # order to calculate max amount of grants to ask from server
9235 want_grant() {
9236         local tgt=$1
9237
9238         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9239         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9240
9241         ((rpc_in_flight++));
9242         nrpages=$((nrpages * rpc_in_flight))
9243
9244         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9245
9246         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9247
9248         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9249         local undirty=$((nrpages * PAGE_SIZE))
9250
9251         local max_extent_pages
9252         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9253         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9254         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9255         local grant_extent_tax
9256         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9257
9258         undirty=$((undirty + nrextents * grant_extent_tax))
9259
9260         echo $undirty
9261 }
9262
9263 # this is size of unit for grant allocation. It should be equal to
9264 # what tgt_grant.c:tgt_grant_chunk() calculates
9265 grant_chunk() {
9266         local tgt=$1
9267         local max_brw_size
9268         local grant_extent_tax
9269
9270         max_brw_size=$(import_param $tgt max_brw_size)
9271
9272         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9273
9274         echo $(((max_brw_size + grant_extent_tax) * 2))
9275 }
9276
9277 test_64d() {
9278         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9279                 skip "OST < 2.10.55 doesn't limit grants enough"
9280
9281         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9282
9283         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9284                 skip "no grant_param connect flag"
9285
9286         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9287
9288         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9289         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9290
9291
9292         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9293         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9294
9295         $LFS setstripe $DIR/$tfile -i 0 -c 1
9296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9297         ddpid=$!
9298
9299         while kill -0 $ddpid; do
9300                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9301
9302                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9303                         kill $ddpid
9304                         error "cur_grant $cur_grant > $max_cur_granted"
9305                 fi
9306
9307                 sleep 1
9308         done
9309 }
9310 run_test 64d "check grant limit exceed"
9311
9312 check_grants() {
9313         local tgt=$1
9314         local expected=$2
9315         local msg=$3
9316         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9317
9318         ((cur_grants == expected)) ||
9319                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9320 }
9321
9322 round_up_p2() {
9323         echo $((($1 + $2 - 1) & ~($2 - 1)))
9324 }
9325
9326 test_64e() {
9327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9328         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9329                 skip "Need OSS version at least 2.11.56"
9330
9331         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9332         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9333         $LCTL set_param debug=+cache
9334
9335         # Remount client to reset grant
9336         remount_client $MOUNT || error "failed to remount client"
9337         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9338
9339         local init_grants=$(import_param $osc_tgt initial_grant)
9340
9341         check_grants $osc_tgt $init_grants "init grants"
9342
9343         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9344         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9345         local gbs=$(import_param $osc_tgt grant_block_size)
9346
9347         # write random number of bytes from max_brw_size / 4 to max_brw_size
9348         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9349         # align for direct io
9350         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9351         # round to grant consumption unit
9352         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9353
9354         local grants=$((wb_round_up + extent_tax))
9355
9356         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9357
9358         # define OBD_FAIL_TGT_NO_GRANT 0x725
9359         # make the server not grant more back
9360         do_facet ost1 $LCTL set_param fail_loc=0x725
9361         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9362
9363         do_facet ost1 $LCTL set_param fail_loc=0
9364
9365         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9366
9367         rm -f $DIR/$tfile || error "rm failed"
9368
9369         # Remount client to reset grant
9370         remount_client $MOUNT || error "failed to remount client"
9371         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9372
9373         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9374
9375         # define OBD_FAIL_TGT_NO_GRANT 0x725
9376         # make the server not grant more back
9377         do_facet ost1 $LCTL set_param fail_loc=0x725
9378         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9379         do_facet ost1 $LCTL set_param fail_loc=0
9380
9381         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9382 }
9383 run_test 64e "check grant consumption (no grant allocation)"
9384
9385 test_64f() {
9386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9387
9388         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9389         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9390         $LCTL set_param debug=+cache
9391
9392         # Remount client to reset grant
9393         remount_client $MOUNT || error "failed to remount client"
9394         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9395
9396         local init_grants=$(import_param $osc_tgt initial_grant)
9397         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9398         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9399         local gbs=$(import_param $osc_tgt grant_block_size)
9400         local chunk=$(grant_chunk $osc_tgt)
9401
9402         # write random number of bytes from max_brw_size / 4 to max_brw_size
9403         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9404         # align for direct io
9405         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9406         # round to grant consumption unit
9407         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9408
9409         local grants=$((wb_round_up + extent_tax))
9410
9411         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9412         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9413                 error "error writing to $DIR/$tfile"
9414
9415         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9416                 "direct io with grant allocation"
9417
9418         rm -f $DIR/$tfile || error "rm failed"
9419
9420         # Remount client to reset grant
9421         remount_client $MOUNT || error "failed to remount client"
9422         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9423
9424         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9425
9426         local cmd="oO_WRONLY:w${write_bytes}_yc"
9427
9428         $MULTIOP $DIR/$tfile $cmd &
9429         MULTIPID=$!
9430         sleep 1
9431
9432         check_grants $osc_tgt $((init_grants - grants)) \
9433                 "buffered io, not write rpc"
9434
9435         kill -USR1 $MULTIPID
9436         wait
9437
9438         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9439                 "buffered io, one RPC"
9440 }
9441 run_test 64f "check grant consumption (with grant allocation)"
9442
9443 test_64g() {
9444         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9445                 skip "Need MDS version at least 2.14.56"
9446
9447         local mdts=$(comma_list $(mdts_nodes))
9448
9449         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9450                         tr '\n' ' ')
9451         stack_trap "$LCTL set_param $old"
9452
9453         # generate dirty pages and increase dirty granted on MDT
9454         stack_trap "rm -f $DIR/$tfile-*"
9455         for (( i = 0; i < 10; i++)); do
9456                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9457                         error "can't set stripe"
9458                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9459                         error "can't dd"
9460                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9461                         $LFS getstripe $DIR/$tfile-$i
9462                         error "not DoM file"
9463                 }
9464         done
9465
9466         # flush dirty pages
9467         sync
9468
9469         # wait until grant shrink reset grant dirty on MDTs
9470         for ((i = 0; i < 120; i++)); do
9471                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9472                         awk '{sum=sum+$1} END {print sum}')
9473                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9474                 echo "$grant_dirty grants, $vm_dirty pages"
9475                 (( grant_dirty + vm_dirty == 0 )) && break
9476                 (( i == 3 )) && sync &&
9477                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9478                 sleep 1
9479         done
9480
9481         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9482                 awk '{sum=sum+$1} END {print sum}')
9483         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9484 }
9485 run_test 64g "grant shrink on MDT"
9486
9487 test_64h() {
9488         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9489                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9490
9491         local instance=$($LFS getname -i $DIR)
9492         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9493         local num_exps=$(do_facet ost1 \
9494             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9495         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9496         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9498
9499         # 10MiB is for file to be written, max_brw_size * 16 *
9500         # num_exps is space reserve so that tgt_grant_shrink() decided
9501         # to not shrink
9502         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9503         (( avail * 1024 < expect )) &&
9504                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9505
9506         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9507         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9508         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9509         $LCTL set_param osc.*OST0000*.grant_shrink=1
9510         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9511
9512         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9513         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9514
9515         # drop cache so that coming read would do rpc
9516         cancel_lru_locks osc
9517
9518         # shrink interval is set to 10, pause for 7 seconds so that
9519         # grant thread did not wake up yet but coming read entered
9520         # shrink mode for rpc (osc_should_shrink_grant())
9521         sleep 7
9522
9523         declare -a cur_grant_bytes
9524         declare -a tot_granted
9525         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9526         tot_granted[0]=$(do_facet ost1 \
9527             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9528
9529         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9530
9531         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9532         tot_granted[1]=$(do_facet ost1 \
9533             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9534
9535         # grant change should be equal on both sides
9536         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9537                 tot_granted[0] - tot_granted[1])) ||
9538                 error "grant change mismatch, "                                \
9539                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9540                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9541 }
9542 run_test 64h "grant shrink on read"
9543
9544 test_64i() {
9545         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9546                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9547
9548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9549         remote_ost_nodsh && skip "remote OSTs with nodsh"
9550
9551         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9552
9553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9554
9555         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9556         local instance=$($LFS getname -i $DIR)
9557
9558         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9559         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9560
9561         # shrink grants and simulate rpc loss
9562         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9563         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9564         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9565
9566         fail ost1
9567
9568         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9569
9570         local testid=$(echo $TESTNAME | tr '_' ' ')
9571
9572         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9573                 grep "GRANT, real grant" &&
9574                 error "client has more grants then it owns" || true
9575 }
9576 run_test 64i "shrink on reconnect"
9577
9578 # bug 1414 - set/get directories' stripe info
9579 test_65a() {
9580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9581
9582         test_mkdir $DIR/$tdir
9583         touch $DIR/$tdir/f1
9584         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9585 }
9586 run_test 65a "directory with no stripe info"
9587
9588 test_65b() {
9589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9590
9591         test_mkdir $DIR/$tdir
9592         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9593
9594         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9595                                                 error "setstripe"
9596         touch $DIR/$tdir/f2
9597         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9598 }
9599 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9600
9601 test_65c() {
9602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9603         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9604
9605         test_mkdir $DIR/$tdir
9606         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9607
9608         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9609                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9610         touch $DIR/$tdir/f3
9611         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9612 }
9613 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9614
9615 test_65d() {
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617
9618         test_mkdir $DIR/$tdir
9619         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9620         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9621
9622         if [[ $STRIPECOUNT -le 0 ]]; then
9623                 sc=1
9624         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9625                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9626                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9627         else
9628                 sc=$(($STRIPECOUNT - 1))
9629         fi
9630         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9631         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9632         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9633                 error "lverify failed"
9634 }
9635 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9636
9637 test_65e() {
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639
9640         test_mkdir $DIR/$tdir
9641
9642         $LFS setstripe $DIR/$tdir || error "setstripe"
9643         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9644                                         error "no stripe info failed"
9645         touch $DIR/$tdir/f6
9646         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9647 }
9648 run_test 65e "directory setstripe defaults"
9649
9650 test_65f() {
9651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9652
9653         test_mkdir $DIR/${tdir}f
9654         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9655                 error "setstripe succeeded" || true
9656 }
9657 run_test 65f "dir setstripe permission (should return error) ==="
9658
9659 test_65g() {
9660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9661
9662         test_mkdir $DIR/$tdir
9663         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9664
9665         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9666                 error "setstripe -S failed"
9667         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9668         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9669                 error "delete default stripe failed"
9670 }
9671 run_test 65g "directory setstripe -d"
9672
9673 test_65h() {
9674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9675
9676         test_mkdir $DIR/$tdir
9677         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9678
9679         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9680                 error "setstripe -S failed"
9681         test_mkdir $DIR/$tdir/dd1
9682         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9683                 error "stripe info inherit failed"
9684 }
9685 run_test 65h "directory stripe info inherit ===================="
9686
9687 test_65i() {
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689
9690         save_layout_restore_at_exit $MOUNT
9691
9692         # bug6367: set non-default striping on root directory
9693         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9694
9695         # bug12836: getstripe on -1 default directory striping
9696         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9697
9698         # bug12836: getstripe -v on -1 default directory striping
9699         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9700
9701         # bug12836: new find on -1 default directory striping
9702         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9703 }
9704 run_test 65i "various tests to set root directory striping"
9705
9706 test_65j() { # bug6367
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708
9709         sync; sleep 1
9710
9711         # if we aren't already remounting for each test, do so for this test
9712         if [ "$I_MOUNTED" = "yes" ]; then
9713                 cleanup || error "failed to unmount"
9714                 setup
9715         fi
9716
9717         save_layout_restore_at_exit $MOUNT
9718
9719         $LFS setstripe -d $MOUNT || error "setstripe failed"
9720 }
9721 run_test 65j "set default striping on root directory (bug 6367)="
9722
9723 cleanup_65k() {
9724         rm -rf $DIR/$tdir
9725         wait_delete_completed
9726         do_facet $SINGLEMDS "lctl set_param -n \
9727                 osp.$ost*MDT0000.max_create_count=$max_count"
9728         do_facet $SINGLEMDS "lctl set_param -n \
9729                 osp.$ost*MDT0000.create_count=$count"
9730         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9731         echo $INACTIVE_OSC "is Activate"
9732
9733         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9734 }
9735
9736 test_65k() { # bug11679
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9739         remote_mds_nodsh && skip "remote MDS with nodsh"
9740
9741         local disable_precreate=true
9742         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9743                 disable_precreate=false
9744
9745         echo "Check OST status: "
9746         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9747                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9748
9749         for OSC in $MDS_OSCS; do
9750                 echo $OSC "is active"
9751                 do_facet $SINGLEMDS lctl --device %$OSC activate
9752         done
9753
9754         for INACTIVE_OSC in $MDS_OSCS; do
9755                 local ost=$(osc_to_ost $INACTIVE_OSC)
9756                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9757                                lov.*md*.target_obd |
9758                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9759
9760                 mkdir -p $DIR/$tdir
9761                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9762                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9763
9764                 echo "Deactivate: " $INACTIVE_OSC
9765                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9766
9767                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9768                               osp.$ost*MDT0000.create_count")
9769                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9770                                   osp.$ost*MDT0000.max_create_count")
9771                 $disable_precreate &&
9772                         do_facet $SINGLEMDS "lctl set_param -n \
9773                                 osp.$ost*MDT0000.max_create_count=0"
9774
9775                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9776                         [ -f $DIR/$tdir/$idx ] && continue
9777                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9778                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9779                                 { cleanup_65k;
9780                                   error "setstripe $idx should succeed"; }
9781                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9782                 done
9783                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9784                 rmdir $DIR/$tdir
9785
9786                 do_facet $SINGLEMDS "lctl set_param -n \
9787                         osp.$ost*MDT0000.max_create_count=$max_count"
9788                 do_facet $SINGLEMDS "lctl set_param -n \
9789                         osp.$ost*MDT0000.create_count=$count"
9790                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9791                 echo $INACTIVE_OSC "is Activate"
9792
9793                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9794         done
9795 }
9796 run_test 65k "validate manual striping works properly with deactivated OSCs"
9797
9798 test_65l() { # bug 12836
9799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9800
9801         test_mkdir -p $DIR/$tdir/test_dir
9802         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9803         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9804 }
9805 run_test 65l "lfs find on -1 stripe dir ========================"
9806
9807 test_65m() {
9808         local layout=$(save_layout $MOUNT)
9809         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9810                 restore_layout $MOUNT $layout
9811                 error "setstripe should fail by non-root users"
9812         }
9813         true
9814 }
9815 run_test 65m "normal user can't set filesystem default stripe"
9816
9817 test_65n() {
9818         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9819         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9820                 skip "Need MDS version at least 2.12.50"
9821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9822
9823         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9824         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9825         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9826
9827         save_layout_restore_at_exit $MOUNT
9828
9829         # new subdirectory under root directory should not inherit
9830         # the default layout from root
9831         local dir1=$MOUNT/$tdir-1
9832         mkdir $dir1 || error "mkdir $dir1 failed"
9833         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9834                 error "$dir1 shouldn't have LOV EA"
9835
9836         # delete the default layout on root directory
9837         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9838
9839         local dir2=$MOUNT/$tdir-2
9840         mkdir $dir2 || error "mkdir $dir2 failed"
9841         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9842                 error "$dir2 shouldn't have LOV EA"
9843
9844         # set a new striping pattern on root directory
9845         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9846         local new_def_stripe_size=$((def_stripe_size * 2))
9847         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9848                 error "set stripe size on $MOUNT failed"
9849
9850         # new file created in $dir2 should inherit the new stripe size from
9851         # the filesystem default
9852         local file2=$dir2/$tfile-2
9853         touch $file2 || error "touch $file2 failed"
9854
9855         local file2_stripe_size=$($LFS getstripe -S $file2)
9856         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9857         {
9858                 echo "file2_stripe_size: '$file2_stripe_size'"
9859                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9860                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9861         }
9862
9863         local dir3=$MOUNT/$tdir-3
9864         mkdir $dir3 || error "mkdir $dir3 failed"
9865         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9866         # the root layout, which is the actual default layout that will be used
9867         # when new files are created in $dir3.
9868         local dir3_layout=$(get_layout_param $dir3)
9869         local root_dir_layout=$(get_layout_param $MOUNT)
9870         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9871         {
9872                 echo "dir3_layout: '$dir3_layout'"
9873                 echo "root_dir_layout: '$root_dir_layout'"
9874                 error "$dir3 should show the default layout from $MOUNT"
9875         }
9876
9877         # set OST pool on root directory
9878         local pool=$TESTNAME
9879         pool_add $pool || error "add $pool failed"
9880         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9881                 error "add targets to $pool failed"
9882
9883         $LFS setstripe -p $pool $MOUNT ||
9884                 error "set OST pool on $MOUNT failed"
9885
9886         # new file created in $dir3 should inherit the pool from
9887         # the filesystem default
9888         local file3=$dir3/$tfile-3
9889         touch $file3 || error "touch $file3 failed"
9890
9891         local file3_pool=$($LFS getstripe -p $file3)
9892         [[ "$file3_pool" = "$pool" ]] ||
9893                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9894
9895         local dir4=$MOUNT/$tdir-4
9896         mkdir $dir4 || error "mkdir $dir4 failed"
9897         local dir4_layout=$(get_layout_param $dir4)
9898         root_dir_layout=$(get_layout_param $MOUNT)
9899         echo "$LFS getstripe -d $dir4"
9900         $LFS getstripe -d $dir4
9901         echo "$LFS getstripe -d $MOUNT"
9902         $LFS getstripe -d $MOUNT
9903         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9904         {
9905                 echo "dir4_layout: '$dir4_layout'"
9906                 echo "root_dir_layout: '$root_dir_layout'"
9907                 error "$dir4 should show the default layout from $MOUNT"
9908         }
9909
9910         # new file created in $dir4 should inherit the pool from
9911         # the filesystem default
9912         local file4=$dir4/$tfile-4
9913         touch $file4 || error "touch $file4 failed"
9914
9915         local file4_pool=$($LFS getstripe -p $file4)
9916         [[ "$file4_pool" = "$pool" ]] ||
9917                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9918
9919         # new subdirectory under non-root directory should inherit
9920         # the default layout from its parent directory
9921         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9922                 error "set directory layout on $dir4 failed"
9923
9924         local dir5=$dir4/$tdir-5
9925         mkdir $dir5 || error "mkdir $dir5 failed"
9926
9927         dir4_layout=$(get_layout_param $dir4)
9928         local dir5_layout=$(get_layout_param $dir5)
9929         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9930         {
9931                 echo "dir4_layout: '$dir4_layout'"
9932                 echo "dir5_layout: '$dir5_layout'"
9933                 error "$dir5 should inherit the default layout from $dir4"
9934         }
9935
9936         # though subdir under ROOT doesn't inherit default layout, but
9937         # its sub dir/file should be created with default layout.
9938         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9939         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9940                 skip "Need MDS version at least 2.12.59"
9941
9942         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9943         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9944         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9945
9946         if [ $default_lmv_hash == "none" ]; then
9947                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9948         else
9949                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9950                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9951         fi
9952
9953         $LFS setdirstripe -D -c 2 $MOUNT ||
9954                 error "setdirstripe -D -c 2 failed"
9955         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9956         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9957         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9958
9959         # $dir4 layout includes pool
9960         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9961         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9962                 error "pool lost on setstripe"
9963         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9964         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9965                 error "pool lost on compound layout setstripe"
9966 }
9967 run_test 65n "don't inherit default layout from root for new subdirectories"
9968
9969 test_65o() {
9970         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9971                 skip "need MDS version at least 2.14.57"
9972
9973         # set OST pool on root directory
9974         local pool=$TESTNAME
9975
9976         pool_add $pool || error "add $pool failed"
9977         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9978                 error "add targets to $pool failed"
9979
9980         local dir1=$MOUNT/$tdir
9981
9982         mkdir $dir1 || error "mkdir $dir1 failed"
9983
9984         # set a new striping pattern on root directory
9985         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9986
9987         $LFS setstripe -p $pool $dir1 ||
9988                 error "set directory layout on $dir1 failed"
9989
9990         # $dir1 layout includes pool
9991         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9992         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9993                 error "pool lost on setstripe"
9994         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9995         $LFS getstripe $dir1
9996         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9997                 error "pool lost on compound layout setstripe"
9998
9999         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10000                 error "setdirstripe failed on sub-dir with inherited pool"
10001         $LFS getstripe $dir1/dir2
10002         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10003                 error "pool lost on compound layout setdirstripe"
10004
10005         $LFS setstripe -E -1 -c 1 $dir1
10006         $LFS getstripe -d $dir1
10007         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10008                 error "pool lost on setstripe"
10009 }
10010 run_test 65o "pool inheritance for mdt component"
10011
10012 test_65p () { # LU-16152
10013         local src_dir=$DIR/$tdir/src_dir
10014         local dst_dir=$DIR/$tdir/dst_dir
10015         local yaml_file=$DIR/$tdir/layout.yaml
10016         local border
10017
10018         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10019                 skip "Need at least version 2.15.51"
10020
10021         test_mkdir -p $src_dir
10022         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10023                 error "failed to setstripe"
10024         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10025                 error "failed to getstripe"
10026
10027         test_mkdir -p $dst_dir
10028         $LFS setstripe --yaml $yaml_file $dst_dir ||
10029                 error "failed to setstripe with yaml file"
10030         border=$($LFS getstripe -d $dst_dir |
10031                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10032                 error "failed to getstripe"
10033
10034         # 2048M is 0x80000000, or 2147483648
10035         (( $border == 2147483648 )) ||
10036                 error "failed to handle huge number in yaml layout"
10037 }
10038 run_test 65p "setstripe with yaml file and huge number"
10039
10040 # bug 2543 - update blocks count on client
10041 test_66() {
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         local COUNT=${COUNT:-8}
10045         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10046         sync; sync_all_data; sync; sync_all_data
10047         cancel_lru_locks osc
10048         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10049         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10050 }
10051 run_test 66 "update inode blocks count on client ==============="
10052
10053 meminfo() {
10054         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10055 }
10056
10057 swap_used() {
10058         swapon -s | awk '($1 == "'$1'") { print $4 }'
10059 }
10060
10061 # bug5265, obdfilter oa2dentry return -ENOENT
10062 # #define OBD_FAIL_SRV_ENOENT 0x217
10063 test_69() {
10064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10065         remote_ost_nodsh && skip "remote OST with nodsh"
10066
10067         f="$DIR/$tfile"
10068         $LFS setstripe -c 1 -i 0 $f
10069
10070         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10071
10072         do_facet ost1 lctl set_param fail_loc=0x217
10073         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10074         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10075
10076         do_facet ost1 lctl set_param fail_loc=0
10077         $DIRECTIO write $f 0 2 || error "write error"
10078
10079         cancel_lru_locks osc
10080         $DIRECTIO read $f 0 1 || error "read error"
10081
10082         do_facet ost1 lctl set_param fail_loc=0x217
10083         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10084
10085         do_facet ost1 lctl set_param fail_loc=0
10086         rm -f $f
10087 }
10088 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10089
10090 test_71() {
10091         test_mkdir $DIR/$tdir
10092         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10093         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10094 }
10095 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10096
10097 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10099         [ "$RUNAS_ID" = "$UID" ] &&
10100                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10101         # Check that testing environment is properly set up. Skip if not
10102         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10103                 skip_env "User $RUNAS_ID does not exist - skipping"
10104
10105         touch $DIR/$tfile
10106         chmod 777 $DIR/$tfile
10107         chmod ug+s $DIR/$tfile
10108         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10109                 error "$RUNAS dd $DIR/$tfile failed"
10110         # See if we are still setuid/sgid
10111         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10112                 error "S/gid is not dropped on write"
10113         # Now test that MDS is updated too
10114         cancel_lru_locks mdc
10115         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10116                 error "S/gid is not dropped on MDS"
10117         rm -f $DIR/$tfile
10118 }
10119 run_test 72a "Test that remove suid works properly (bug5695) ===="
10120
10121 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10122         local perm
10123
10124         [ "$RUNAS_ID" = "$UID" ] &&
10125                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10126         [ "$RUNAS_ID" -eq 0 ] &&
10127                 skip_env "RUNAS_ID = 0 -- skipping"
10128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10129         # Check that testing environment is properly set up. Skip if not
10130         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10131                 skip_env "User $RUNAS_ID does not exist - skipping"
10132
10133         touch $DIR/${tfile}-f{g,u}
10134         test_mkdir $DIR/${tfile}-dg
10135         test_mkdir $DIR/${tfile}-du
10136         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10137         chmod g+s $DIR/${tfile}-{f,d}g
10138         chmod u+s $DIR/${tfile}-{f,d}u
10139         for perm in 777 2777 4777; do
10140                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10141                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10142                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10143                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10144         done
10145         true
10146 }
10147 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10148
10149 # bug 3462 - multiple simultaneous MDC requests
10150 test_73() {
10151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10152
10153         test_mkdir $DIR/d73-1
10154         test_mkdir $DIR/d73-2
10155         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10156         pid1=$!
10157
10158         lctl set_param fail_loc=0x80000129
10159         $MULTIOP $DIR/d73-1/f73-2 Oc &
10160         sleep 1
10161         lctl set_param fail_loc=0
10162
10163         $MULTIOP $DIR/d73-2/f73-3 Oc &
10164         pid3=$!
10165
10166         kill -USR1 $pid1
10167         wait $pid1 || return 1
10168
10169         sleep 25
10170
10171         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10172         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10173         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10174
10175         rm -rf $DIR/d73-*
10176 }
10177 run_test 73 "multiple MDC requests (should not deadlock)"
10178
10179 test_74a() { # bug 6149, 6184
10180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10181
10182         touch $DIR/f74a
10183         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10184         #
10185         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10186         # will spin in a tight reconnection loop
10187         $LCTL set_param fail_loc=0x8000030e
10188         # get any lock that won't be difficult - lookup works.
10189         ls $DIR/f74a
10190         $LCTL set_param fail_loc=0
10191         rm -f $DIR/f74a
10192         true
10193 }
10194 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10195
10196 test_74b() { # bug 13310
10197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10198
10199         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10200         #
10201         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10202         # will spin in a tight reconnection loop
10203         $LCTL set_param fail_loc=0x8000030e
10204         # get a "difficult" lock
10205         touch $DIR/f74b
10206         $LCTL set_param fail_loc=0
10207         rm -f $DIR/f74b
10208         true
10209 }
10210 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10211
10212 test_74c() {
10213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10214
10215         #define OBD_FAIL_LDLM_NEW_LOCK
10216         $LCTL set_param fail_loc=0x319
10217         touch $DIR/$tfile && error "touch successful"
10218         $LCTL set_param fail_loc=0
10219         true
10220 }
10221 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10222
10223 slab_lic=/sys/kernel/slab/lustre_inode_cache
10224 num_objects() {
10225         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10226         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10227                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10228 }
10229
10230 test_76a() { # Now for b=20433, added originally in b=1443
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232
10233         cancel_lru_locks osc
10234         # there may be some slab objects cached per core
10235         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10236         local before=$(num_objects)
10237         local count=$((512 * cpus))
10238         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10239         local margin=$((count / 10))
10240         if [[ -f $slab_lic/aliases ]]; then
10241                 local aliases=$(cat $slab_lic/aliases)
10242                 (( aliases > 0 )) && margin=$((margin * aliases))
10243         fi
10244
10245         echo "before slab objects: $before"
10246         for i in $(seq $count); do
10247                 touch $DIR/$tfile
10248                 rm -f $DIR/$tfile
10249         done
10250         cancel_lru_locks osc
10251         local after=$(num_objects)
10252         echo "created: $count, after slab objects: $after"
10253         # shared slab counts are not very accurate, allow significant margin
10254         # the main goal is that the cache growth is not permanently > $count
10255         while (( after > before + margin )); do
10256                 sleep 1
10257                 after=$(num_objects)
10258                 wait=$((wait + 1))
10259                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10260                 if (( wait > 60 )); then
10261                         error "inode slab grew from $before+$margin to $after"
10262                 fi
10263         done
10264 }
10265 run_test 76a "confirm clients recycle inodes properly ===="
10266
10267 test_76b() {
10268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10269         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10270
10271         local count=512
10272         local before=$(num_objects)
10273
10274         for i in $(seq $count); do
10275                 mkdir $DIR/$tdir
10276                 rmdir $DIR/$tdir
10277         done
10278
10279         local after=$(num_objects)
10280         local wait=0
10281
10282         while (( after > before )); do
10283                 sleep 1
10284                 after=$(num_objects)
10285                 wait=$((wait + 1))
10286                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10287                 if (( wait > 60 )); then
10288                         error "inode slab grew from $before to $after"
10289                 fi
10290         done
10291
10292         echo "slab objects before: $before, after: $after"
10293 }
10294 run_test 76b "confirm clients recycle directory inodes properly ===="
10295
10296 export ORIG_CSUM=""
10297 set_checksums()
10298 {
10299         # Note: in sptlrpc modes which enable its own bulk checksum, the
10300         # original crc32_le bulk checksum will be automatically disabled,
10301         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10302         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10303         # In this case set_checksums() will not be no-op, because sptlrpc
10304         # bulk checksum will be enabled all through the test.
10305
10306         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10307         lctl set_param -n osc.*.checksums $1
10308         return 0
10309 }
10310
10311 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10312                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10313 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10314                              tr -d [] | head -n1)}
10315 set_checksum_type()
10316 {
10317         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10318         rc=$?
10319         log "set checksum type to $1, rc = $rc"
10320         return $rc
10321 }
10322
10323 get_osc_checksum_type()
10324 {
10325         # arugment 1: OST name, like OST0000
10326         ost=$1
10327         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10328                         sed 's/.*\[\(.*\)\].*/\1/g')
10329         rc=$?
10330         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10331         echo $checksum_type
10332 }
10333
10334 F77_TMP=$TMP/f77-temp
10335 F77SZ=8
10336 setup_f77() {
10337         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10338                 error "error writing to $F77_TMP"
10339 }
10340
10341 test_77a() { # bug 10889
10342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10343         $GSS && skip_env "could not run with gss"
10344
10345         [ ! -f $F77_TMP ] && setup_f77
10346         set_checksums 1
10347         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10348         set_checksums 0
10349         rm -f $DIR/$tfile
10350 }
10351 run_test 77a "normal checksum read/write operation"
10352
10353 test_77b() { # bug 10889
10354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10355         $GSS && skip_env "could not run with gss"
10356
10357         [ ! -f $F77_TMP ] && setup_f77
10358         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10359         $LCTL set_param fail_loc=0x80000409
10360         set_checksums 1
10361
10362         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10363                 error "dd error: $?"
10364         $LCTL set_param fail_loc=0
10365
10366         for algo in $CKSUM_TYPES; do
10367                 cancel_lru_locks osc
10368                 set_checksum_type $algo
10369                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10370                 $LCTL set_param fail_loc=0x80000408
10371                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10372                 $LCTL set_param fail_loc=0
10373         done
10374         set_checksums 0
10375         set_checksum_type $ORIG_CSUM_TYPE
10376         rm -f $DIR/$tfile
10377 }
10378 run_test 77b "checksum error on client write, read"
10379
10380 cleanup_77c() {
10381         trap 0
10382         set_checksums 0
10383         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10384         $check_ost &&
10385                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10386         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10387         $check_ost && [ -n "$ost_file_prefix" ] &&
10388                 do_facet ost1 rm -f ${ost_file_prefix}\*
10389 }
10390
10391 test_77c() {
10392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10393         $GSS && skip_env "could not run with gss"
10394         remote_ost_nodsh && skip "remote OST with nodsh"
10395
10396         local bad1
10397         local osc_file_prefix
10398         local osc_file
10399         local check_ost=false
10400         local ost_file_prefix
10401         local ost_file
10402         local orig_cksum
10403         local dump_cksum
10404         local fid
10405
10406         # ensure corruption will occur on first OSS/OST
10407         $LFS setstripe -i 0 $DIR/$tfile
10408
10409         [ ! -f $F77_TMP ] && setup_f77
10410         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10411                 error "dd write error: $?"
10412         fid=$($LFS path2fid $DIR/$tfile)
10413
10414         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10415         then
10416                 check_ost=true
10417                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10418                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10419         else
10420                 echo "OSS do not support bulk pages dump upon error"
10421         fi
10422
10423         osc_file_prefix=$($LCTL get_param -n debug_path)
10424         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10425
10426         trap cleanup_77c EXIT
10427
10428         set_checksums 1
10429         # enable bulk pages dump upon error on Client
10430         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10431         # enable bulk pages dump upon error on OSS
10432         $check_ost &&
10433                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10434
10435         # flush Client cache to allow next read to reach OSS
10436         cancel_lru_locks osc
10437
10438         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10439         $LCTL set_param fail_loc=0x80000408
10440         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10441         $LCTL set_param fail_loc=0
10442
10443         rm -f $DIR/$tfile
10444
10445         # check cksum dump on Client
10446         osc_file=$(ls ${osc_file_prefix}*)
10447         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10448         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10449         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10450         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10451         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10452                      cksum)
10453         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10454         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10455                 error "dump content does not match on Client"
10456
10457         $check_ost || skip "No need to check cksum dump on OSS"
10458
10459         # check cksum dump on OSS
10460         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10461         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10462         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10463         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10464         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10465                 error "dump content does not match on OSS"
10466
10467         cleanup_77c
10468 }
10469 run_test 77c "checksum error on client read with debug"
10470
10471 test_77d() { # bug 10889
10472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10473         $GSS && skip_env "could not run with gss"
10474
10475         stack_trap "rm -f $DIR/$tfile"
10476         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10477         $LCTL set_param fail_loc=0x80000409
10478         set_checksums 1
10479         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10480                 error "direct write: rc=$?"
10481         $LCTL set_param fail_loc=0
10482         set_checksums 0
10483
10484         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10485         $LCTL set_param fail_loc=0x80000408
10486         set_checksums 1
10487         cancel_lru_locks osc
10488         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10489                 error "direct read: rc=$?"
10490         $LCTL set_param fail_loc=0
10491         set_checksums 0
10492 }
10493 run_test 77d "checksum error on OST direct write, read"
10494
10495 test_77f() { # bug 10889
10496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10497         $GSS && skip_env "could not run with gss"
10498
10499         set_checksums 1
10500         stack_trap "rm -f $DIR/$tfile"
10501         for algo in $CKSUM_TYPES; do
10502                 cancel_lru_locks osc
10503                 set_checksum_type $algo
10504                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10505                 $LCTL set_param fail_loc=0x409
10506                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10507                         error "direct write succeeded"
10508                 $LCTL set_param fail_loc=0
10509         done
10510         set_checksum_type $ORIG_CSUM_TYPE
10511         set_checksums 0
10512 }
10513 run_test 77f "repeat checksum error on write (expect error)"
10514
10515 test_77g() { # bug 10889
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517         $GSS && skip_env "could not run with gss"
10518         remote_ost_nodsh && skip "remote OST with nodsh"
10519
10520         [ ! -f $F77_TMP ] && setup_f77
10521
10522         local file=$DIR/$tfile
10523         stack_trap "rm -f $file" EXIT
10524
10525         $LFS setstripe -c 1 -i 0 $file
10526         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10527         do_facet ost1 lctl set_param fail_loc=0x8000021a
10528         set_checksums 1
10529         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10530                 error "write error: rc=$?"
10531         do_facet ost1 lctl set_param fail_loc=0
10532         set_checksums 0
10533
10534         cancel_lru_locks osc
10535         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10536         do_facet ost1 lctl set_param fail_loc=0x8000021b
10537         set_checksums 1
10538         cmp $F77_TMP $file || error "file compare failed"
10539         do_facet ost1 lctl set_param fail_loc=0
10540         set_checksums 0
10541 }
10542 run_test 77g "checksum error on OST write, read"
10543
10544 test_77k() { # LU-10906
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546         $GSS && skip_env "could not run with gss"
10547
10548         local cksum_param="osc.$FSNAME*.checksums"
10549         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10550         local checksum
10551         local i
10552
10553         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10554         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10555         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10556
10557         for i in 0 1; do
10558                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10559                         error "failed to set checksum=$i on MGS"
10560                 wait_update $HOSTNAME "$get_checksum" $i
10561                 #remount
10562                 echo "remount client, checksum should be $i"
10563                 remount_client $MOUNT || error "failed to remount client"
10564                 checksum=$(eval $get_checksum)
10565                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10566         done
10567         # remove persistent param to avoid races with checksum mountopt below
10568         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10569                 error "failed to delete checksum on MGS"
10570
10571         for opt in "checksum" "nochecksum"; do
10572                 #remount with mount option
10573                 echo "remount client with option $opt, checksum should be $i"
10574                 umount_client $MOUNT || error "failed to umount client"
10575                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10576                         error "failed to mount client with option '$opt'"
10577                 checksum=$(eval $get_checksum)
10578                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10579                 i=$((i - 1))
10580         done
10581
10582         remount_client $MOUNT || error "failed to remount client"
10583 }
10584 run_test 77k "enable/disable checksum correctly"
10585
10586 test_77l() {
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588         $GSS && skip_env "could not run with gss"
10589
10590         set_checksums 1
10591         stack_trap "set_checksums $ORIG_CSUM" EXIT
10592         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10593
10594         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10595
10596         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10597         for algo in $CKSUM_TYPES; do
10598                 set_checksum_type $algo || error "fail to set checksum type $algo"
10599                 osc_algo=$(get_osc_checksum_type OST0000)
10600                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10601
10602                 # no locks, no reqs to let the connection idle
10603                 cancel_lru_locks osc
10604                 lru_resize_disable osc
10605                 wait_osc_import_state client ost1 IDLE
10606
10607                 # ensure ost1 is connected
10608                 stat $DIR/$tfile >/dev/null || error "can't stat"
10609                 wait_osc_import_state client ost1 FULL
10610
10611                 osc_algo=$(get_osc_checksum_type OST0000)
10612                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10613         done
10614         return 0
10615 }
10616 run_test 77l "preferred checksum type is remembered after reconnected"
10617
10618 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10619 rm -f $F77_TMP
10620 unset F77_TMP
10621
10622 test_77m() {
10623         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10624                 skip "Need at least version 2.14.52"
10625         local param=checksum_speed
10626
10627         $LCTL get_param $param || error "reading $param failed"
10628
10629         csum_speeds=$($LCTL get_param -n $param)
10630
10631         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10632                 error "known checksum types are missing"
10633 }
10634 run_test 77m "Verify checksum_speed is correctly read"
10635
10636 check_filefrag_77n() {
10637         local nr_ext=0
10638         local starts=()
10639         local ends=()
10640
10641         while read extidx a b start end rest; do
10642                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10643                         nr_ext=$(( $nr_ext + 1 ))
10644                         starts+=( ${start%..} )
10645                         ends+=( ${end%:} )
10646                 fi
10647         done < <( filefrag -sv $1 )
10648
10649         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10650         return 1
10651 }
10652
10653 test_77n() {
10654         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10655
10656         touch $DIR/$tfile
10657         $TRUNCATE $DIR/$tfile 0
10658         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10659         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10660         check_filefrag_77n $DIR/$tfile ||
10661                 skip "$tfile blocks not contiguous around hole"
10662
10663         set_checksums 1
10664         stack_trap "set_checksums $ORIG_CSUM" EXIT
10665         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10666         stack_trap "rm -f $DIR/$tfile"
10667
10668         for algo in $CKSUM_TYPES; do
10669                 if [[ "$algo" =~ ^t10 ]]; then
10670                         set_checksum_type $algo ||
10671                                 error "fail to set checksum type $algo"
10672                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10673                                 error "fail to read $tfile with $algo"
10674                 fi
10675         done
10676         rm -f $DIR/$tfile
10677         return 0
10678 }
10679 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10680
10681 test_77o() {
10682         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10683                 skip "Need MDS version at least 2.14.55"
10684         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10685                 skip "Need OST version at least 2.14.55"
10686         local ofd=obdfilter
10687         local mdt=mdt
10688
10689         # print OST checksum_type
10690         echo "$ofd.$FSNAME-*.checksum_type:"
10691         do_nodes $(comma_list $(osts_nodes)) \
10692                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10693
10694         # print MDT checksum_type
10695         echo "$mdt.$FSNAME-*.checksum_type:"
10696         do_nodes $(comma_list $(mdts_nodes)) \
10697                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10698
10699         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10700                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10701
10702         (( $o_count == $OSTCOUNT )) ||
10703                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10704
10705         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10706                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10707
10708         (( $m_count == $MDSCOUNT )) ||
10709                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10710 }
10711 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10712
10713 cleanup_test_78() {
10714         trap 0
10715         rm -f $DIR/$tfile
10716 }
10717
10718 test_78() { # bug 10901
10719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10720         remote_ost || skip_env "local OST"
10721
10722         NSEQ=5
10723         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10724         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10725         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10726         echo "MemTotal: $MEMTOTAL"
10727
10728         # reserve 256MB of memory for the kernel and other running processes,
10729         # and then take 1/2 of the remaining memory for the read/write buffers.
10730         if [ $MEMTOTAL -gt 512 ] ;then
10731                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10732         else
10733                 # for those poor memory-starved high-end clusters...
10734                 MEMTOTAL=$((MEMTOTAL / 2))
10735         fi
10736         echo "Mem to use for directio: $MEMTOTAL"
10737
10738         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10739         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10740         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10741         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10742                 head -n1)
10743         echo "Smallest OST: $SMALLESTOST"
10744         [[ $SMALLESTOST -lt 10240 ]] &&
10745                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10746
10747         trap cleanup_test_78 EXIT
10748
10749         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10750                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10751
10752         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10753         echo "File size: $F78SIZE"
10754         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10755         for i in $(seq 1 $NSEQ); do
10756                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10757                 echo directIO rdwr round $i of $NSEQ
10758                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10759         done
10760
10761         cleanup_test_78
10762 }
10763 run_test 78 "handle large O_DIRECT writes correctly ============"
10764
10765 test_79() { # bug 12743
10766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10767
10768         wait_delete_completed
10769
10770         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10771         BKFREE=$(calc_osc_kbytes kbytesfree)
10772         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10773
10774         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10775         DFTOTAL=`echo $STRING | cut -d, -f1`
10776         DFUSED=`echo $STRING  | cut -d, -f2`
10777         DFAVAIL=`echo $STRING | cut -d, -f3`
10778         DFFREE=$(($DFTOTAL - $DFUSED))
10779
10780         ALLOWANCE=$((64 * $OSTCOUNT))
10781
10782         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10783            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10784                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10785         fi
10786         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10787            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10788                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10789         fi
10790         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10791            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10792                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10793         fi
10794 }
10795 run_test 79 "df report consistency check ======================="
10796
10797 test_80() { # bug 10718
10798         remote_ost_nodsh && skip "remote OST with nodsh"
10799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10800
10801         # relax strong synchronous semantics for slow backends like ZFS
10802         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10803                 local soc="obdfilter.*.sync_lock_cancel"
10804                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10805
10806                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10807                 if [ -z "$save" ]; then
10808                         soc="obdfilter.*.sync_on_lock_cancel"
10809                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10810                 fi
10811
10812                 if [ "$save" != "never" ]; then
10813                         local hosts=$(comma_list $(osts_nodes))
10814
10815                         do_nodes $hosts $LCTL set_param $soc=never
10816                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10817                 fi
10818         fi
10819
10820         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10821         sync; sleep 1; sync
10822         local before=$(date +%s)
10823         cancel_lru_locks osc
10824         local after=$(date +%s)
10825         local diff=$((after - before))
10826         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10827
10828         rm -f $DIR/$tfile
10829 }
10830 run_test 80 "Page eviction is equally fast at high offsets too"
10831
10832 test_81a() { # LU-456
10833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10834         remote_ost_nodsh && skip "remote OST with nodsh"
10835
10836         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10837         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10838         do_facet ost1 lctl set_param fail_loc=0x80000228
10839
10840         # write should trigger a retry and success
10841         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10842         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10843         RC=$?
10844         if [ $RC -ne 0 ] ; then
10845                 error "write should success, but failed for $RC"
10846         fi
10847 }
10848 run_test 81a "OST should retry write when get -ENOSPC ==============="
10849
10850 test_81b() { # LU-456
10851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10852         remote_ost_nodsh && skip "remote OST with nodsh"
10853
10854         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10855         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10856         do_facet ost1 lctl set_param fail_loc=0x228
10857
10858         # write should retry several times and return -ENOSPC finally
10859         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10860         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10861         RC=$?
10862         ENOSPC=28
10863         if [ $RC -ne $ENOSPC ] ; then
10864                 error "dd should fail for -ENOSPC, but succeed."
10865         fi
10866 }
10867 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10868
10869 test_99() {
10870         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10871
10872         test_mkdir $DIR/$tdir.cvsroot
10873         chown $RUNAS_ID $DIR/$tdir.cvsroot
10874
10875         cd $TMP
10876         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10877
10878         cd /etc/init.d
10879         # some versions of cvs import exit(1) when asked to import links or
10880         # files they can't read.  ignore those files.
10881         local toignore=$(find . -type l -printf '-I %f\n' -o \
10882                          ! -perm /4 -printf '-I %f\n')
10883         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10884                 $tdir.reposname vtag rtag
10885
10886         cd $DIR
10887         test_mkdir $DIR/$tdir.reposname
10888         chown $RUNAS_ID $DIR/$tdir.reposname
10889         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10890
10891         cd $DIR/$tdir.reposname
10892         $RUNAS touch foo99
10893         $RUNAS cvs add -m 'addmsg' foo99
10894         $RUNAS cvs update
10895         $RUNAS cvs commit -m 'nomsg' foo99
10896         rm -fr $DIR/$tdir.cvsroot
10897 }
10898 run_test 99 "cvs strange file/directory operations"
10899
10900 test_100() {
10901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10902         [[ "$NETTYPE" =~ tcp ]] ||
10903                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10904         remote_ost_nodsh && skip "remote OST with nodsh"
10905         remote_mds_nodsh && skip "remote MDS with nodsh"
10906         remote_servers ||
10907                 skip "useless for local single node setup"
10908
10909         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10910                 [ "$PROT" != "tcp" ] && continue
10911                 RPORT=$(echo $REMOTE | cut -d: -f2)
10912                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10913
10914                 rc=0
10915                 LPORT=`echo $LOCAL | cut -d: -f2`
10916                 if [ $LPORT -ge 1024 ]; then
10917                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10918                         netstat -tna
10919                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10920                 fi
10921         done
10922         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10923 }
10924 run_test 100 "check local port using privileged port ==========="
10925
10926 function get_named_value()
10927 {
10928     local tag=$1
10929
10930     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10931 }
10932
10933 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10934                    awk '/^max_cached_mb/ { print $2 }')
10935
10936 cleanup_101a() {
10937         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10938         trap 0
10939 }
10940
10941 test_101a() {
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943
10944         local s
10945         local discard
10946         local nreads=10000
10947         local cache_limit=32
10948
10949         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10950         trap cleanup_101a EXIT
10951         $LCTL set_param -n llite.*.read_ahead_stats=0
10952         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10953
10954         #
10955         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10956         #
10957         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10958         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10959
10960         discard=0
10961         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10962                    get_named_value 'read.but.discarded'); do
10963                         discard=$(($discard + $s))
10964         done
10965         cleanup_101a
10966
10967         $LCTL get_param osc.*-osc*.rpc_stats
10968         $LCTL get_param llite.*.read_ahead_stats
10969
10970         # Discard is generally zero, but sometimes a few random reads line up
10971         # and trigger larger readahead, which is wasted & leads to discards.
10972         if [[ $(($discard)) -gt $nreads ]]; then
10973                 error "too many ($discard) discarded pages"
10974         fi
10975         rm -f $DIR/$tfile || true
10976 }
10977 run_test 101a "check read-ahead for random reads"
10978
10979 setup_test101bc() {
10980         test_mkdir $DIR/$tdir
10981         local ssize=$1
10982         local FILE_LENGTH=$2
10983         STRIPE_OFFSET=0
10984
10985         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10986
10987         local list=$(comma_list $(osts_nodes))
10988         set_osd_param $list '' read_cache_enable 0
10989         set_osd_param $list '' writethrough_cache_enable 0
10990
10991         trap cleanup_test101bc EXIT
10992         # prepare the read-ahead file
10993         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10994
10995         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10996                                 count=$FILE_SIZE_MB 2> /dev/null
10997
10998 }
10999
11000 cleanup_test101bc() {
11001         trap 0
11002         rm -rf $DIR/$tdir
11003         rm -f $DIR/$tfile
11004
11005         local list=$(comma_list $(osts_nodes))
11006         set_osd_param $list '' read_cache_enable 1
11007         set_osd_param $list '' writethrough_cache_enable 1
11008 }
11009
11010 calc_total() {
11011         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11012 }
11013
11014 ra_check_101() {
11015         local read_size=$1
11016         local stripe_size=$2
11017         local stride_length=$((stripe_size / read_size))
11018         local stride_width=$((stride_length * OSTCOUNT))
11019         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11020                                 (stride_width - stride_length) ))
11021         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11022                   get_named_value 'read.but.discarded' | calc_total)
11023
11024         if [[ $discard -gt $discard_limit ]]; then
11025                 $LCTL get_param llite.*.read_ahead_stats
11026                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11027         else
11028                 echo "Read-ahead success for size ${read_size}"
11029         fi
11030 }
11031
11032 test_101b() {
11033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11035
11036         local STRIPE_SIZE=1048576
11037         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11038
11039         if [ $SLOW == "yes" ]; then
11040                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11041         else
11042                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11043         fi
11044
11045         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11046
11047         # prepare the read-ahead file
11048         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11049         cancel_lru_locks osc
11050         for BIDX in 2 4 8 16 32 64 128 256
11051         do
11052                 local BSIZE=$((BIDX*4096))
11053                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11054                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11055                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11056                 $LCTL set_param -n llite.*.read_ahead_stats=0
11057                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11058                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11059                 cancel_lru_locks osc
11060                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11061         done
11062         cleanup_test101bc
11063         true
11064 }
11065 run_test 101b "check stride-io mode read-ahead ================="
11066
11067 test_101c() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069
11070         local STRIPE_SIZE=1048576
11071         local FILE_LENGTH=$((STRIPE_SIZE*100))
11072         local nreads=10000
11073         local rsize=65536
11074         local osc_rpc_stats
11075
11076         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11077
11078         cancel_lru_locks osc
11079         $LCTL set_param osc.*.rpc_stats=0
11080         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11081         $LCTL get_param osc.*.rpc_stats
11082         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11083                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11084                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11085                 local size
11086
11087                 if [ $lines -le 20 ]; then
11088                         echo "continue debug"
11089                         continue
11090                 fi
11091                 for size in 1 2 4 8; do
11092                         local rpc=$(echo "$stats" |
11093                                     awk '($1 == "'$size':") {print $2; exit; }')
11094                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11095                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11096                 done
11097                 echo "$osc_rpc_stats check passed!"
11098         done
11099         cleanup_test101bc
11100         true
11101 }
11102 run_test 101c "check stripe_size aligned read-ahead"
11103
11104 test_101d() {
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106
11107         local file=$DIR/$tfile
11108         local sz_MB=${FILESIZE_101d:-80}
11109         local ra_MB=${READAHEAD_MB:-40}
11110
11111         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11112         [ $free_MB -lt $sz_MB ] &&
11113                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11114
11115         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11116         $LFS setstripe -c -1 $file || error "setstripe failed"
11117
11118         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11119         echo Cancel LRU locks on lustre client to flush the client cache
11120         cancel_lru_locks osc
11121
11122         echo Disable read-ahead
11123         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11124         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11125         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11126         $LCTL get_param -n llite.*.max_read_ahead_mb
11127
11128         echo "Reading the test file $file with read-ahead disabled"
11129         local sz_KB=$((sz_MB * 1024 / 4))
11130         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11131         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11132         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11133                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11134
11135         echo "Cancel LRU locks on lustre client to flush the client cache"
11136         cancel_lru_locks osc
11137         echo Enable read-ahead with ${ra_MB}MB
11138         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11139
11140         echo "Reading the test file $file with read-ahead enabled"
11141         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11142                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11143
11144         echo "read-ahead disabled time read $raOFF"
11145         echo "read-ahead enabled time read $raON"
11146
11147         rm -f $file
11148         wait_delete_completed
11149
11150         # use awk for this check instead of bash because it handles decimals
11151         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11152                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11153 }
11154 run_test 101d "file read with and without read-ahead enabled"
11155
11156 test_101e() {
11157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11158
11159         local file=$DIR/$tfile
11160         local size_KB=500  #KB
11161         local count=100
11162         local bsize=1024
11163
11164         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11165         local need_KB=$((count * size_KB))
11166         [[ $free_KB -le $need_KB ]] &&
11167                 skip_env "Need free space $need_KB, have $free_KB"
11168
11169         echo "Creating $count ${size_KB}K test files"
11170         for ((i = 0; i < $count; i++)); do
11171                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11172         done
11173
11174         echo "Cancel LRU locks on lustre client to flush the client cache"
11175         cancel_lru_locks $OSC
11176
11177         echo "Reset readahead stats"
11178         $LCTL set_param -n llite.*.read_ahead_stats=0
11179
11180         for ((i = 0; i < $count; i++)); do
11181                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11182         done
11183
11184         $LCTL get_param llite.*.max_cached_mb
11185         $LCTL get_param llite.*.read_ahead_stats
11186         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11187                      get_named_value 'misses' | calc_total)
11188
11189         for ((i = 0; i < $count; i++)); do
11190                 rm -rf $file.$i 2>/dev/null
11191         done
11192
11193         #10000 means 20% reads are missing in readahead
11194         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11195 }
11196 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11197
11198 test_101f() {
11199         which iozone || skip_env "no iozone installed"
11200
11201         local old_debug=$($LCTL get_param debug)
11202         old_debug=${old_debug#*=}
11203         $LCTL set_param debug="reada mmap"
11204
11205         # create a test file
11206         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11207
11208         echo Cancel LRU locks on lustre client to flush the client cache
11209         cancel_lru_locks osc
11210
11211         echo Reset readahead stats
11212         $LCTL set_param -n llite.*.read_ahead_stats=0
11213
11214         echo mmap read the file with small block size
11215         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11216                 > /dev/null 2>&1
11217
11218         echo checking missing pages
11219         $LCTL get_param llite.*.read_ahead_stats
11220         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11221                         get_named_value 'misses' | calc_total)
11222
11223         $LCTL set_param debug="$old_debug"
11224         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11225         rm -f $DIR/$tfile
11226 }
11227 run_test 101f "check mmap read performance"
11228
11229 test_101g_brw_size_test() {
11230         local mb=$1
11231         local pages=$((mb * 1048576 / PAGE_SIZE))
11232         local file=$DIR/$tfile
11233
11234         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11235                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11236         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11237                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11238                         return 2
11239         done
11240
11241         stack_trap "rm -f $file" EXIT
11242         $LCTL set_param -n osc.*.rpc_stats=0
11243
11244         # 10 RPCs should be enough for the test
11245         local count=10
11246         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11247                 { error "dd write ${mb} MB blocks failed"; return 3; }
11248         cancel_lru_locks osc
11249         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11250                 { error "dd write ${mb} MB blocks failed"; return 4; }
11251
11252         # calculate number of full-sized read and write RPCs
11253         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11254                 sed -n '/pages per rpc/,/^$/p' |
11255                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11256                 END { print reads,writes }'))
11257         # allow one extra full-sized read RPC for async readahead
11258         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11259                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11260         [[ ${rpcs[1]} == $count ]] ||
11261                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11262 }
11263
11264 test_101g() {
11265         remote_ost_nodsh && skip "remote OST with nodsh"
11266
11267         local rpcs
11268         local osts=$(get_facets OST)
11269         local list=$(comma_list $(osts_nodes))
11270         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11271         local brw_size="obdfilter.*.brw_size"
11272
11273         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11274
11275         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11276
11277         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11278                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11279                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11280            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11281                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11282                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11283
11284                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11285                         suffix="M"
11286
11287                 if [[ $orig_mb -lt 16 ]]; then
11288                         save_lustre_params $osts "$brw_size" > $p
11289                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11290                                 error "set 16MB RPC size failed"
11291
11292                         echo "remount client to enable new RPC size"
11293                         remount_client $MOUNT || error "remount_client failed"
11294                 fi
11295
11296                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11297                 # should be able to set brw_size=12, but no rpc_stats for that
11298                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11299         fi
11300
11301         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11302
11303         if [[ $orig_mb -lt 16 ]]; then
11304                 restore_lustre_params < $p
11305                 remount_client $MOUNT || error "remount_client restore failed"
11306         fi
11307
11308         rm -f $p $DIR/$tfile
11309 }
11310 run_test 101g "Big bulk(4/16 MiB) readahead"
11311
11312 test_101h() {
11313         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11314
11315         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11316                 error "dd 70M file failed"
11317         echo Cancel LRU locks on lustre client to flush the client cache
11318         cancel_lru_locks osc
11319
11320         echo "Reset readahead stats"
11321         $LCTL set_param -n llite.*.read_ahead_stats 0
11322
11323         echo "Read 10M of data but cross 64M bundary"
11324         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11325         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11326                      get_named_value 'misses' | calc_total)
11327         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11328         rm -f $p $DIR/$tfile
11329 }
11330 run_test 101h "Readahead should cover current read window"
11331
11332 test_101i() {
11333         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11334                 error "dd 10M file failed"
11335
11336         local max_per_file_mb=$($LCTL get_param -n \
11337                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11338         cancel_lru_locks osc
11339         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11340         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11341                 error "set max_read_ahead_per_file_mb to 1 failed"
11342
11343         echo "Reset readahead stats"
11344         $LCTL set_param llite.*.read_ahead_stats=0
11345
11346         dd if=$DIR/$tfile of=/dev/null bs=2M
11347
11348         $LCTL get_param llite.*.read_ahead_stats
11349         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11350                      awk '/misses/ { print $2 }')
11351         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11352         rm -f $DIR/$tfile
11353 }
11354 run_test 101i "allow current readahead to exceed reservation"
11355
11356 test_101j() {
11357         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11358                 error "setstripe $DIR/$tfile failed"
11359         local file_size=$((1048576 * 16))
11360         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11361         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11362
11363         echo Disable read-ahead
11364         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11365
11366         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11367         for blk in $PAGE_SIZE 1048576 $file_size; do
11368                 cancel_lru_locks osc
11369                 echo "Reset readahead stats"
11370                 $LCTL set_param -n llite.*.read_ahead_stats=0
11371                 local count=$(($file_size / $blk))
11372                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11373                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11374                              get_named_value 'failed.to.fast.read' | calc_total)
11375                 $LCTL get_param -n llite.*.read_ahead_stats
11376                 [ $miss -eq $count ] || error "expected $count got $miss"
11377         done
11378
11379         rm -f $p $DIR/$tfile
11380 }
11381 run_test 101j "A complete read block should be submitted when no RA"
11382
11383 test_101k()
11384 {
11385         local file=$DIR/$tfile
11386
11387         check_set_fallocate_or_skip
11388
11389         $LCTL set_param -n llite.*.read_ahead_stats=0
11390         fallocate -l 16K $file || error "failed to fallocate $file"
11391         cancel_lru_locks osc
11392         $MULTIOP $file or1048576c
11393         $LCTL get_param llite.*.read_ahead_stats
11394 }
11395 run_test 101k "read ahead for small file"
11396
11397 setup_test102() {
11398         test_mkdir $DIR/$tdir
11399         chown $RUNAS_ID $DIR/$tdir
11400         STRIPE_SIZE=65536
11401         STRIPE_OFFSET=1
11402         STRIPE_COUNT=$OSTCOUNT
11403         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11404
11405         trap cleanup_test102 EXIT
11406         cd $DIR
11407         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11408         cd $DIR/$tdir
11409         for num in 1 2 3 4; do
11410                 for count in $(seq 1 $STRIPE_COUNT); do
11411                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11412                                 local size=`expr $STRIPE_SIZE \* $num`
11413                                 local file=file"$num-$idx-$count"
11414                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11415                         done
11416                 done
11417         done
11418
11419         cd $DIR
11420         $1 tar cf $TMP/f102.tar $tdir --xattrs
11421 }
11422
11423 cleanup_test102() {
11424         trap 0
11425         rm -f $TMP/f102.tar
11426         rm -rf $DIR/d0.sanity/d102
11427 }
11428
11429 test_102a() {
11430         [ "$UID" != 0 ] && skip "must run as root"
11431         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11432                 skip_env "must have user_xattr"
11433
11434         [ -z "$(which setfattr 2>/dev/null)" ] &&
11435                 skip_env "could not find setfattr"
11436
11437         local testfile=$DIR/$tfile
11438
11439         touch $testfile
11440         echo "set/get xattr..."
11441         setfattr -n trusted.name1 -v value1 $testfile ||
11442                 error "setfattr -n trusted.name1=value1 $testfile failed"
11443         getfattr -n trusted.name1 $testfile 2> /dev/null |
11444           grep "trusted.name1=.value1" ||
11445                 error "$testfile missing trusted.name1=value1"
11446
11447         setfattr -n user.author1 -v author1 $testfile ||
11448                 error "setfattr -n user.author1=author1 $testfile failed"
11449         getfattr -n user.author1 $testfile 2> /dev/null |
11450           grep "user.author1=.author1" ||
11451                 error "$testfile missing trusted.author1=author1"
11452
11453         echo "listxattr..."
11454         setfattr -n trusted.name2 -v value2 $testfile ||
11455                 error "$testfile unable to set trusted.name2"
11456         setfattr -n trusted.name3 -v value3 $testfile ||
11457                 error "$testfile unable to set trusted.name3"
11458         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11459             grep "trusted.name" | wc -l) -eq 3 ] ||
11460                 error "$testfile missing 3 trusted.name xattrs"
11461
11462         setfattr -n user.author2 -v author2 $testfile ||
11463                 error "$testfile unable to set user.author2"
11464         setfattr -n user.author3 -v author3 $testfile ||
11465                 error "$testfile unable to set user.author3"
11466         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11467             grep "user.author" | wc -l) -eq 3 ] ||
11468                 error "$testfile missing 3 user.author xattrs"
11469
11470         echo "remove xattr..."
11471         setfattr -x trusted.name1 $testfile ||
11472                 error "$testfile error deleting trusted.name1"
11473         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11474                 error "$testfile did not delete trusted.name1 xattr"
11475
11476         setfattr -x user.author1 $testfile ||
11477                 error "$testfile error deleting user.author1"
11478         echo "set lustre special xattr ..."
11479         $LFS setstripe -c1 $testfile
11480         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11481                 awk -F "=" '/trusted.lov/ { print $2 }' )
11482         setfattr -n "trusted.lov" -v $lovea $testfile ||
11483                 error "$testfile doesn't ignore setting trusted.lov again"
11484         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11485                 error "$testfile allow setting invalid trusted.lov"
11486         rm -f $testfile
11487 }
11488 run_test 102a "user xattr test =================================="
11489
11490 check_102b_layout() {
11491         local layout="$*"
11492         local testfile=$DIR/$tfile
11493
11494         echo "test layout '$layout'"
11495         $LFS setstripe $layout $testfile || error "setstripe failed"
11496         $LFS getstripe -y $testfile
11497
11498         echo "get/set/list trusted.lov xattr ..." # b=10930
11499         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11500         [[ "$value" =~ "trusted.lov" ]] ||
11501                 error "can't get trusted.lov from $testfile"
11502         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11503                 error "getstripe failed"
11504
11505         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11506
11507         value=$(cut -d= -f2 <<<$value)
11508         # LU-13168: truncated xattr should fail if short lov_user_md header
11509         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11510                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11511         for len in $lens; do
11512                 echo "setfattr $len $testfile.2"
11513                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11514                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11515         done
11516         local stripe_size=$($LFS getstripe -S $testfile.2)
11517         local stripe_count=$($LFS getstripe -c $testfile.2)
11518         [[ $stripe_size -eq 65536 ]] ||
11519                 error "stripe size $stripe_size != 65536"
11520         [[ $stripe_count -eq $stripe_count_orig ]] ||
11521                 error "stripe count $stripe_count != $stripe_count_orig"
11522         rm $testfile $testfile.2
11523 }
11524
11525 test_102b() {
11526         [ -z "$(which setfattr 2>/dev/null)" ] &&
11527                 skip_env "could not find setfattr"
11528         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11529
11530         # check plain layout
11531         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11532
11533         # and also check composite layout
11534         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11535
11536 }
11537 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11538
11539 test_102c() {
11540         [ -z "$(which setfattr 2>/dev/null)" ] &&
11541                 skip_env "could not find setfattr"
11542         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11543
11544         # b10930: get/set/list lustre.lov xattr
11545         echo "get/set/list lustre.lov xattr ..."
11546         test_mkdir $DIR/$tdir
11547         chown $RUNAS_ID $DIR/$tdir
11548         local testfile=$DIR/$tdir/$tfile
11549         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11550                 error "setstripe failed"
11551         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11552                 error "getstripe failed"
11553         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11554         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11555
11556         local testfile2=${testfile}2
11557         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11558                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11559
11560         $RUNAS $MCREATE $testfile2
11561         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11562         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11563         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11564         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11565         [ $stripe_count -eq $STRIPECOUNT ] ||
11566                 error "stripe count $stripe_count != $STRIPECOUNT"
11567 }
11568 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11569
11570 compare_stripe_info1() {
11571         local stripe_index_all_zero=true
11572
11573         for num in 1 2 3 4; do
11574                 for count in $(seq 1 $STRIPE_COUNT); do
11575                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11576                                 local size=$((STRIPE_SIZE * num))
11577                                 local file=file"$num-$offset-$count"
11578                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11579                                 [[ $stripe_size -ne $size ]] &&
11580                                     error "$file: size $stripe_size != $size"
11581                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11582                                 # allow fewer stripes to be created, ORI-601
11583                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11584                                     error "$file: count $stripe_count != $count"
11585                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11586                                 [[ $stripe_index -ne 0 ]] &&
11587                                         stripe_index_all_zero=false
11588                         done
11589                 done
11590         done
11591         $stripe_index_all_zero &&
11592                 error "all files are being extracted starting from OST index 0"
11593         return 0
11594 }
11595
11596 have_xattrs_include() {
11597         tar --help | grep -q xattrs-include &&
11598                 echo --xattrs-include="lustre.*"
11599 }
11600
11601 test_102d() {
11602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11603         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11604
11605         XINC=$(have_xattrs_include)
11606         setup_test102
11607         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11608         cd $DIR/$tdir/$tdir
11609         compare_stripe_info1
11610 }
11611 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11612
11613 test_102f() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11616
11617         XINC=$(have_xattrs_include)
11618         setup_test102
11619         test_mkdir $DIR/$tdir.restore
11620         cd $DIR
11621         tar cf - --xattrs $tdir | tar xf - \
11622                 -C $DIR/$tdir.restore --xattrs $XINC
11623         cd $DIR/$tdir.restore/$tdir
11624         compare_stripe_info1
11625 }
11626 run_test 102f "tar copy files, not keep osts"
11627
11628 grow_xattr() {
11629         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11630                 skip "must have user_xattr"
11631         [ -z "$(which setfattr 2>/dev/null)" ] &&
11632                 skip_env "could not find setfattr"
11633         [ -z "$(which getfattr 2>/dev/null)" ] &&
11634                 skip_env "could not find getfattr"
11635
11636         local xsize=${1:-1024}  # in bytes
11637         local file=$DIR/$tfile
11638         local value="$(generate_string $xsize)"
11639         local xbig=trusted.big
11640         local toobig=$2
11641
11642         touch $file
11643         log "save $xbig on $file"
11644         if [ -z "$toobig" ]
11645         then
11646                 setfattr -n $xbig -v $value $file ||
11647                         error "saving $xbig on $file failed"
11648         else
11649                 setfattr -n $xbig -v $value $file &&
11650                         error "saving $xbig on $file succeeded"
11651                 return 0
11652         fi
11653
11654         local orig=$(get_xattr_value $xbig $file)
11655         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11656
11657         local xsml=trusted.sml
11658         log "save $xsml on $file"
11659         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11660
11661         local new=$(get_xattr_value $xbig $file)
11662         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11663
11664         log "grow $xsml on $file"
11665         setfattr -n $xsml -v "$value" $file ||
11666                 error "growing $xsml on $file failed"
11667
11668         new=$(get_xattr_value $xbig $file)
11669         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11670         log "$xbig still valid after growing $xsml"
11671
11672         rm -f $file
11673 }
11674
11675 test_102h() { # bug 15777
11676         grow_xattr 1024
11677 }
11678 run_test 102h "grow xattr from inside inode to external block"
11679
11680 test_102ha() {
11681         large_xattr_enabled || skip_env "ea_inode feature disabled"
11682
11683         echo "setting xattr of max xattr size: $(max_xattr_size)"
11684         grow_xattr $(max_xattr_size)
11685
11686         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11687         echo "This should fail:"
11688         grow_xattr $(($(max_xattr_size) + 10)) 1
11689 }
11690 run_test 102ha "grow xattr from inside inode to external inode"
11691
11692 test_102i() { # bug 17038
11693         [ -z "$(which getfattr 2>/dev/null)" ] &&
11694                 skip "could not find getfattr"
11695
11696         touch $DIR/$tfile
11697         ln -s $DIR/$tfile $DIR/${tfile}link
11698         getfattr -n trusted.lov $DIR/$tfile ||
11699                 error "lgetxattr on $DIR/$tfile failed"
11700         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11701                 grep -i "no such attr" ||
11702                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11703         rm -f $DIR/$tfile $DIR/${tfile}link
11704 }
11705 run_test 102i "lgetxattr test on symbolic link ============"
11706
11707 test_102j() {
11708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11709         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11710
11711         XINC=$(have_xattrs_include)
11712         setup_test102 "$RUNAS"
11713         chown $RUNAS_ID $DIR/$tdir
11714         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11715         cd $DIR/$tdir/$tdir
11716         compare_stripe_info1 "$RUNAS"
11717 }
11718 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11719
11720 test_102k() {
11721         [ -z "$(which setfattr 2>/dev/null)" ] &&
11722                 skip "could not find setfattr"
11723
11724         touch $DIR/$tfile
11725         # b22187 just check that does not crash for regular file.
11726         setfattr -n trusted.lov $DIR/$tfile
11727         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11728         local test_kdir=$DIR/$tdir
11729         test_mkdir $test_kdir
11730         local default_size=$($LFS getstripe -S $test_kdir)
11731         local default_count=$($LFS getstripe -c $test_kdir)
11732         local default_offset=$($LFS getstripe -i $test_kdir)
11733         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11734                 error 'dir setstripe failed'
11735         setfattr -n trusted.lov $test_kdir
11736         local stripe_size=$($LFS getstripe -S $test_kdir)
11737         local stripe_count=$($LFS getstripe -c $test_kdir)
11738         local stripe_offset=$($LFS getstripe -i $test_kdir)
11739         [ $stripe_size -eq $default_size ] ||
11740                 error "stripe size $stripe_size != $default_size"
11741         [ $stripe_count -eq $default_count ] ||
11742                 error "stripe count $stripe_count != $default_count"
11743         [ $stripe_offset -eq $default_offset ] ||
11744                 error "stripe offset $stripe_offset != $default_offset"
11745         rm -rf $DIR/$tfile $test_kdir
11746 }
11747 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11748
11749 test_102l() {
11750         [ -z "$(which getfattr 2>/dev/null)" ] &&
11751                 skip "could not find getfattr"
11752
11753         # LU-532 trusted. xattr is invisible to non-root
11754         local testfile=$DIR/$tfile
11755
11756         touch $testfile
11757
11758         echo "listxattr as user..."
11759         chown $RUNAS_ID $testfile
11760         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11761             grep -q "trusted" &&
11762                 error "$testfile trusted xattrs are user visible"
11763
11764         return 0;
11765 }
11766 run_test 102l "listxattr size test =================================="
11767
11768 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11769         local path=$DIR/$tfile
11770         touch $path
11771
11772         listxattr_size_check $path || error "listattr_size_check $path failed"
11773 }
11774 run_test 102m "Ensure listxattr fails on small bufffer ========"
11775
11776 cleanup_test102
11777
11778 getxattr() { # getxattr path name
11779         # Return the base64 encoding of the value of xattr name on path.
11780         local path=$1
11781         local name=$2
11782
11783         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11784         # file: $path
11785         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11786         #
11787         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11788
11789         getfattr --absolute-names --encoding=base64 --name=$name $path |
11790                 awk -F= -v name=$name '$1 == name {
11791                         print substr($0, index($0, "=") + 1);
11792         }'
11793 }
11794
11795 test_102n() { # LU-4101 mdt: protect internal xattrs
11796         [ -z "$(which setfattr 2>/dev/null)" ] &&
11797                 skip "could not find setfattr"
11798         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11799         then
11800                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11801         fi
11802
11803         local file0=$DIR/$tfile.0
11804         local file1=$DIR/$tfile.1
11805         local xattr0=$TMP/$tfile.0
11806         local xattr1=$TMP/$tfile.1
11807         local namelist="lov lma lmv link fid version som hsm"
11808         local name
11809         local value
11810
11811         rm -rf $file0 $file1 $xattr0 $xattr1
11812         touch $file0 $file1
11813
11814         # Get 'before' xattrs of $file1.
11815         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11816
11817         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11818                 namelist+=" lfsck_namespace"
11819         for name in $namelist; do
11820                 # Try to copy xattr from $file0 to $file1.
11821                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11822
11823                 setfattr --name=trusted.$name --value="$value" $file1 ||
11824                         error "setxattr 'trusted.$name' failed"
11825
11826                 # Try to set a garbage xattr.
11827                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11828
11829                 if [[ x$name == "xlov" ]]; then
11830                         setfattr --name=trusted.lov --value="$value" $file1 &&
11831                         error "setxattr invalid 'trusted.lov' success"
11832                 else
11833                         setfattr --name=trusted.$name --value="$value" $file1 ||
11834                                 error "setxattr invalid 'trusted.$name' failed"
11835                 fi
11836
11837                 # Try to remove the xattr from $file1. We don't care if this
11838                 # appears to succeed or fail, we just don't want there to be
11839                 # any changes or crashes.
11840                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11841         done
11842
11843         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11844         then
11845                 name="lfsck_ns"
11846                 # Try to copy xattr from $file0 to $file1.
11847                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11848
11849                 setfattr --name=trusted.$name --value="$value" $file1 ||
11850                         error "setxattr 'trusted.$name' failed"
11851
11852                 # Try to set a garbage xattr.
11853                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11854
11855                 setfattr --name=trusted.$name --value="$value" $file1 ||
11856                         error "setxattr 'trusted.$name' failed"
11857
11858                 # Try to remove the xattr from $file1. We don't care if this
11859                 # appears to succeed or fail, we just don't want there to be
11860                 # any changes or crashes.
11861                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11862         fi
11863
11864         # Get 'after' xattrs of file1.
11865         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11866
11867         if ! diff $xattr0 $xattr1; then
11868                 error "before and after xattrs of '$file1' differ"
11869         fi
11870
11871         rm -rf $file0 $file1 $xattr0 $xattr1
11872
11873         return 0
11874 }
11875 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11876
11877 test_102p() { # LU-4703 setxattr did not check ownership
11878         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11879                 skip "MDS needs to be at least 2.5.56"
11880
11881         local testfile=$DIR/$tfile
11882
11883         touch $testfile
11884
11885         echo "setfacl as user..."
11886         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11887         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11888
11889         echo "setfattr as user..."
11890         setfacl -m "u:$RUNAS_ID:---" $testfile
11891         $RUNAS setfattr -x system.posix_acl_access $testfile
11892         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11893 }
11894 run_test 102p "check setxattr(2) correctly fails without permission"
11895
11896 test_102q() {
11897         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11898                 skip "MDS needs to be at least 2.6.92"
11899
11900         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11901 }
11902 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11903
11904 test_102r() {
11905         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11906                 skip "MDS needs to be at least 2.6.93"
11907
11908         touch $DIR/$tfile || error "touch"
11909         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11910         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11911         rm $DIR/$tfile || error "rm"
11912
11913         #normal directory
11914         mkdir -p $DIR/$tdir || error "mkdir"
11915         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11916         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11917         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11918                 error "$testfile error deleting user.author1"
11919         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11920                 grep "user.$(basename $tdir)" &&
11921                 error "$tdir did not delete user.$(basename $tdir)"
11922         rmdir $DIR/$tdir || error "rmdir"
11923
11924         #striped directory
11925         test_mkdir $DIR/$tdir
11926         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11927         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11928         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11929                 error "$testfile error deleting user.author1"
11930         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11931                 grep "user.$(basename $tdir)" &&
11932                 error "$tdir did not delete user.$(basename $tdir)"
11933         rmdir $DIR/$tdir || error "rm striped dir"
11934 }
11935 run_test 102r "set EAs with empty values"
11936
11937 test_102s() {
11938         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11939                 skip "MDS needs to be at least 2.11.52"
11940
11941         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11942
11943         save_lustre_params client "llite.*.xattr_cache" > $save
11944
11945         for cache in 0 1; do
11946                 lctl set_param llite.*.xattr_cache=$cache
11947
11948                 rm -f $DIR/$tfile
11949                 touch $DIR/$tfile || error "touch"
11950                 for prefix in lustre security system trusted user; do
11951                         # Note getxattr() may fail with 'Operation not
11952                         # supported' or 'No such attribute' depending
11953                         # on prefix and cache.
11954                         getfattr -n $prefix.n102s $DIR/$tfile &&
11955                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11956                 done
11957         done
11958
11959         restore_lustre_params < $save
11960 }
11961 run_test 102s "getting nonexistent xattrs should fail"
11962
11963 test_102t() {
11964         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11965                 skip "MDS needs to be at least 2.11.52"
11966
11967         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11968
11969         save_lustre_params client "llite.*.xattr_cache" > $save
11970
11971         for cache in 0 1; do
11972                 lctl set_param llite.*.xattr_cache=$cache
11973
11974                 for buf_size in 0 256; do
11975                         rm -f $DIR/$tfile
11976                         touch $DIR/$tfile || error "touch"
11977                         setfattr -n user.multiop $DIR/$tfile
11978                         $MULTIOP $DIR/$tfile oa$buf_size ||
11979                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11980                 done
11981         done
11982
11983         restore_lustre_params < $save
11984 }
11985 run_test 102t "zero length xattr values handled correctly"
11986
11987 run_acl_subtest()
11988 {
11989         local test=$LUSTRE/tests/acl/$1.test
11990         local tmp=$(mktemp -t $1-XXXXXX).test
11991         local bin=$2
11992         local dmn=$3
11993         local grp=$4
11994         local nbd=$5
11995         export LANG=C
11996
11997
11998         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11999         local sedgroups="-e s/:users/:$grp/g"
12000         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12001
12002         sed $sedusers $sedgroups < $test > $tmp
12003         stack_trap "rm -f $tmp"
12004         [[ -s $tmp ]] || error "sed failed to create test script"
12005
12006         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12007         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12008 }
12009
12010 test_103a() {
12011         [ "$UID" != 0 ] && skip "must run as root"
12012         $GSS && skip_env "could not run under gss"
12013         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12014                 skip_env "must have acl enabled"
12015         which setfacl || skip_env "could not find setfacl"
12016         remote_mds_nodsh && skip "remote MDS with nodsh"
12017
12018         ACLBIN=${ACLBIN:-"bin"}
12019         ACLDMN=${ACLDMN:-"daemon"}
12020         ACLGRP=${ACLGRP:-"users"}
12021         ACLNBD=${ACLNBD:-"nobody"}
12022
12023         if ! id $ACLBIN ||
12024            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12025                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12026                 ACLBIN=$USER0
12027                 if ! id $ACLBIN ; then
12028                         cat /etc/passwd
12029                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12030                 fi
12031         fi
12032         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12033            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12034                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12035                 ACLDMN=$USER1
12036                 if ! id $ACLDMN ; then
12037                         cat /etc/passwd
12038                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12039                 fi
12040         fi
12041         if ! getent group $ACLGRP; then
12042                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12043                 ACLGRP="$TSTUSR"
12044                 if ! getent group $ACLGRP; then
12045                         echo "cannot find group '$ACLGRP', adding it"
12046                         cat /etc/group
12047                         add_group 60000 $ACLGRP
12048                 fi
12049         fi
12050
12051         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12052         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12053         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12054
12055         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12056                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12057                 ACLGRP="$TSTUSR"
12058                 if ! getent group $ACLGRP; then
12059                         echo "cannot find group '$ACLGRP', adding it"
12060                         cat /etc/group
12061                         add_group 60000 $ACLGRP
12062                 fi
12063                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12064                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12065                         cat /etc/group
12066                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12067                 fi
12068         fi
12069
12070         gpasswd -a $ACLDMN $ACLBIN ||
12071                 error "setting client group failed"             # LU-5641
12072         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12073                 error "setting MDS group failed"                # LU-5641
12074
12075         declare -a identity_old
12076
12077         for num in $(seq $MDSCOUNT); do
12078                 switch_identity $num true || identity_old[$num]=$?
12079         done
12080
12081         SAVE_UMASK=$(umask)
12082         umask 0022
12083         mkdir -p $DIR/$tdir
12084         cd $DIR/$tdir
12085
12086         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12087         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12088         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12089         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12090         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12091         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12092         if ! id -u $ACLNBD ||
12093            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12094                 ACLNBD="nfsnobody"
12095                 if ! id -u $ACLNBD; then
12096                         ACLNBD=""
12097                 fi
12098         fi
12099         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12100                 add_group $(id -u $ACLNBD) $ACLNBD
12101                 if ! getent group $ACLNBD; then
12102                         ACLNBD=""
12103                 fi
12104         fi
12105         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12106            [[ -n "$ACLNBD" ]] && which setfattr; then
12107                 run_acl_subtest permissions_xattr \
12108                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12109         elif [[ -z "$ACLNBD" ]]; then
12110                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12111         else
12112                 echo "skip 'permission_xattr' test - missing setfattr command"
12113         fi
12114         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12115
12116         # inheritance test got from HP
12117         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12118         chmod +x make-tree || error "chmod +x failed"
12119         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12120         rm -f make-tree
12121
12122         echo "LU-974 ignore umask when acl is enabled..."
12123         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12124         if [ $MDSCOUNT -ge 2 ]; then
12125                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12126         fi
12127
12128         echo "LU-2561 newly created file is same size as directory..."
12129         if [ "$mds1_FSTYPE" != "zfs" ]; then
12130                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12131         else
12132                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12133         fi
12134
12135         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12136
12137         cd $SAVE_PWD
12138         umask $SAVE_UMASK
12139
12140         for num in $(seq $MDSCOUNT); do
12141                 if [ "${identity_old[$num]}" = 1 ]; then
12142                         switch_identity $num false || identity_old[$num]=$?
12143                 fi
12144         done
12145 }
12146 run_test 103a "acl test"
12147
12148 test_103b() {
12149         declare -a pids
12150         local U
12151
12152         for U in {0..511}; do
12153                 {
12154                 local O=$(printf "%04o" $U)
12155
12156                 umask $(printf "%04o" $((511 ^ $O)))
12157                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12158                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12159
12160                 (( $S == ($O & 0666) )) ||
12161                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12162
12163                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12164                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12165                 (( $S == ($O & 0666) )) ||
12166                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12167
12168                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12169                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12170                 (( $S == ($O & 0666) )) ||
12171                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12172                 rm -f $DIR/$tfile.[smp]$0
12173                 } &
12174                 local pid=$!
12175
12176                 # limit the concurrently running threads to 64. LU-11878
12177                 local idx=$((U % 64))
12178                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12179                 pids[idx]=$pid
12180         done
12181         wait
12182 }
12183 run_test 103b "umask lfs setstripe"
12184
12185 test_103c() {
12186         mkdir -p $DIR/$tdir
12187         cp -rp $DIR/$tdir $DIR/$tdir.bak
12188
12189         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12190                 error "$DIR/$tdir shouldn't contain default ACL"
12191         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12192                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12193         true
12194 }
12195 run_test 103c "'cp -rp' won't set empty acl"
12196
12197 test_103e() {
12198         local numacl
12199         local fileacl
12200         local saved_debug=$($LCTL get_param -n debug)
12201
12202         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12203                 skip "MDS needs to be at least 2.14.52"
12204
12205         large_xattr_enabled || skip_env "ea_inode feature disabled"
12206
12207         mkdir -p $DIR/$tdir
12208         # add big LOV EA to cause reply buffer overflow earlier
12209         $LFS setstripe -C 1000 $DIR/$tdir
12210         lctl set_param mdc.*-mdc*.stats=clear
12211
12212         $LCTL set_param debug=0
12213         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12214         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12215
12216         # add a large number of default ACLs (expect 8000+ for 2.13+)
12217         for U in {2..7000}; do
12218                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12219                         error "Able to add just $U default ACLs"
12220         done
12221         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12222         echo "$numacl default ACLs created"
12223
12224         stat $DIR/$tdir || error "Cannot stat directory"
12225         # check file creation
12226         touch $DIR/$tdir/$tfile ||
12227                 error "failed to create $tfile with $numacl default ACLs"
12228         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12229         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12230         echo "$fileacl ACLs were inherited"
12231         (( $fileacl == $numacl )) ||
12232                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12233         # check that new ACLs creation adds new ACLs to inherited ACLs
12234         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12235                 error "Cannot set new ACL"
12236         numacl=$((numacl + 1))
12237         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12238         (( $fileacl == $numacl )) ||
12239                 error "failed to add new ACL: $fileacl != $numacl as expected"
12240         # adds more ACLs to a file to reach their maximum at 8000+
12241         numacl=0
12242         for U in {20000..25000}; do
12243                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12244                 numacl=$((numacl + 1))
12245         done
12246         echo "Added $numacl more ACLs to the file"
12247         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12248         echo "Total $fileacl ACLs in file"
12249         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12250         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12251         rmdir $DIR/$tdir || error "Cannot remove directory"
12252 }
12253 run_test 103e "inheritance of big amount of default ACLs"
12254
12255 test_103f() {
12256         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12257                 skip "MDS needs to be at least 2.14.51"
12258
12259         large_xattr_enabled || skip_env "ea_inode feature disabled"
12260
12261         # enable changelog to consume more internal MDD buffers
12262         changelog_register
12263
12264         mkdir -p $DIR/$tdir
12265         # add big LOV EA
12266         $LFS setstripe -C 1000 $DIR/$tdir
12267         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12268         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12269         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12270         rmdir $DIR/$tdir || error "Cannot remove directory"
12271 }
12272 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12273
12274 test_104a() {
12275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12276
12277         touch $DIR/$tfile
12278         lfs df || error "lfs df failed"
12279         lfs df -ih || error "lfs df -ih failed"
12280         lfs df -h $DIR || error "lfs df -h $DIR failed"
12281         lfs df -i $DIR || error "lfs df -i $DIR failed"
12282         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12283         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12284
12285         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12286         lctl --device %$OSC deactivate
12287         lfs df || error "lfs df with deactivated OSC failed"
12288         lctl --device %$OSC activate
12289         # wait the osc back to normal
12290         wait_osc_import_ready client ost
12291
12292         lfs df || error "lfs df with reactivated OSC failed"
12293         rm -f $DIR/$tfile
12294 }
12295 run_test 104a "lfs df [-ih] [path] test ========================="
12296
12297 test_104b() {
12298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12299         [ $RUNAS_ID -eq $UID ] &&
12300                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12301
12302         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12303                         grep "Permission denied" | wc -l)))
12304         if [ $denied_cnt -ne 0 ]; then
12305                 error "lfs check servers test failed"
12306         fi
12307 }
12308 run_test 104b "$RUNAS lfs check servers test ===================="
12309
12310 #
12311 # Verify $1 is within range of $2.
12312 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12313 # $1 is <= 2% of $2. Else Fail.
12314 #
12315 value_in_range() {
12316         # Strip all units (M, G, T)
12317         actual=$(echo $1 | tr -d A-Z)
12318         expect=$(echo $2 | tr -d A-Z)
12319
12320         expect_lo=$(($expect * 98 / 100)) # 2% below
12321         expect_hi=$(($expect * 102 / 100)) # 2% above
12322
12323         # permit 2% drift above and below
12324         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12325 }
12326
12327 test_104c() {
12328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12329         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12330
12331         local ost_param="osd-zfs.$FSNAME-OST0000."
12332         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12333         local ofacets=$(get_facets OST)
12334         local mfacets=$(get_facets MDS)
12335         local saved_ost_blocks=
12336         local saved_mdt_blocks=
12337
12338         echo "Before recordsize change"
12339         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12340         df=($(df -h | grep "$MOUNT"$))
12341
12342         # For checking.
12343         echo "lfs output : ${lfs_df[*]}"
12344         echo "df  output : ${df[*]}"
12345
12346         for facet in ${ofacets//,/ }; do
12347                 if [ -z $saved_ost_blocks ]; then
12348                         saved_ost_blocks=$(do_facet $facet \
12349                                 lctl get_param -n $ost_param.blocksize)
12350                         echo "OST Blocksize: $saved_ost_blocks"
12351                 fi
12352                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12353                 do_facet $facet zfs set recordsize=32768 $ost
12354         done
12355
12356         # BS too small. Sufficient for functional testing.
12357         for facet in ${mfacets//,/ }; do
12358                 if [ -z $saved_mdt_blocks ]; then
12359                         saved_mdt_blocks=$(do_facet $facet \
12360                                 lctl get_param -n $mdt_param.blocksize)
12361                         echo "MDT Blocksize: $saved_mdt_blocks"
12362                 fi
12363                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12364                 do_facet $facet zfs set recordsize=32768 $mdt
12365         done
12366
12367         # Give new values chance to reflect change
12368         sleep 2
12369
12370         echo "After recordsize change"
12371         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12372         df_after=($(df -h | grep "$MOUNT"$))
12373
12374         # For checking.
12375         echo "lfs output : ${lfs_df_after[*]}"
12376         echo "df  output : ${df_after[*]}"
12377
12378         # Verify lfs df
12379         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12380                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12381         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12382                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12383         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12384                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12385
12386         # Verify df
12387         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12388                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12389         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12390                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12391         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12392                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12393
12394         # Restore MDT recordize back to original
12395         for facet in ${mfacets//,/ }; do
12396                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12397                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12398         done
12399
12400         # Restore OST recordize back to original
12401         for facet in ${ofacets//,/ }; do
12402                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12403                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12404         done
12405
12406         return 0
12407 }
12408 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12409
12410 test_104d() {
12411         (( $RUNAS_ID != $UID )) ||
12412                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12413
12414         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12415                 skip "lustre version doesn't support lctl dl with non-root"
12416
12417         # debugfs only allows root users to access files, so the
12418         # previous move of the "devices" file to debugfs broke
12419         # "lctl dl" for non-root users. The LU-9680 Netlink
12420         # interface again allows non-root users to list devices.
12421         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12422                 error "lctl dl doesn't work for non root"
12423
12424         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12425         [ "$ost_count" -eq $OSTCOUNT ]  ||
12426                 error "lctl dl reports wrong number of OST devices"
12427
12428         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12429         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12430                 error "lctl dl reports wrong number of MDT devices"
12431 }
12432 run_test 104d "$RUNAS lctl dl test"
12433
12434 test_105a() {
12435         # doesn't work on 2.4 kernels
12436         touch $DIR/$tfile
12437         if $(flock_is_enabled); then
12438                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12439         else
12440                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12441         fi
12442         rm -f $DIR/$tfile
12443 }
12444 run_test 105a "flock when mounted without -o flock test ========"
12445
12446 test_105b() {
12447         touch $DIR/$tfile
12448         if $(flock_is_enabled); then
12449                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12450         else
12451                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12452         fi
12453         rm -f $DIR/$tfile
12454 }
12455 run_test 105b "fcntl when mounted without -o flock test ========"
12456
12457 test_105c() {
12458         touch $DIR/$tfile
12459         if $(flock_is_enabled); then
12460                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12461         else
12462                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12463         fi
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 105c "lockf when mounted without -o flock test"
12467
12468 test_105d() { # bug 15924
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         test_mkdir $DIR/$tdir
12472         flock_is_enabled || skip_env "mount w/o flock enabled"
12473         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12474         $LCTL set_param fail_loc=0x80000315
12475         flocks_test 2 $DIR/$tdir
12476 }
12477 run_test 105d "flock race (should not freeze) ========"
12478
12479 test_105e() { # bug 22660 && 22040
12480         flock_is_enabled || skip_env "mount w/o flock enabled"
12481
12482         touch $DIR/$tfile
12483         flocks_test 3 $DIR/$tfile
12484 }
12485 run_test 105e "Two conflicting flocks from same process"
12486
12487 test_106() { #bug 10921
12488         test_mkdir $DIR/$tdir
12489         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12490         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12491 }
12492 run_test 106 "attempt exec of dir followed by chown of that dir"
12493
12494 test_107() {
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         CDIR=`pwd`
12498         local file=core
12499
12500         cd $DIR
12501         rm -f $file
12502
12503         local save_pattern=$(sysctl -n kernel.core_pattern)
12504         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12505         sysctl -w kernel.core_pattern=$file
12506         sysctl -w kernel.core_uses_pid=0
12507
12508         ulimit -c unlimited
12509         sleep 60 &
12510         SLEEPPID=$!
12511
12512         sleep 1
12513
12514         kill -s 11 $SLEEPPID
12515         wait $SLEEPPID
12516         if [ -e $file ]; then
12517                 size=`stat -c%s $file`
12518                 [ $size -eq 0 ] && error "Fail to create core file $file"
12519         else
12520                 error "Fail to create core file $file"
12521         fi
12522         rm -f $file
12523         sysctl -w kernel.core_pattern=$save_pattern
12524         sysctl -w kernel.core_uses_pid=$save_uses_pid
12525         cd $CDIR
12526 }
12527 run_test 107 "Coredump on SIG"
12528
12529 test_110() {
12530         test_mkdir $DIR/$tdir
12531         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12532         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12533                 error "mkdir with 256 char should fail, but did not"
12534         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12535                 error "create with 255 char failed"
12536         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12537                 error "create with 256 char should fail, but did not"
12538
12539         ls -l $DIR/$tdir
12540         rm -rf $DIR/$tdir
12541 }
12542 run_test 110 "filename length checking"
12543
12544 test_116a() { # was previously test_116()
12545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12546         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12547         remote_mds_nodsh && skip "remote MDS with nodsh"
12548
12549         echo -n "Free space priority "
12550         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12551                 head -n1
12552         declare -a AVAIL
12553         free_min_max
12554
12555         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12556         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12557         stack_trap simple_cleanup_common
12558
12559         # Check if we need to generate uneven OSTs
12560         test_mkdir -p $DIR/$tdir/OST${MINI}
12561         local FILL=$((MINV / 4))
12562         local DIFF=$((MAXV - MINV))
12563         local DIFF2=$((DIFF * 100 / MINV))
12564
12565         local threshold=$(do_facet $SINGLEMDS \
12566                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12567         threshold=${threshold%%%}
12568         echo -n "Check for uneven OSTs: "
12569         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12570
12571         if [[ $DIFF2 -gt $threshold ]]; then
12572                 echo "ok"
12573                 echo "Don't need to fill OST$MINI"
12574         else
12575                 # generate uneven OSTs. Write 2% over the QOS threshold value
12576                 echo "no"
12577                 DIFF=$((threshold - DIFF2 + 2))
12578                 DIFF2=$((MINV * DIFF / 100))
12579                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12580                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12581                         error "setstripe failed"
12582                 DIFF=$((DIFF2 / 2048))
12583                 i=0
12584                 while [ $i -lt $DIFF ]; do
12585                         i=$((i + 1))
12586                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12587                                 bs=2M count=1 2>/dev/null
12588                         echo -n .
12589                 done
12590                 echo .
12591                 sync
12592                 sleep_maxage
12593                 free_min_max
12594         fi
12595
12596         DIFF=$((MAXV - MINV))
12597         DIFF2=$((DIFF * 100 / MINV))
12598         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12599         if [ $DIFF2 -gt $threshold ]; then
12600                 echo "ok"
12601         else
12602                 skip "QOS imbalance criteria not met"
12603         fi
12604
12605         MINI1=$MINI
12606         MINV1=$MINV
12607         MAXI1=$MAXI
12608         MAXV1=$MAXV
12609
12610         # now fill using QOS
12611         $LFS setstripe -c 1 $DIR/$tdir
12612         FILL=$((FILL / 200))
12613         if [ $FILL -gt 600 ]; then
12614                 FILL=600
12615         fi
12616         echo "writing $FILL files to QOS-assigned OSTs"
12617         i=0
12618         while [ $i -lt $FILL ]; do
12619                 i=$((i + 1))
12620                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12621                         count=1 2>/dev/null
12622                 echo -n .
12623         done
12624         echo "wrote $i 200k files"
12625         sync
12626         sleep_maxage
12627
12628         echo "Note: free space may not be updated, so measurements might be off"
12629         free_min_max
12630         DIFF2=$((MAXV - MINV))
12631         echo "free space delta: orig $DIFF final $DIFF2"
12632         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12633         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12634         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12635         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12636         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12637         if [[ $DIFF -gt 0 ]]; then
12638                 FILL=$((DIFF2 * 100 / DIFF - 100))
12639                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12640         fi
12641
12642         # Figure out which files were written where
12643         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12644                awk '/'$MINI1': / {print $2; exit}')
12645         echo $UUID
12646         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12647         echo "$MINC files created on smaller OST $MINI1"
12648         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12649                awk '/'$MAXI1': / {print $2; exit}')
12650         echo $UUID
12651         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12652         echo "$MAXC files created on larger OST $MAXI1"
12653         if [[ $MINC -gt 0 ]]; then
12654                 FILL=$((MAXC * 100 / MINC - 100))
12655                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12656         fi
12657         [[ $MAXC -gt $MINC ]] ||
12658                 error_ignore LU-9 "stripe QOS didn't balance free space"
12659 }
12660 run_test 116a "stripe QOS: free space balance ==================="
12661
12662 test_116b() { # LU-2093
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664         remote_mds_nodsh && skip "remote MDS with nodsh"
12665
12666 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12667         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12668                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12669         [ -z "$old_rr" ] && skip "no QOS"
12670         do_facet $SINGLEMDS lctl set_param \
12671                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12672         mkdir -p $DIR/$tdir
12673         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12674         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12675         do_facet $SINGLEMDS lctl set_param fail_loc=0
12676         rm -rf $DIR/$tdir
12677         do_facet $SINGLEMDS lctl set_param \
12678                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12679 }
12680 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12681
12682 test_117() # bug 10891
12683 {
12684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12685
12686         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12687         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12688         lctl set_param fail_loc=0x21e
12689         > $DIR/$tfile || error "truncate failed"
12690         lctl set_param fail_loc=0
12691         echo "Truncate succeeded."
12692         rm -f $DIR/$tfile
12693 }
12694 run_test 117 "verify osd extend =========="
12695
12696 NO_SLOW_RESENDCOUNT=4
12697 export OLD_RESENDCOUNT=""
12698 set_resend_count () {
12699         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12700         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12701         lctl set_param -n $PROC_RESENDCOUNT $1
12702         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12703 }
12704
12705 # for reduce test_118* time (b=14842)
12706 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12707
12708 # Reset async IO behavior after error case
12709 reset_async() {
12710         FILE=$DIR/reset_async
12711
12712         # Ensure all OSCs are cleared
12713         $LFS setstripe -c -1 $FILE
12714         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12715         sync
12716         rm $FILE
12717 }
12718
12719 test_118a() #bug 11710
12720 {
12721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12722
12723         reset_async
12724
12725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12726         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12727         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12728
12729         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12730                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12731                 return 1;
12732         fi
12733         rm -f $DIR/$tfile
12734 }
12735 run_test 118a "verify O_SYNC works =========="
12736
12737 test_118b()
12738 {
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740         remote_ost_nodsh && skip "remote OST with nodsh"
12741
12742         reset_async
12743
12744         #define OBD_FAIL_SRV_ENOENT 0x217
12745         set_nodes_failloc "$(osts_nodes)" 0x217
12746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12747         RC=$?
12748         set_nodes_failloc "$(osts_nodes)" 0
12749         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12750         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12751                     grep -c writeback)
12752
12753         if [[ $RC -eq 0 ]]; then
12754                 error "Must return error due to dropped pages, rc=$RC"
12755                 return 1;
12756         fi
12757
12758         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12759                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12760                 return 1;
12761         fi
12762
12763         echo "Dirty pages not leaked on ENOENT"
12764
12765         # Due to the above error the OSC will issue all RPCs syncronously
12766         # until a subsequent RPC completes successfully without error.
12767         $MULTIOP $DIR/$tfile Ow4096yc
12768         rm -f $DIR/$tfile
12769
12770         return 0
12771 }
12772 run_test 118b "Reclaim dirty pages on fatal error =========="
12773
12774 test_118c()
12775 {
12776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12777
12778         # for 118c, restore the original resend count, LU-1940
12779         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12780                                 set_resend_count $OLD_RESENDCOUNT
12781         remote_ost_nodsh && skip "remote OST with nodsh"
12782
12783         reset_async
12784
12785         #define OBD_FAIL_OST_EROFS               0x216
12786         set_nodes_failloc "$(osts_nodes)" 0x216
12787
12788         # multiop should block due to fsync until pages are written
12789         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12790         MULTIPID=$!
12791         sleep 1
12792
12793         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12794                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12795         fi
12796
12797         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12798                     grep -c writeback)
12799         if [[ $WRITEBACK -eq 0 ]]; then
12800                 error "No page in writeback, writeback=$WRITEBACK"
12801         fi
12802
12803         set_nodes_failloc "$(osts_nodes)" 0
12804         wait $MULTIPID
12805         RC=$?
12806         if [[ $RC -ne 0 ]]; then
12807                 error "Multiop fsync failed, rc=$RC"
12808         fi
12809
12810         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12811         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12812                     grep -c writeback)
12813         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12814                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12815         fi
12816
12817         rm -f $DIR/$tfile
12818         echo "Dirty pages flushed via fsync on EROFS"
12819         return 0
12820 }
12821 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12822
12823 # continue to use small resend count to reduce test_118* time (b=14842)
12824 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12825
12826 test_118d()
12827 {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829         remote_ost_nodsh && skip "remote OST with nodsh"
12830
12831         reset_async
12832
12833         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12834         set_nodes_failloc "$(osts_nodes)" 0x214
12835         # multiop should block due to fsync until pages are written
12836         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12837         MULTIPID=$!
12838         sleep 1
12839
12840         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12841                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12842         fi
12843
12844         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12845                     grep -c writeback)
12846         if [[ $WRITEBACK -eq 0 ]]; then
12847                 error "No page in writeback, writeback=$WRITEBACK"
12848         fi
12849
12850         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12851         set_nodes_failloc "$(osts_nodes)" 0
12852
12853         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12854         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12855                     grep -c writeback)
12856         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12857                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12858         fi
12859
12860         rm -f $DIR/$tfile
12861         echo "Dirty pages gaurenteed flushed via fsync"
12862         return 0
12863 }
12864 run_test 118d "Fsync validation inject a delay of the bulk =========="
12865
12866 test_118f() {
12867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12868
12869         reset_async
12870
12871         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12872         lctl set_param fail_loc=0x8000040a
12873
12874         # Should simulate EINVAL error which is fatal
12875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12876         RC=$?
12877         if [[ $RC -eq 0 ]]; then
12878                 error "Must return error due to dropped pages, rc=$RC"
12879         fi
12880
12881         lctl set_param fail_loc=0x0
12882
12883         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12884         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12885         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12886                     grep -c writeback)
12887         if [[ $LOCKED -ne 0 ]]; then
12888                 error "Locked pages remain in cache, locked=$LOCKED"
12889         fi
12890
12891         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12892                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12893         fi
12894
12895         rm -f $DIR/$tfile
12896         echo "No pages locked after fsync"
12897
12898         reset_async
12899         return 0
12900 }
12901 run_test 118f "Simulate unrecoverable OSC side error =========="
12902
12903 test_118g() {
12904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12905
12906         reset_async
12907
12908         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12909         lctl set_param fail_loc=0x406
12910
12911         # simulate local -ENOMEM
12912         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12913         RC=$?
12914
12915         lctl set_param fail_loc=0
12916         if [[ $RC -eq 0 ]]; then
12917                 error "Must return error due to dropped pages, rc=$RC"
12918         fi
12919
12920         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12921         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12922         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12923                         grep -c writeback)
12924         if [[ $LOCKED -ne 0 ]]; then
12925                 error "Locked pages remain in cache, locked=$LOCKED"
12926         fi
12927
12928         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12929                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12930         fi
12931
12932         rm -f $DIR/$tfile
12933         echo "No pages locked after fsync"
12934
12935         reset_async
12936         return 0
12937 }
12938 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12939
12940 test_118h() {
12941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12942         remote_ost_nodsh && skip "remote OST with nodsh"
12943
12944         reset_async
12945
12946         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12947         set_nodes_failloc "$(osts_nodes)" 0x20e
12948         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12949         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12950         RC=$?
12951
12952         set_nodes_failloc "$(osts_nodes)" 0
12953         if [[ $RC -eq 0 ]]; then
12954                 error "Must return error due to dropped pages, rc=$RC"
12955         fi
12956
12957         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12958         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12960                     grep -c writeback)
12961         if [[ $LOCKED -ne 0 ]]; then
12962                 error "Locked pages remain in cache, locked=$LOCKED"
12963         fi
12964
12965         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12966                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12967         fi
12968
12969         rm -f $DIR/$tfile
12970         echo "No pages locked after fsync"
12971
12972         return 0
12973 }
12974 run_test 118h "Verify timeout in handling recoverables errors  =========="
12975
12976 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12977
12978 test_118i() {
12979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12980         remote_ost_nodsh && skip "remote OST with nodsh"
12981
12982         reset_async
12983
12984         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12985         set_nodes_failloc "$(osts_nodes)" 0x20e
12986
12987         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12988         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12989         PID=$!
12990         sleep 5
12991         set_nodes_failloc "$(osts_nodes)" 0
12992
12993         wait $PID
12994         RC=$?
12995         if [[ $RC -ne 0 ]]; then
12996                 error "got error, but should be not, rc=$RC"
12997         fi
12998
12999         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13002         if [[ $LOCKED -ne 0 ]]; then
13003                 error "Locked pages remain in cache, locked=$LOCKED"
13004         fi
13005
13006         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13007                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13008         fi
13009
13010         rm -f $DIR/$tfile
13011         echo "No pages locked after fsync"
13012
13013         return 0
13014 }
13015 run_test 118i "Fix error before timeout in recoverable error  =========="
13016
13017 [ "$SLOW" = "no" ] && set_resend_count 4
13018
13019 test_118j() {
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021         remote_ost_nodsh && skip "remote OST with nodsh"
13022
13023         reset_async
13024
13025         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13026         set_nodes_failloc "$(osts_nodes)" 0x220
13027
13028         # return -EIO from OST
13029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13030         RC=$?
13031         set_nodes_failloc "$(osts_nodes)" 0x0
13032         if [[ $RC -eq 0 ]]; then
13033                 error "Must return error due to dropped pages, rc=$RC"
13034         fi
13035
13036         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13039         if [[ $LOCKED -ne 0 ]]; then
13040                 error "Locked pages remain in cache, locked=$LOCKED"
13041         fi
13042
13043         # in recoverable error on OST we want resend and stay until it finished
13044         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13045                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13046         fi
13047
13048         rm -f $DIR/$tfile
13049         echo "No pages locked after fsync"
13050
13051         return 0
13052 }
13053 run_test 118j "Simulate unrecoverable OST side error =========="
13054
13055 test_118k()
13056 {
13057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13058         remote_ost_nodsh && skip "remote OSTs with nodsh"
13059
13060         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13061         set_nodes_failloc "$(osts_nodes)" 0x20e
13062         test_mkdir $DIR/$tdir
13063
13064         for ((i=0;i<10;i++)); do
13065                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13066                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13067                 SLEEPPID=$!
13068                 sleep 0.500s
13069                 kill $SLEEPPID
13070                 wait $SLEEPPID
13071         done
13072
13073         set_nodes_failloc "$(osts_nodes)" 0
13074         rm -rf $DIR/$tdir
13075 }
13076 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13077
13078 test_118l() # LU-646
13079 {
13080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13081
13082         test_mkdir $DIR/$tdir
13083         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13084         rm -rf $DIR/$tdir
13085 }
13086 run_test 118l "fsync dir"
13087
13088 test_118m() # LU-3066
13089 {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091
13092         test_mkdir $DIR/$tdir
13093         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13094         rm -rf $DIR/$tdir
13095 }
13096 run_test 118m "fdatasync dir ========="
13097
13098 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13099
13100 test_118n()
13101 {
13102         local begin
13103         local end
13104
13105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13106         remote_ost_nodsh && skip "remote OSTs with nodsh"
13107
13108         # Sleep to avoid a cached response.
13109         #define OBD_STATFS_CACHE_SECONDS 1
13110         sleep 2
13111
13112         # Inject a 10 second delay in the OST_STATFS handler.
13113         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13114         set_nodes_failloc "$(osts_nodes)" 0x242
13115
13116         begin=$SECONDS
13117         stat --file-system $MOUNT > /dev/null
13118         end=$SECONDS
13119
13120         set_nodes_failloc "$(osts_nodes)" 0
13121
13122         if ((end - begin > 20)); then
13123             error "statfs took $((end - begin)) seconds, expected 10"
13124         fi
13125 }
13126 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13127
13128 test_119a() # bug 11737
13129 {
13130         BSIZE=$((512 * 1024))
13131         directio write $DIR/$tfile 0 1 $BSIZE
13132         # We ask to read two blocks, which is more than a file size.
13133         # directio will indicate an error when requested and actual
13134         # sizes aren't equeal (a normal situation in this case) and
13135         # print actual read amount.
13136         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13137         if [ "$NOB" != "$BSIZE" ]; then
13138                 error "read $NOB bytes instead of $BSIZE"
13139         fi
13140         rm -f $DIR/$tfile
13141 }
13142 run_test 119a "Short directIO read must return actual read amount"
13143
13144 test_119b() # bug 11737
13145 {
13146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13147
13148         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13149         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13150         sync
13151         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13152                 error "direct read failed"
13153         rm -f $DIR/$tfile
13154 }
13155 run_test 119b "Sparse directIO read must return actual read amount"
13156
13157 test_119c() # bug 13099
13158 {
13159         BSIZE=1048576
13160         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13161         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13162         rm -f $DIR/$tfile
13163 }
13164 run_test 119c "Testing for direct read hitting hole"
13165
13166 test_119d() # bug 15950
13167 {
13168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13169
13170         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13171         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13172         BSIZE=1048576
13173         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13174         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13175         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13176         lctl set_param fail_loc=0x40d
13177         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13178         pid_dio=$!
13179         sleep 1
13180         cat $DIR/$tfile > /dev/null &
13181         lctl set_param fail_loc=0
13182         pid_reads=$!
13183         wait $pid_dio
13184         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13185         sleep 2
13186         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13187         error "the read rpcs have not completed in 2s"
13188         rm -f $DIR/$tfile
13189         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13190 }
13191 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13192
13193 test_120a() {
13194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13195         remote_mds_nodsh && skip "remote MDS with nodsh"
13196         test_mkdir -i0 -c1 $DIR/$tdir
13197         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13198                 skip_env "no early lock cancel on server"
13199
13200         lru_resize_disable mdc
13201         lru_resize_disable osc
13202         cancel_lru_locks mdc
13203         # asynchronous object destroy at MDT could cause bl ast to client
13204         cancel_lru_locks osc
13205
13206         stat $DIR/$tdir > /dev/null
13207         can1=$(do_facet mds1 \
13208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13209                awk '/ldlm_cancel/ {print $2}')
13210         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13211                awk '/ldlm_bl_callback/ {print $2}')
13212         test_mkdir -i0 -c1 $DIR/$tdir/d1
13213         can2=$(do_facet mds1 \
13214                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13215                awk '/ldlm_cancel/ {print $2}')
13216         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13217                awk '/ldlm_bl_callback/ {print $2}')
13218         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13219         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13220         lru_resize_enable mdc
13221         lru_resize_enable osc
13222 }
13223 run_test 120a "Early Lock Cancel: mkdir test"
13224
13225 test_120b() {
13226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13227         remote_mds_nodsh && skip "remote MDS with nodsh"
13228         test_mkdir $DIR/$tdir
13229         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13230                 skip_env "no early lock cancel on server"
13231
13232         lru_resize_disable mdc
13233         lru_resize_disable osc
13234         cancel_lru_locks mdc
13235         stat $DIR/$tdir > /dev/null
13236         can1=$(do_facet $SINGLEMDS \
13237                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13238                awk '/ldlm_cancel/ {print $2}')
13239         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13240                awk '/ldlm_bl_callback/ {print $2}')
13241         touch $DIR/$tdir/f1
13242         can2=$(do_facet $SINGLEMDS \
13243                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13244                awk '/ldlm_cancel/ {print $2}')
13245         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13246                awk '/ldlm_bl_callback/ {print $2}')
13247         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13248         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13249         lru_resize_enable mdc
13250         lru_resize_enable osc
13251 }
13252 run_test 120b "Early Lock Cancel: create test"
13253
13254 test_120c() {
13255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13256         remote_mds_nodsh && skip "remote MDS with nodsh"
13257         test_mkdir -i0 -c1 $DIR/$tdir
13258         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13259                 skip "no early lock cancel on server"
13260
13261         lru_resize_disable mdc
13262         lru_resize_disable osc
13263         test_mkdir -i0 -c1 $DIR/$tdir/d1
13264         test_mkdir -i0 -c1 $DIR/$tdir/d2
13265         touch $DIR/$tdir/d1/f1
13266         cancel_lru_locks mdc
13267         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13268         can1=$(do_facet mds1 \
13269                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13270                awk '/ldlm_cancel/ {print $2}')
13271         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13272                awk '/ldlm_bl_callback/ {print $2}')
13273         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13274         can2=$(do_facet mds1 \
13275                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13276                awk '/ldlm_cancel/ {print $2}')
13277         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13278                awk '/ldlm_bl_callback/ {print $2}')
13279         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13280         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13281         lru_resize_enable mdc
13282         lru_resize_enable osc
13283 }
13284 run_test 120c "Early Lock Cancel: link test"
13285
13286 test_120d() {
13287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13288         remote_mds_nodsh && skip "remote MDS with nodsh"
13289         test_mkdir -i0 -c1 $DIR/$tdir
13290         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13291                 skip_env "no early lock cancel on server"
13292
13293         lru_resize_disable mdc
13294         lru_resize_disable osc
13295         touch $DIR/$tdir
13296         cancel_lru_locks mdc
13297         stat $DIR/$tdir > /dev/null
13298         can1=$(do_facet mds1 \
13299                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13300                awk '/ldlm_cancel/ {print $2}')
13301         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13302                awk '/ldlm_bl_callback/ {print $2}')
13303         chmod a+x $DIR/$tdir
13304         can2=$(do_facet mds1 \
13305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13306                awk '/ldlm_cancel/ {print $2}')
13307         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13308                awk '/ldlm_bl_callback/ {print $2}')
13309         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13310         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13311         lru_resize_enable mdc
13312         lru_resize_enable osc
13313 }
13314 run_test 120d "Early Lock Cancel: setattr test"
13315
13316 test_120e() {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13319                 skip_env "no early lock cancel on server"
13320         remote_mds_nodsh && skip "remote MDS with nodsh"
13321
13322         local dlmtrace_set=false
13323
13324         test_mkdir -i0 -c1 $DIR/$tdir
13325         lru_resize_disable mdc
13326         lru_resize_disable osc
13327         ! $LCTL get_param debug | grep -q dlmtrace &&
13328                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13329         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13330         cancel_lru_locks mdc
13331         cancel_lru_locks osc
13332         dd if=$DIR/$tdir/f1 of=/dev/null
13333         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13334         # XXX client can not do early lock cancel of OST lock
13335         # during unlink (LU-4206), so cancel osc lock now.
13336         sleep 2
13337         cancel_lru_locks osc
13338         can1=$(do_facet mds1 \
13339                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13340                awk '/ldlm_cancel/ {print $2}')
13341         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13342                awk '/ldlm_bl_callback/ {print $2}')
13343         unlink $DIR/$tdir/f1
13344         sleep 5
13345         can2=$(do_facet mds1 \
13346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13347                awk '/ldlm_cancel/ {print $2}')
13348         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13349                awk '/ldlm_bl_callback/ {print $2}')
13350         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13351                 $LCTL dk $TMP/cancel.debug.txt
13352         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13353                 $LCTL dk $TMP/blocking.debug.txt
13354         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13355         lru_resize_enable mdc
13356         lru_resize_enable osc
13357 }
13358 run_test 120e "Early Lock Cancel: unlink test"
13359
13360 test_120f() {
13361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13362         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13363                 skip_env "no early lock cancel on server"
13364         remote_mds_nodsh && skip "remote MDS with nodsh"
13365
13366         test_mkdir -i0 -c1 $DIR/$tdir
13367         lru_resize_disable mdc
13368         lru_resize_disable osc
13369         test_mkdir -i0 -c1 $DIR/$tdir/d1
13370         test_mkdir -i0 -c1 $DIR/$tdir/d2
13371         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13372         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13373         cancel_lru_locks mdc
13374         cancel_lru_locks osc
13375         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13376         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13377         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13378         # XXX client can not do early lock cancel of OST lock
13379         # during rename (LU-4206), so cancel osc lock now.
13380         sleep 2
13381         cancel_lru_locks osc
13382         can1=$(do_facet mds1 \
13383                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13384                awk '/ldlm_cancel/ {print $2}')
13385         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13386                awk '/ldlm_bl_callback/ {print $2}')
13387         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13388         sleep 5
13389         can2=$(do_facet mds1 \
13390                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13391                awk '/ldlm_cancel/ {print $2}')
13392         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13393                awk '/ldlm_bl_callback/ {print $2}')
13394         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13395         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13396         lru_resize_enable mdc
13397         lru_resize_enable osc
13398 }
13399 run_test 120f "Early Lock Cancel: rename test"
13400
13401 test_120g() {
13402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13403         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13404                 skip_env "no early lock cancel on server"
13405         remote_mds_nodsh && skip "remote MDS with nodsh"
13406
13407         lru_resize_disable mdc
13408         lru_resize_disable osc
13409         count=10000
13410         echo create $count files
13411         test_mkdir $DIR/$tdir
13412         cancel_lru_locks mdc
13413         cancel_lru_locks osc
13414         t0=$(date +%s)
13415
13416         can0=$(do_facet $SINGLEMDS \
13417                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13418                awk '/ldlm_cancel/ {print $2}')
13419         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13420                awk '/ldlm_bl_callback/ {print $2}')
13421         createmany -o $DIR/$tdir/f $count
13422         sync
13423         can1=$(do_facet $SINGLEMDS \
13424                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13425                awk '/ldlm_cancel/ {print $2}')
13426         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13427                awk '/ldlm_bl_callback/ {print $2}')
13428         t1=$(date +%s)
13429         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13430         echo rm $count files
13431         rm -r $DIR/$tdir
13432         sync
13433         can2=$(do_facet $SINGLEMDS \
13434                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13435                awk '/ldlm_cancel/ {print $2}')
13436         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13437                awk '/ldlm_bl_callback/ {print $2}')
13438         t2=$(date +%s)
13439         echo total: $count removes in $((t2-t1))
13440         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13441         sleep 2
13442         # wait for commitment of removal
13443         lru_resize_enable mdc
13444         lru_resize_enable osc
13445 }
13446 run_test 120g "Early Lock Cancel: performance test"
13447
13448 test_121() { #bug #10589
13449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13450
13451         rm -rf $DIR/$tfile
13452         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13453 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13454         lctl set_param fail_loc=0x310
13455         cancel_lru_locks osc > /dev/null
13456         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13457         lctl set_param fail_loc=0
13458         [[ $reads -eq $writes ]] ||
13459                 error "read $reads blocks, must be $writes blocks"
13460 }
13461 run_test 121 "read cancel race ========="
13462
13463 test_123a_base() { # was test 123, statahead(bug 11401)
13464         local lsx="$1"
13465
13466         SLOWOK=0
13467         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13468                 log "testing UP system. Performance may be lower than expected."
13469                 SLOWOK=1
13470         fi
13471         running_in_vm && SLOWOK=1
13472
13473         rm -rf $DIR/$tdir
13474         test_mkdir $DIR/$tdir
13475         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13476         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13477         MULT=10
13478         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13479                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13480
13481                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13482                 lctl set_param -n llite.*.statahead_max 0
13483                 lctl get_param llite.*.statahead_max
13484                 cancel_lru_locks mdc
13485                 cancel_lru_locks osc
13486                 stime=$(date +%s)
13487                 time $lsx $DIR/$tdir | wc -l
13488                 etime=$(date +%s)
13489                 delta=$((etime - stime))
13490                 log "$lsx $i files without statahead: $delta sec"
13491                 lctl set_param llite.*.statahead_max=$max
13492
13493                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13494                          awk '/statahead.wrong:/ { print $NF }')
13495                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13496                 cancel_lru_locks mdc
13497                 cancel_lru_locks osc
13498                 stime=$(date +%s)
13499                 time $lsx $DIR/$tdir | wc -l
13500                 etime=$(date +%s)
13501                 delta_sa=$((etime - stime))
13502                 log "$lsx $i files with statahead: $delta_sa sec"
13503                 lctl get_param -n llite.*.statahead_stats
13504                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13505                          awk '/statahead.wrong:/ { print $NF }')
13506
13507                 [[ $swrong -lt $ewrong ]] &&
13508                         log "statahead was stopped, maybe too many locks held!"
13509                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13510
13511                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13512                         max=$(lctl get_param -n llite.*.statahead_max |
13513                                 head -n 1)
13514                         lctl set_param -n llite.*.statahead_max 0
13515                         lctl get_param llite.*.statahead_max
13516                         cancel_lru_locks mdc
13517                         cancel_lru_locks osc
13518                         stime=$(date +%s)
13519                         time $lsx $DIR/$tdir | wc -l
13520                         etime=$(date +%s)
13521                         delta=$((etime - stime))
13522                         log "$lsx $i files again without statahead: $delta sec"
13523                         lctl set_param llite.*.statahead_max=$max
13524                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13525                                 if [ $SLOWOK -eq 0 ]; then
13526                                         error "$lsx $i files is slower with statahead!"
13527                                 else
13528                                         log "$lsx $i files is slower with statahead!"
13529                                 fi
13530                                 break
13531                         fi
13532                 fi
13533
13534                 [ $delta -gt 20 ] && break
13535                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13536                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13537         done
13538         log "$lsx done"
13539
13540         stime=$(date +%s)
13541         rm -r $DIR/$tdir
13542         sync
13543         etime=$(date +%s)
13544         delta=$((etime - stime))
13545         log "rm -r $DIR/$tdir/: $delta seconds"
13546         log "rm done"
13547         lctl get_param -n llite.*.statahead_stats
13548 }
13549
13550 test_123aa() {
13551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13552
13553         test_123a_base "ls -l"
13554 }
13555 run_test 123aa "verify statahead work"
13556
13557 test_123ab() {
13558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13559
13560         statx_supported || skip_env "Test must be statx() syscall supported"
13561
13562         test_123a_base "$STATX -l"
13563 }
13564 run_test 123ab "verify statahead work by using statx"
13565
13566 test_123ac() {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568
13569         statx_supported || skip_env "Test must be statx() syscall supported"
13570
13571         local rpcs_before
13572         local rpcs_after
13573         local agl_before
13574         local agl_after
13575
13576         cancel_lru_locks $OSC
13577         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13578         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13579                      awk '/agl.total:/ { print $NF }')
13580         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13581         test_123a_base "$STATX --cached=always -D"
13582         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13583                     awk '/agl.total:/ { print $NF }')
13584         [ $agl_before -eq $agl_after ] ||
13585                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13586         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13587         [ $rpcs_after -eq $rpcs_before ] ||
13588                 error "$STATX should not send glimpse RPCs to $OSC"
13589 }
13590 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13591
13592 test_123b () { # statahead(bug 15027)
13593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13594
13595         test_mkdir $DIR/$tdir
13596         createmany -o $DIR/$tdir/$tfile-%d 1000
13597
13598         cancel_lru_locks mdc
13599         cancel_lru_locks osc
13600
13601 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13602         lctl set_param fail_loc=0x80000803
13603         ls -lR $DIR/$tdir > /dev/null
13604         log "ls done"
13605         lctl set_param fail_loc=0x0
13606         lctl get_param -n llite.*.statahead_stats
13607         rm -r $DIR/$tdir
13608         sync
13609
13610 }
13611 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13612
13613 test_123c() {
13614         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13615
13616         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13617         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13618         touch $DIR/$tdir.1/{1..3}
13619         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13620
13621         remount_client $MOUNT
13622
13623         $MULTIOP $DIR/$tdir.0 Q
13624
13625         # let statahead to complete
13626         ls -l $DIR/$tdir.0 > /dev/null
13627
13628         testid=$(echo $TESTNAME | tr '_' ' ')
13629         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13630                 error "statahead warning" || true
13631 }
13632 run_test 123c "Can not initialize inode warning on DNE statahead"
13633
13634 test_123d() {
13635         local num=100
13636         local swrong
13637         local ewrong
13638
13639         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13640         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13641                 error "setdirstripe $DIR/$tdir failed"
13642         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13643         remount_client $MOUNT
13644         $LCTL get_param llite.*.statahead_max
13645         $LCTL set_param llite.*.statahead_stats=0 ||
13646                 error "clear statahead_stats failed"
13647         swrong=$(lctl get_param -n llite.*.statahead_stats |
13648                  awk '/statahead.wrong:/ { print $NF }')
13649         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13650         # wait for statahead thread finished to update hit/miss stats.
13651         sleep 1
13652         $LCTL get_param -n llite.*.statahead_stats
13653         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13654                  awk '/statahead.wrong:/ { print $NF }')
13655         (( $swrong == $ewrong )) ||
13656                 log "statahead was stopped, maybe too many locks held!"
13657 }
13658 run_test 123d "Statahead on striped directories works correctly"
13659
13660 test_124a() {
13661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13662         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13663                 skip_env "no lru resize on server"
13664
13665         local NR=2000
13666
13667         test_mkdir $DIR/$tdir
13668
13669         log "create $NR files at $DIR/$tdir"
13670         createmany -o $DIR/$tdir/f $NR ||
13671                 error "failed to create $NR files in $DIR/$tdir"
13672
13673         cancel_lru_locks mdc
13674         ls -l $DIR/$tdir > /dev/null
13675
13676         local NSDIR=""
13677         local LRU_SIZE=0
13678         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13679                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13680                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13681                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13682                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13683                         log "NSDIR=$NSDIR"
13684                         log "NS=$(basename $NSDIR)"
13685                         break
13686                 fi
13687         done
13688
13689         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13690                 skip "Not enough cached locks created!"
13691         fi
13692         log "LRU=$LRU_SIZE"
13693
13694         local SLEEP=30
13695
13696         # We know that lru resize allows one client to hold $LIMIT locks
13697         # for 10h. After that locks begin to be killed by client.
13698         local MAX_HRS=10
13699         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13700         log "LIMIT=$LIMIT"
13701         if [ $LIMIT -lt $LRU_SIZE ]; then
13702                 skip "Limit is too small $LIMIT"
13703         fi
13704
13705         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13706         # killing locks. Some time was spent for creating locks. This means
13707         # that up to the moment of sleep finish we must have killed some of
13708         # them (10-100 locks). This depends on how fast ther were created.
13709         # Many of them were touched in almost the same moment and thus will
13710         # be killed in groups.
13711         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13712
13713         # Use $LRU_SIZE_B here to take into account real number of locks
13714         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13715         local LRU_SIZE_B=$LRU_SIZE
13716         log "LVF=$LVF"
13717         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13718         log "OLD_LVF=$OLD_LVF"
13719         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13720
13721         # Let's make sure that we really have some margin. Client checks
13722         # cached locks every 10 sec.
13723         SLEEP=$((SLEEP+20))
13724         log "Sleep ${SLEEP} sec"
13725         local SEC=0
13726         while ((SEC<$SLEEP)); do
13727                 echo -n "..."
13728                 sleep 5
13729                 SEC=$((SEC+5))
13730                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13731                 echo -n "$LRU_SIZE"
13732         done
13733         echo ""
13734         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13735         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13736
13737         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13738                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13739                 unlinkmany $DIR/$tdir/f $NR
13740                 return
13741         }
13742
13743         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13744         log "unlink $NR files at $DIR/$tdir"
13745         unlinkmany $DIR/$tdir/f $NR
13746 }
13747 run_test 124a "lru resize ======================================="
13748
13749 get_max_pool_limit()
13750 {
13751         local limit=$($LCTL get_param \
13752                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13753         local max=0
13754         for l in $limit; do
13755                 if [[ $l -gt $max ]]; then
13756                         max=$l
13757                 fi
13758         done
13759         echo $max
13760 }
13761
13762 test_124b() {
13763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13764         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13765                 skip_env "no lru resize on server"
13766
13767         LIMIT=$(get_max_pool_limit)
13768
13769         NR=$(($(default_lru_size)*20))
13770         if [[ $NR -gt $LIMIT ]]; then
13771                 log "Limit lock number by $LIMIT locks"
13772                 NR=$LIMIT
13773         fi
13774
13775         IFree=$(mdsrate_inodes_available)
13776         if [ $IFree -lt $NR ]; then
13777                 log "Limit lock number by $IFree inodes"
13778                 NR=$IFree
13779         fi
13780
13781         lru_resize_disable mdc
13782         test_mkdir -p $DIR/$tdir/disable_lru_resize
13783
13784         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13785         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13786         cancel_lru_locks mdc
13787         stime=`date +%s`
13788         PID=""
13789         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13790         PID="$PID $!"
13791         sleep 2
13792         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13793         PID="$PID $!"
13794         sleep 2
13795         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13796         PID="$PID $!"
13797         wait $PID
13798         etime=`date +%s`
13799         nolruresize_delta=$((etime-stime))
13800         log "ls -la time: $nolruresize_delta seconds"
13801         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13802         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13803
13804         lru_resize_enable mdc
13805         test_mkdir -p $DIR/$tdir/enable_lru_resize
13806
13807         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13808         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13809         cancel_lru_locks mdc
13810         stime=`date +%s`
13811         PID=""
13812         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13813         PID="$PID $!"
13814         sleep 2
13815         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13816         PID="$PID $!"
13817         sleep 2
13818         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13819         PID="$PID $!"
13820         wait $PID
13821         etime=`date +%s`
13822         lruresize_delta=$((etime-stime))
13823         log "ls -la time: $lruresize_delta seconds"
13824         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13825
13826         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13827                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13828         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13829                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13830         else
13831                 log "lru resize performs the same with no lru resize"
13832         fi
13833         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13834 }
13835 run_test 124b "lru resize (performance test) ======================="
13836
13837 test_124c() {
13838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13839         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13840                 skip_env "no lru resize on server"
13841
13842         # cache ununsed locks on client
13843         local nr=100
13844         cancel_lru_locks mdc
13845         test_mkdir $DIR/$tdir
13846         createmany -o $DIR/$tdir/f $nr ||
13847                 error "failed to create $nr files in $DIR/$tdir"
13848         ls -l $DIR/$tdir > /dev/null
13849
13850         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13851         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13852         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13853         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13854         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13855
13856         # set lru_max_age to 1 sec
13857         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13858         echo "sleep $((recalc_p * 2)) seconds..."
13859         sleep $((recalc_p * 2))
13860
13861         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13862         # restore lru_max_age
13863         $LCTL set_param -n $nsdir.lru_max_age $max_age
13864         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13865         unlinkmany $DIR/$tdir/f $nr
13866 }
13867 run_test 124c "LRUR cancel very aged locks"
13868
13869 test_124d() {
13870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13871         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13872                 skip_env "no lru resize on server"
13873
13874         # cache ununsed locks on client
13875         local nr=100
13876
13877         lru_resize_disable mdc
13878         stack_trap "lru_resize_enable mdc" EXIT
13879
13880         cancel_lru_locks mdc
13881
13882         # asynchronous object destroy at MDT could cause bl ast to client
13883         test_mkdir $DIR/$tdir
13884         createmany -o $DIR/$tdir/f $nr ||
13885                 error "failed to create $nr files in $DIR/$tdir"
13886         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13887
13888         ls -l $DIR/$tdir > /dev/null
13889
13890         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13891         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13892         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13893         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13894
13895         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13896
13897         # set lru_max_age to 1 sec
13898         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13899         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13900
13901         echo "sleep $((recalc_p * 2)) seconds..."
13902         sleep $((recalc_p * 2))
13903
13904         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13905
13906         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13907 }
13908 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13909
13910 test_125() { # 13358
13911         $LCTL get_param -n llite.*.client_type | grep -q local ||
13912                 skip "must run as local client"
13913         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13914                 skip_env "must have acl enabled"
13915         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13916
13917         test_mkdir $DIR/$tdir
13918         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13919         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13920                 error "setfacl $DIR/$tdir failed"
13921         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13922 }
13923 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13924
13925 test_126() { # bug 12829/13455
13926         $GSS && skip_env "must run as gss disabled"
13927         $LCTL get_param -n llite.*.client_type | grep -q local ||
13928                 skip "must run as local client"
13929         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13930
13931         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13932         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13933         rm -f $DIR/$tfile
13934         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13935 }
13936 run_test 126 "check that the fsgid provided by the client is taken into account"
13937
13938 test_127a() { # bug 15521
13939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13940         local name count samp unit min max sum sumsq
13941         local tmpfile=$TMP/$tfile.tmp
13942
13943         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13944         echo "stats before reset"
13945         stack_trap "rm -f $tmpfile"
13946         local now=$(date +%s)
13947
13948         $LCTL get_param osc.*.stats | tee $tmpfile
13949
13950         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13951         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13952         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13953         local uptime=$(awk '{ print $1 }' /proc/uptime)
13954
13955         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13956         (( ${snapshot_time%\.*} >= $now - 5 &&
13957            ${snapshot_time%\.*} <= $now + 5 )) ||
13958                 error "snapshot_time=$snapshot_time != now=$now"
13959         # elapsed _should_ be from mount, but at least less than uptime
13960         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13961                 error "elapsed=$elapsed > uptime=$uptime"
13962         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13963            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13964                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13965
13966         $LCTL set_param osc.*.stats=0
13967         local reset=$(date +%s)
13968         local fsize=$((2048 * 1024))
13969
13970         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13971         cancel_lru_locks osc
13972         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13973
13974         now=$(date +%s)
13975         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13976         while read name count samp unit min max sum sumsq; do
13977                 [[ "$samp" == "samples" ]] || continue
13978
13979                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13980                 [ ! $min ] && error "Missing min value for $name proc entry"
13981                 eval $name=$count || error "Wrong proc format"
13982
13983                 case $name in
13984                 read_bytes|write_bytes)
13985                         [[ "$unit" =~ "bytes" ]] ||
13986                                 error "unit is not 'bytes': $unit"
13987                         (( $min >= 4096 )) || error "min is too small: $min"
13988                         (( $min <= $fsize )) || error "min is too big: $min"
13989                         (( $max >= 4096 )) || error "max is too small: $max"
13990                         (( $max <= $fsize )) || error "max is too big: $max"
13991                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13992                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13993                                 error "sumsquare is too small: $sumsq"
13994                         (( $sumsq <= $fsize * $fsize )) ||
13995                                 error "sumsquare is too big: $sumsq"
13996                         ;;
13997                 ost_read|ost_write)
13998                         [[ "$unit" =~ "usec" ]] ||
13999                                 error "unit is not 'usec': $unit"
14000                         ;;
14001                 *)      ;;
14002                 esac
14003         done < $tmpfile
14004
14005         #check that we actually got some stats
14006         [ "$read_bytes" ] || error "Missing read_bytes stats"
14007         [ "$write_bytes" ] || error "Missing write_bytes stats"
14008         [ "$read_bytes" != 0 ] || error "no read done"
14009         [ "$write_bytes" != 0 ] || error "no write done"
14010
14011         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14012         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14013         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14014
14015         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14016         (( ${snapshot_time%\.*} >= $now - 5 &&
14017            ${snapshot_time%\.*} <= $now + 5 )) ||
14018                 error "reset snapshot_time=$snapshot_time != now=$now"
14019         # elapsed should be from time of stats reset
14020         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14021            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14022                 error "reset elapsed=$elapsed > $now - $reset"
14023         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14024            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14025                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14026 }
14027 run_test 127a "verify the client stats are sane"
14028
14029 test_127b() { # bug LU-333
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031         local name count samp unit min max sum sumsq
14032
14033         echo "stats before reset"
14034         $LCTL get_param llite.*.stats
14035         $LCTL set_param llite.*.stats=0
14036
14037         # perform 2 reads and writes so MAX is different from SUM.
14038         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14039         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14040         cancel_lru_locks osc
14041         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14042         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14043
14044         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14045         stack_trap "rm -f $TMP/$tfile.tmp"
14046         while read name count samp unit min max sum sumsq; do
14047                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14048                 eval $name=$count || error "Wrong proc format"
14049
14050                 case $name in
14051                 read_bytes|write_bytes)
14052                         [[ "$unit" =~ "bytes" ]] ||
14053                                 error "unit is not 'bytes': $unit"
14054                         (( $count == 2 )) || error "count is not 2: $count"
14055                         (( $min == $PAGE_SIZE )) ||
14056                                 error "min is not $PAGE_SIZE: $min"
14057                         (( $max == $PAGE_SIZE )) ||
14058                                 error "max is not $PAGE_SIZE: $max"
14059                         (( $sum == $PAGE_SIZE * 2 )) ||
14060                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14061                         ;;
14062                 read|write)
14063                         [[ "$unit" =~ "usec" ]] ||
14064                                 error "unit is not 'usec': $unit"
14065                         ;;
14066                 *)      ;;
14067                 esac
14068         done < $TMP/$tfile.tmp
14069
14070         #check that we actually got some stats
14071         [ "$read_bytes" ] || error "Missing read_bytes stats"
14072         [ "$write_bytes" ] || error "Missing write_bytes stats"
14073         [ "$read_bytes" != 0 ] || error "no read done"
14074         [ "$write_bytes" != 0 ] || error "no write done"
14075 }
14076 run_test 127b "verify the llite client stats are sane"
14077
14078 test_127c() { # LU-12394
14079         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14080         local size
14081         local bsize
14082         local reads
14083         local writes
14084         local count
14085
14086         $LCTL set_param llite.*.extents_stats=1
14087         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14088
14089         # Use two stripes so there is enough space in default config
14090         $LFS setstripe -c 2 $DIR/$tfile
14091
14092         # Extent stats start at 0-4K and go in power of two buckets
14093         # LL_HIST_START = 12 --> 2^12 = 4K
14094         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14095         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14096         # small configs
14097         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14098                 do
14099                 # Write and read, 2x each, second time at a non-zero offset
14100                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14101                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14102                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14103                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14104                 rm -f $DIR/$tfile
14105         done
14106
14107         $LCTL get_param llite.*.extents_stats
14108
14109         count=2
14110         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14111                 do
14112                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14113                                 grep -m 1 $bsize)
14114                 reads=$(echo $bucket | awk '{print $5}')
14115                 writes=$(echo $bucket | awk '{print $9}')
14116                 [ "$reads" -eq $count ] ||
14117                         error "$reads reads in < $bsize bucket, expect $count"
14118                 [ "$writes" -eq $count ] ||
14119                         error "$writes writes in < $bsize bucket, expect $count"
14120         done
14121
14122         # Test mmap write and read
14123         $LCTL set_param llite.*.extents_stats=c
14124         size=512
14125         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14126         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14127         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14128
14129         $LCTL get_param llite.*.extents_stats
14130
14131         count=$(((size*1024) / PAGE_SIZE))
14132
14133         bsize=$((2 * PAGE_SIZE / 1024))K
14134
14135         bucket=$($LCTL get_param -n llite.*.extents_stats |
14136                         grep -m 1 $bsize)
14137         reads=$(echo $bucket | awk '{print $5}')
14138         writes=$(echo $bucket | awk '{print $9}')
14139         # mmap writes fault in the page first, creating an additonal read
14140         [ "$reads" -eq $((2 * count)) ] ||
14141                 error "$reads reads in < $bsize bucket, expect $count"
14142         [ "$writes" -eq $count ] ||
14143                 error "$writes writes in < $bsize bucket, expect $count"
14144 }
14145 run_test 127c "test llite extent stats with regular & mmap i/o"
14146
14147 test_128() { # bug 15212
14148         touch $DIR/$tfile
14149         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14150                 find $DIR/$tfile
14151                 find $DIR/$tfile
14152         EOF
14153
14154         result=$(grep error $TMP/$tfile.log)
14155         rm -f $DIR/$tfile $TMP/$tfile.log
14156         [ -z "$result" ] ||
14157                 error "consecutive find's under interactive lfs failed"
14158 }
14159 run_test 128 "interactive lfs for 2 consecutive find's"
14160
14161 set_dir_limits () {
14162         local mntdev
14163         local canondev
14164         local node
14165
14166         local ldproc=/proc/fs/ldiskfs
14167         local facets=$(get_facets MDS)
14168
14169         for facet in ${facets//,/ }; do
14170                 canondev=$(ldiskfs_canon \
14171                            *.$(convert_facet2label $facet).mntdev $facet)
14172                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14173                         ldproc=/sys/fs/ldiskfs
14174                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14175                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14176         done
14177 }
14178
14179 check_mds_dmesg() {
14180         local facets=$(get_facets MDS)
14181         for facet in ${facets//,/ }; do
14182                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14183         done
14184         return 1
14185 }
14186
14187 test_129() {
14188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14189         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14190                 skip "Need MDS version with at least 2.5.56"
14191         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14192                 skip_env "ldiskfs only test"
14193         fi
14194         remote_mds_nodsh && skip "remote MDS with nodsh"
14195
14196         local ENOSPC=28
14197         local has_warning=false
14198
14199         rm -rf $DIR/$tdir
14200         mkdir -p $DIR/$tdir
14201
14202         # block size of mds1
14203         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14204         set_dir_limits $maxsize $((maxsize * 6 / 8))
14205         stack_trap "set_dir_limits 0 0"
14206         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14207         local dirsize=$(stat -c%s "$DIR/$tdir")
14208         local nfiles=0
14209         while (( $dirsize <= $maxsize )); do
14210                 $MCREATE $DIR/$tdir/file_base_$nfiles
14211                 rc=$?
14212                 # check two errors:
14213                 # ENOSPC for ext4 max_dir_size, which has been used since
14214                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14215                 if (( rc == ENOSPC )); then
14216                         set_dir_limits 0 0
14217                         echo "rc=$rc returned as expected after $nfiles files"
14218
14219                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14220                                 error "create failed w/o dir size limit"
14221
14222                         # messages may be rate limited if test is run repeatedly
14223                         check_mds_dmesg '"is approaching max"' ||
14224                                 echo "warning message should be output"
14225                         check_mds_dmesg '"has reached max"' ||
14226                                 echo "reached message should be output"
14227
14228                         dirsize=$(stat -c%s "$DIR/$tdir")
14229
14230                         [[ $dirsize -ge $maxsize ]] && return 0
14231                         error "dirsize $dirsize < $maxsize after $nfiles files"
14232                 elif (( rc != 0 )); then
14233                         break
14234                 fi
14235                 nfiles=$((nfiles + 1))
14236                 dirsize=$(stat -c%s "$DIR/$tdir")
14237         done
14238
14239         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14240 }
14241 run_test 129 "test directory size limit ========================"
14242
14243 OLDIFS="$IFS"
14244 cleanup_130() {
14245         trap 0
14246         IFS="$OLDIFS"
14247 }
14248
14249 test_130a() {
14250         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14251         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14252
14253         trap cleanup_130 EXIT RETURN
14254
14255         local fm_file=$DIR/$tfile
14256         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14257         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14258                 error "dd failed for $fm_file"
14259
14260         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14261         filefrag -ves $fm_file
14262         local rc=$?
14263         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14264                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14265         (( $rc == 0 )) || error "filefrag $fm_file failed"
14266
14267         filefrag_op=$(filefrag -ve -k $fm_file |
14268                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14269         local lun=$($LFS getstripe -i $fm_file)
14270
14271         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14272         IFS=$'\n'
14273         local tot_len=0
14274         for line in $filefrag_op; do
14275                 local frag_lun=$(echo $line | cut -d: -f5)
14276                 local ext_len=$(echo $line | cut -d: -f4)
14277
14278                 if (( $frag_lun != $lun )); then
14279                         error "FIEMAP on 1-stripe file($fm_file) failed"
14280                         return
14281                 fi
14282                 (( tot_len += ext_len ))
14283         done
14284
14285         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14286                 error "FIEMAP on 1-stripe file($fm_file) failed"
14287                 return
14288         fi
14289
14290         echo "FIEMAP on single striped file succeeded"
14291 }
14292 run_test 130a "FIEMAP (1-stripe file)"
14293
14294 test_130b() {
14295         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14296
14297         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14298         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14299         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14300                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14301
14302         trap cleanup_130 EXIT RETURN
14303
14304         local fm_file=$DIR/$tfile
14305         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14306                 error "setstripe on $fm_file"
14307
14308         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14309                 error "dd failed on $fm_file"
14310
14311         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14312         filefrag_op=$(filefrag -ve -k $fm_file |
14313                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14314
14315         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14316                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14317
14318         IFS=$'\n'
14319         local tot_len=0
14320         local num_luns=1
14321
14322         for line in $filefrag_op; do
14323                 local frag_lun=$(echo $line | cut -d: -f5 |
14324                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14325                 local ext_len=$(echo $line | cut -d: -f4)
14326                 if (( $frag_lun != $last_lun )); then
14327                         if (( tot_len != 1024 )); then
14328                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14329                                 return
14330                         else
14331                                 (( num_luns += 1 ))
14332                                 tot_len=0
14333                         fi
14334                 fi
14335                 (( tot_len += ext_len ))
14336                 last_lun=$frag_lun
14337         done
14338         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14339                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14340                 return
14341         fi
14342
14343         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14344 }
14345 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14346
14347 test_130c() {
14348         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14349
14350         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14351         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14352         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14353                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14354
14355         trap cleanup_130 EXIT RETURN
14356
14357         local fm_file=$DIR/$tfile
14358         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14359
14360         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14361                 error "dd failed on $fm_file"
14362
14363         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14364         filefrag_op=$(filefrag -ve -k $fm_file |
14365                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14366
14367         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14368                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14369
14370         IFS=$'\n'
14371         local tot_len=0
14372         local num_luns=1
14373         for line in $filefrag_op; do
14374                 local frag_lun=$(echo $line | cut -d: -f5 |
14375                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14376                 local ext_len=$(echo $line | cut -d: -f4)
14377                 if (( $frag_lun != $last_lun )); then
14378                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14379                         if (( logical != 512 )); then
14380                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14381                                 return
14382                         fi
14383                         if (( tot_len != 512 )); then
14384                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14385                                 return
14386                         else
14387                                 (( num_luns += 1 ))
14388                                 tot_len=0
14389                         fi
14390                 fi
14391                 (( tot_len += ext_len ))
14392                 last_lun=$frag_lun
14393         done
14394         if (( num_luns != 2 || tot_len != 512 )); then
14395                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14396                 return
14397         fi
14398
14399         echo "FIEMAP on 2-stripe file with hole succeeded"
14400 }
14401 run_test 130c "FIEMAP (2-stripe file with hole)"
14402
14403 test_130d() {
14404         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14405
14406         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14407         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14408         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14409                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14410
14411         trap cleanup_130 EXIT RETURN
14412
14413         local fm_file=$DIR/$tfile
14414         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14415                         error "setstripe on $fm_file"
14416
14417         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14418         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14419                 error "dd failed on $fm_file"
14420
14421         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14422         filefrag_op=$(filefrag -ve -k $fm_file |
14423                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14424
14425         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14426                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14427
14428         IFS=$'\n'
14429         local tot_len=0
14430         local num_luns=1
14431         for line in $filefrag_op; do
14432                 local frag_lun=$(echo $line | cut -d: -f5 |
14433                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14434                 local ext_len=$(echo $line | cut -d: -f4)
14435                 if (( $frag_lun != $last_lun )); then
14436                         if (( tot_len != 1024 )); then
14437                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14438                                 return
14439                         else
14440                                 (( num_luns += 1 ))
14441                                 local tot_len=0
14442                         fi
14443                 fi
14444                 (( tot_len += ext_len ))
14445                 last_lun=$frag_lun
14446         done
14447         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14448                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14449                 return
14450         fi
14451
14452         echo "FIEMAP on N-stripe file succeeded"
14453 }
14454 run_test 130d "FIEMAP (N-stripe file)"
14455
14456 test_130e() {
14457         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14458
14459         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14460         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14461         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14462                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14463
14464         trap cleanup_130 EXIT RETURN
14465
14466         local fm_file=$DIR/$tfile
14467         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14468
14469         local num_blks=512
14470         local expected_len=$(( (num_blks / 2) * 64 ))
14471         for ((i = 0; i < $num_blks; i++)); do
14472                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14473                         conv=notrunc > /dev/null 2>&1
14474         done
14475
14476         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14477         filefrag_op=$(filefrag -ve -k $fm_file |
14478                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14479
14480         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14481
14482         IFS=$'\n'
14483         local tot_len=0
14484         local num_luns=1
14485         for line in $filefrag_op; do
14486                 local frag_lun=$(echo $line | cut -d: -f5)
14487                 local ext_len=$(echo $line | cut -d: -f4)
14488                 if (( $frag_lun != $last_lun )); then
14489                         if (( tot_len != $expected_len )); then
14490                                 error "OST$last_lun $tot_len != $expected_len"
14491                         else
14492                                 (( num_luns += 1 ))
14493                                 tot_len=0
14494                         fi
14495                 fi
14496                 (( tot_len += ext_len ))
14497                 last_lun=$frag_lun
14498         done
14499         if (( num_luns != 2 || tot_len != $expected_len )); then
14500                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14501         fi
14502
14503         echo "FIEMAP with continuation calls succeeded"
14504 }
14505 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14506
14507 test_130f() {
14508         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14509         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14510         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14511                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14512
14513         local fm_file=$DIR/$tfile
14514         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14515                 error "multiop create with lov_delay_create on $fm_file"
14516
14517         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14518         filefrag_extents=$(filefrag -vek $fm_file |
14519                            awk '/extents? found/ { print $2 }')
14520         if (( $filefrag_extents != 0 )); then
14521                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14522         fi
14523
14524         rm -f $fm_file
14525 }
14526 run_test 130f "FIEMAP (unstriped file)"
14527
14528 test_130g() {
14529         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14530                 skip "Need MDS version with at least 2.12.53 for overstriping"
14531         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14532         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14533         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14534                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14535
14536         local file=$DIR/$tfile
14537         local nr=$((OSTCOUNT * 100))
14538
14539         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14540
14541         stack_trap "rm -f $file"
14542         dd if=/dev/zero of=$file count=$nr bs=1M
14543         sync
14544         nr=$($LFS getstripe -c $file)
14545
14546         local extents=$(filefrag -v $file |
14547                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14548
14549         echo "filefrag list $extents extents in file with stripecount $nr"
14550         if (( extents < nr )); then
14551                 $LFS getstripe $file
14552                 filefrag -v $file
14553                 error "filefrag printed $extents < $nr extents"
14554         fi
14555 }
14556 run_test 130g "FIEMAP (overstripe file)"
14557
14558 # Test for writev/readv
14559 test_131a() {
14560         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14561                 error "writev test failed"
14562         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14563                 error "readv failed"
14564         rm -f $DIR/$tfile
14565 }
14566 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14567
14568 test_131b() {
14569         local fsize=$((524288 + 1048576 + 1572864))
14570         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14571                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14572                         error "append writev test failed"
14573
14574         ((fsize += 1572864 + 1048576))
14575         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14576                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14577                         error "append writev test failed"
14578         rm -f $DIR/$tfile
14579 }
14580 run_test 131b "test append writev"
14581
14582 test_131c() {
14583         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14584         error "NOT PASS"
14585 }
14586 run_test 131c "test read/write on file w/o objects"
14587
14588 test_131d() {
14589         rwv -f $DIR/$tfile -w -n 1 1572864
14590         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14591         if [ "$NOB" != 1572864 ]; then
14592                 error "Short read filed: read $NOB bytes instead of 1572864"
14593         fi
14594         rm -f $DIR/$tfile
14595 }
14596 run_test 131d "test short read"
14597
14598 test_131e() {
14599         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14600         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14601         error "read hitting hole failed"
14602         rm -f $DIR/$tfile
14603 }
14604 run_test 131e "test read hitting hole"
14605
14606 check_stats() {
14607         local facet=$1
14608         local op=$2
14609         local want=${3:-0}
14610         local res
14611
14612         # open             11 samples [usecs] 468 4793 13658 35791898
14613         case $facet in
14614         mds*) res=($(do_facet $facet \
14615                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14616                  ;;
14617         ost*) res=($(do_facet $facet \
14618                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14619                  ;;
14620         *) error "Wrong facet '$facet'" ;;
14621         esac
14622         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14623         # if $want is zero, it means any stat increment is ok.
14624         if (( $want > 0 )); then
14625                 local count=${res[1]}
14626
14627                 if (( $count != $want )); then
14628                         if [[ $facet =~ "mds" ]]; then
14629                                 do_nodes $(comma_list $(mdts_nodes)) \
14630                                         $LCTL get_param mdt.*.md_stats
14631                         else
14632                                 do_nodes $(comma_list $(osts-nodes)) \
14633                                         $LCTL get_param obdfilter.*.stats
14634                         fi
14635                         error "The $op counter on $facet is $count, not $want"
14636                 fi
14637         fi
14638 }
14639
14640 test_133a() {
14641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14642         remote_ost_nodsh && skip "remote OST with nodsh"
14643         remote_mds_nodsh && skip "remote MDS with nodsh"
14644         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14645                 skip_env "MDS doesn't support rename stats"
14646
14647         local testdir=$DIR/${tdir}/stats_testdir
14648
14649         mkdir -p $DIR/${tdir}
14650
14651         # clear stats.
14652         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14653         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14654
14655         # verify mdt stats first.
14656         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14657         check_stats $SINGLEMDS "mkdir" 1
14658
14659         # clear "open" from "lfs mkdir" above
14660         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14661         touch ${testdir}/${tfile} || error "touch failed"
14662         check_stats $SINGLEMDS "open" 1
14663         check_stats $SINGLEMDS "close" 1
14664         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14665                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14666                 check_stats $SINGLEMDS "mknod" 2
14667         }
14668         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14669         check_stats $SINGLEMDS "unlink" 1
14670         rm -f ${testdir}/${tfile} || error "file remove failed"
14671         check_stats $SINGLEMDS "unlink" 2
14672
14673         # remove working dir and check mdt stats again.
14674         rmdir ${testdir} || error "rmdir failed"
14675         check_stats $SINGLEMDS "rmdir" 1
14676
14677         local testdir1=$DIR/${tdir}/stats_testdir1
14678         mkdir_on_mdt0 -p ${testdir}
14679         mkdir_on_mdt0 -p ${testdir1}
14680         touch ${testdir1}/test1
14681         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14682         check_stats $SINGLEMDS "crossdir_rename" 1
14683
14684         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14685         check_stats $SINGLEMDS "samedir_rename" 1
14686
14687         rm -rf $DIR/${tdir}
14688 }
14689 run_test 133a "Verifying MDT stats ========================================"
14690
14691 test_133b() {
14692         local res
14693
14694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14695         remote_ost_nodsh && skip "remote OST with nodsh"
14696         remote_mds_nodsh && skip "remote MDS with nodsh"
14697
14698         local testdir=$DIR/${tdir}/stats_testdir
14699
14700         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14701         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14702         touch ${testdir}/${tfile} || error "touch failed"
14703         cancel_lru_locks mdc
14704
14705         # clear stats.
14706         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14707         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14708
14709         # extra mdt stats verification.
14710         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14711         check_stats $SINGLEMDS "setattr" 1
14712         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14713         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14714         then            # LU-1740
14715                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14716                 check_stats $SINGLEMDS "getattr" 1
14717         fi
14718         rm -rf $DIR/${tdir}
14719
14720         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14721         # so the check below is not reliable
14722         [ $MDSCOUNT -eq 1 ] || return 0
14723
14724         # Sleep to avoid a cached response.
14725         #define OBD_STATFS_CACHE_SECONDS 1
14726         sleep 2
14727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14728         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14729         $LFS df || error "lfs failed"
14730         check_stats $SINGLEMDS "statfs" 1
14731
14732         # check aggregated statfs (LU-10018)
14733         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14734                 return 0
14735         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14736                 return 0
14737         sleep 2
14738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14739         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14740         df $DIR
14741         check_stats $SINGLEMDS "statfs" 1
14742
14743         # We want to check that the client didn't send OST_STATFS to
14744         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14745         # extra care is needed here.
14746         if remote_mds; then
14747                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14748                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14749
14750                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14751                 [ "$res" ] && error "OST got STATFS"
14752         fi
14753
14754         return 0
14755 }
14756 run_test 133b "Verifying extra MDT stats =================================="
14757
14758 test_133c() {
14759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14760         remote_ost_nodsh && skip "remote OST with nodsh"
14761         remote_mds_nodsh && skip "remote MDS with nodsh"
14762
14763         local testdir=$DIR/$tdir/stats_testdir
14764
14765         test_mkdir -p $testdir
14766
14767         # verify obdfilter stats.
14768         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14769         sync
14770         cancel_lru_locks osc
14771         wait_delete_completed
14772
14773         # clear stats.
14774         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14775         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14776
14777         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14778                 error "dd failed"
14779         sync
14780         cancel_lru_locks osc
14781         check_stats ost1 "write" 1
14782
14783         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14784         check_stats ost1 "read" 1
14785
14786         > $testdir/$tfile || error "truncate failed"
14787         check_stats ost1 "punch" 1
14788
14789         rm -f $testdir/$tfile || error "file remove failed"
14790         wait_delete_completed
14791         check_stats ost1 "destroy" 1
14792
14793         rm -rf $DIR/$tdir
14794 }
14795 run_test 133c "Verifying OST stats ========================================"
14796
14797 order_2() {
14798         local value=$1
14799         local orig=$value
14800         local order=1
14801
14802         while [ $value -ge 2 ]; do
14803                 order=$((order*2))
14804                 value=$((value/2))
14805         done
14806
14807         if [ $orig -gt $order ]; then
14808                 order=$((order*2))
14809         fi
14810         echo $order
14811 }
14812
14813 size_in_KMGT() {
14814     local value=$1
14815     local size=('K' 'M' 'G' 'T');
14816     local i=0
14817     local size_string=$value
14818
14819     while [ $value -ge 1024 ]; do
14820         if [ $i -gt 3 ]; then
14821             #T is the biggest unit we get here, if that is bigger,
14822             #just return XXXT
14823             size_string=${value}T
14824             break
14825         fi
14826         value=$((value >> 10))
14827         if [ $value -lt 1024 ]; then
14828             size_string=${value}${size[$i]}
14829             break
14830         fi
14831         i=$((i + 1))
14832     done
14833
14834     echo $size_string
14835 }
14836
14837 get_rename_size() {
14838         local size=$1
14839         local context=${2:-.}
14840         local sample=$(do_facet $SINGLEMDS $LCTL \
14841                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14842                 grep -A1 $context |
14843                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14844         echo $sample
14845 }
14846
14847 test_133d() {
14848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14849         remote_ost_nodsh && skip "remote OST with nodsh"
14850         remote_mds_nodsh && skip "remote MDS with nodsh"
14851         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14852                 skip_env "MDS doesn't support rename stats"
14853
14854         local testdir1=$DIR/${tdir}/stats_testdir1
14855         local testdir2=$DIR/${tdir}/stats_testdir2
14856         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14857
14858         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14859
14860         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14861         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14862
14863         createmany -o $testdir1/test 512 || error "createmany failed"
14864
14865         # check samedir rename size
14866         mv ${testdir1}/test0 ${testdir1}/test_0
14867
14868         local testdir1_size=$(ls -l $DIR/${tdir} |
14869                 awk '/stats_testdir1/ {print $5}')
14870         local testdir2_size=$(ls -l $DIR/${tdir} |
14871                 awk '/stats_testdir2/ {print $5}')
14872
14873         testdir1_size=$(order_2 $testdir1_size)
14874         testdir2_size=$(order_2 $testdir2_size)
14875
14876         testdir1_size=$(size_in_KMGT $testdir1_size)
14877         testdir2_size=$(size_in_KMGT $testdir2_size)
14878
14879         echo "source rename dir size: ${testdir1_size}"
14880         echo "target rename dir size: ${testdir2_size}"
14881
14882         local cmd="do_facet $SINGLEMDS $LCTL "
14883         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14884
14885         eval $cmd || error "$cmd failed"
14886         local samedir=$($cmd | grep 'same_dir')
14887         local same_sample=$(get_rename_size $testdir1_size)
14888         [ -z "$samedir" ] && error "samedir_rename_size count error"
14889         [[ $same_sample -eq 1 ]] ||
14890                 error "samedir_rename_size error $same_sample"
14891         echo "Check same dir rename stats success"
14892
14893         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14894
14895         # check crossdir rename size
14896         mv ${testdir1}/test_0 ${testdir2}/test_0
14897
14898         testdir1_size=$(ls -l $DIR/${tdir} |
14899                 awk '/stats_testdir1/ {print $5}')
14900         testdir2_size=$(ls -l $DIR/${tdir} |
14901                 awk '/stats_testdir2/ {print $5}')
14902
14903         testdir1_size=$(order_2 $testdir1_size)
14904         testdir2_size=$(order_2 $testdir2_size)
14905
14906         testdir1_size=$(size_in_KMGT $testdir1_size)
14907         testdir2_size=$(size_in_KMGT $testdir2_size)
14908
14909         echo "source rename dir size: ${testdir1_size}"
14910         echo "target rename dir size: ${testdir2_size}"
14911
14912         eval $cmd || error "$cmd failed"
14913         local crossdir=$($cmd | grep 'crossdir')
14914         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14915         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14916         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14917         [[ $src_sample -eq 1 ]] ||
14918                 error "crossdir_rename_size error $src_sample"
14919         [[ $tgt_sample -eq 1 ]] ||
14920                 error "crossdir_rename_size error $tgt_sample"
14921         echo "Check cross dir rename stats success"
14922         rm -rf $DIR/${tdir}
14923 }
14924 run_test 133d "Verifying rename_stats ========================================"
14925
14926 test_133e() {
14927         remote_mds_nodsh && skip "remote MDS with nodsh"
14928         remote_ost_nodsh && skip "remote OST with nodsh"
14929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14930
14931         local testdir=$DIR/${tdir}/stats_testdir
14932         local ctr f0 f1 bs=32768 count=42 sum
14933
14934         mkdir -p ${testdir} || error "mkdir failed"
14935
14936         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14937
14938         for ctr in {write,read}_bytes; do
14939                 sync
14940                 cancel_lru_locks osc
14941
14942                 do_facet ost1 $LCTL set_param -n \
14943                         "obdfilter.*.exports.clear=clear"
14944
14945                 if [ $ctr = write_bytes ]; then
14946                         f0=/dev/zero
14947                         f1=${testdir}/${tfile}
14948                 else
14949                         f0=${testdir}/${tfile}
14950                         f1=/dev/null
14951                 fi
14952
14953                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14954                         error "dd failed"
14955                 sync
14956                 cancel_lru_locks osc
14957
14958                 sum=$(do_facet ost1 $LCTL get_param \
14959                         "obdfilter.*.exports.*.stats" |
14960                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14961                                 $1 == ctr { sum += $7 }
14962                                 END { printf("%0.0f", sum) }')
14963
14964                 if ((sum != bs * count)); then
14965                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14966                 fi
14967         done
14968
14969         rm -rf $DIR/${tdir}
14970 }
14971 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14972
14973 test_133f() {
14974         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14975                 skip "too old lustre for get_param -R ($facet_ver)"
14976
14977         # verifying readability.
14978         $LCTL get_param -R '*' &> /dev/null
14979
14980         # Verifing writability with badarea_io.
14981         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14982         local skipped_params='force_lbug|changelog_mask|daemon_file'
14983         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14984                 egrep -v "$skipped_params" |
14985                 xargs -n 1 find $proc_dirs -name |
14986                 xargs -n 1 badarea_io ||
14987                 error "client badarea_io failed"
14988
14989         # remount the FS in case writes/reads /proc break the FS
14990         cleanup || error "failed to unmount"
14991         setup || error "failed to setup"
14992 }
14993 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14994
14995 test_133g() {
14996         remote_mds_nodsh && skip "remote MDS with nodsh"
14997         remote_ost_nodsh && skip "remote OST with nodsh"
14998
14999         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15000         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15001         local facet
15002         for facet in mds1 ost1; do
15003                 local facet_ver=$(lustre_version_code $facet)
15004                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15005                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15006                 else
15007                         log "$facet: too old lustre for get_param -R"
15008                 fi
15009                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15010                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15011                                 tr -d = | egrep -v $skipped_params |
15012                                 xargs -n 1 find $proc_dirs -name |
15013                                 xargs -n 1 badarea_io" ||
15014                                         error "$facet badarea_io failed"
15015                 else
15016                         skip_noexit "$facet: too old lustre for get_param -R"
15017                 fi
15018         done
15019
15020         # remount the FS in case writes/reads /proc break the FS
15021         cleanup || error "failed to unmount"
15022         setup || error "failed to setup"
15023 }
15024 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15025
15026 test_133h() {
15027         remote_mds_nodsh && skip "remote MDS with nodsh"
15028         remote_ost_nodsh && skip "remote OST with nodsh"
15029         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15030                 skip "Need MDS version at least 2.9.54"
15031
15032         local facet
15033         for facet in client mds1 ost1; do
15034                 # Get the list of files that are missing the terminating newline
15035                 local plist=$(do_facet $facet
15036                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15037                 local ent
15038                 for ent in $plist; do
15039                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15040                                 awk -v FS='\v' -v RS='\v\v' \
15041                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15042                                         print FILENAME}'" 2>/dev/null)
15043                         [ -z $missing ] || {
15044                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15045                                 error "file does not end with newline: $facet-$ent"
15046                         }
15047                 done
15048         done
15049 }
15050 run_test 133h "Proc files should end with newlines"
15051
15052 test_134a() {
15053         remote_mds_nodsh && skip "remote MDS with nodsh"
15054         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15055                 skip "Need MDS version at least 2.7.54"
15056
15057         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15058         cancel_lru_locks mdc
15059
15060         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15061         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15062         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15063
15064         local nr=1000
15065         createmany -o $DIR/$tdir/f $nr ||
15066                 error "failed to create $nr files in $DIR/$tdir"
15067         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15068
15069         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15070         do_facet mds1 $LCTL set_param fail_loc=0x327
15071         do_facet mds1 $LCTL set_param fail_val=500
15072         touch $DIR/$tdir/m
15073
15074         echo "sleep 10 seconds ..."
15075         sleep 10
15076         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15077
15078         do_facet mds1 $LCTL set_param fail_loc=0
15079         do_facet mds1 $LCTL set_param fail_val=0
15080         [ $lck_cnt -lt $unused ] ||
15081                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15082
15083         rm $DIR/$tdir/m
15084         unlinkmany $DIR/$tdir/f $nr
15085 }
15086 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15087
15088 test_134b() {
15089         remote_mds_nodsh && skip "remote MDS with nodsh"
15090         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15091                 skip "Need MDS version at least 2.7.54"
15092
15093         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15094         cancel_lru_locks mdc
15095
15096         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15097                         ldlm.lock_reclaim_threshold_mb)
15098         # disable reclaim temporarily
15099         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15100
15101         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15102         do_facet mds1 $LCTL set_param fail_loc=0x328
15103         do_facet mds1 $LCTL set_param fail_val=500
15104
15105         $LCTL set_param debug=+trace
15106
15107         local nr=600
15108         createmany -o $DIR/$tdir/f $nr &
15109         local create_pid=$!
15110
15111         echo "Sleep $TIMEOUT seconds ..."
15112         sleep $TIMEOUT
15113         if ! ps -p $create_pid  > /dev/null 2>&1; then
15114                 do_facet mds1 $LCTL set_param fail_loc=0
15115                 do_facet mds1 $LCTL set_param fail_val=0
15116                 do_facet mds1 $LCTL set_param \
15117                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15118                 error "createmany finished incorrectly!"
15119         fi
15120         do_facet mds1 $LCTL set_param fail_loc=0
15121         do_facet mds1 $LCTL set_param fail_val=0
15122         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15123         wait $create_pid || return 1
15124
15125         unlinkmany $DIR/$tdir/f $nr
15126 }
15127 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15128
15129 test_135() {
15130         remote_mds_nodsh && skip "remote MDS with nodsh"
15131         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15132                 skip "Need MDS version at least 2.13.50"
15133         local fname
15134
15135         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15136
15137 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15138         #set only one record at plain llog
15139         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15140
15141         #fill already existed plain llog each 64767
15142         #wrapping whole catalog
15143         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15144
15145         createmany -o $DIR/$tdir/$tfile_ 64700
15146         for (( i = 0; i < 64700; i = i + 2 ))
15147         do
15148                 rm $DIR/$tdir/$tfile_$i &
15149                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15150                 local pid=$!
15151                 wait $pid
15152         done
15153
15154         #waiting osp synchronization
15155         wait_delete_completed
15156 }
15157 run_test 135 "Race catalog processing"
15158
15159 test_136() {
15160         remote_mds_nodsh && skip "remote MDS with nodsh"
15161         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15162                 skip "Need MDS version at least 2.13.50"
15163         local fname
15164
15165         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15166         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15167         #set only one record at plain llog
15168 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15169         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15170
15171         #fill already existed 2 plain llogs each 64767
15172         #wrapping whole catalog
15173         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15174         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15175         wait_delete_completed
15176
15177         createmany -o $DIR/$tdir/$tfile_ 10
15178         sleep 25
15179
15180         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15181         for (( i = 0; i < 10; i = i + 3 ))
15182         do
15183                 rm $DIR/$tdir/$tfile_$i &
15184                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15185                 local pid=$!
15186                 wait $pid
15187                 sleep 7
15188                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15189         done
15190
15191         #waiting osp synchronization
15192         wait_delete_completed
15193 }
15194 run_test 136 "Race catalog processing 2"
15195
15196 test_140() { #bug-17379
15197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15198
15199         test_mkdir $DIR/$tdir
15200         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15201         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15202
15203         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15204         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15205         local i=0
15206         while i=$((i + 1)); do
15207                 test_mkdir $i
15208                 cd $i || error "Changing to $i"
15209                 ln -s ../stat stat || error "Creating stat symlink"
15210                 # Read the symlink until ELOOP present,
15211                 # not LBUGing the system is considered success,
15212                 # we didn't overrun the stack.
15213                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15214                 if [ $ret -ne 0 ]; then
15215                         if [ $ret -eq 40 ]; then
15216                                 break  # -ELOOP
15217                         else
15218                                 error "Open stat symlink"
15219                                         return
15220                         fi
15221                 fi
15222         done
15223         i=$((i - 1))
15224         echo "The symlink depth = $i"
15225         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15226                 error "Invalid symlink depth"
15227
15228         # Test recursive symlink
15229         ln -s symlink_self symlink_self
15230         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15231         echo "open symlink_self returns $ret"
15232         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15233 }
15234 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15235
15236 test_150a() {
15237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15238
15239         local TF="$TMP/$tfile"
15240
15241         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15242         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15243         cp $TF $DIR/$tfile
15244         cancel_lru_locks $OSC
15245         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15246         remount_client $MOUNT
15247         df -P $MOUNT
15248         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15249
15250         $TRUNCATE $TF 6000
15251         $TRUNCATE $DIR/$tfile 6000
15252         cancel_lru_locks $OSC
15253         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15254
15255         echo "12345" >>$TF
15256         echo "12345" >>$DIR/$tfile
15257         cancel_lru_locks $OSC
15258         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15259
15260         echo "12345" >>$TF
15261         echo "12345" >>$DIR/$tfile
15262         cancel_lru_locks $OSC
15263         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15264 }
15265 run_test 150a "truncate/append tests"
15266
15267 test_150b() {
15268         check_set_fallocate_or_skip
15269         local out
15270
15271         touch $DIR/$tfile
15272         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15273         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15274                 skip_eopnotsupp "$out|check_fallocate failed"
15275 }
15276 run_test 150b "Verify fallocate (prealloc) functionality"
15277
15278 test_150bb() {
15279         check_set_fallocate_or_skip
15280
15281         touch $DIR/$tfile
15282         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15283         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15284         > $DIR/$tfile
15285         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15286         # precomputed md5sum for 20MB of zeroes
15287         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15288         local sum=($(md5sum $DIR/$tfile))
15289
15290         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15291
15292         check_set_fallocate 1
15293
15294         > $DIR/$tfile
15295         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15296         sum=($(md5sum $DIR/$tfile))
15297
15298         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15299 }
15300 run_test 150bb "Verify fallocate modes both zero space"
15301
15302 test_150c() {
15303         check_set_fallocate_or_skip
15304         local striping="-c2"
15305
15306         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15307         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15308         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15309         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15310         local want=$((OSTCOUNT * 1048576))
15311
15312         # Must allocate all requested space, not more than 5% extra
15313         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15314                 error "bytes $bytes is not $want"
15315
15316         rm -f $DIR/$tfile
15317
15318         echo "verify fallocate on PFL file"
15319
15320         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15321
15322         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15323                 error "Create $DIR/$tfile failed"
15324         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15325         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15326         want=$((512 * 1048576))
15327
15328         # Must allocate all requested space, not more than 5% extra
15329         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15330                 error "bytes $bytes is not $want"
15331 }
15332 run_test 150c "Verify fallocate Size and Blocks"
15333
15334 test_150d() {
15335         check_set_fallocate_or_skip
15336         local striping="-c2"
15337
15338         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15339
15340         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15341         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15342                 error "setstripe failed"
15343         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15344         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15345         local want=$((OSTCOUNT * 1048576))
15346
15347         # Must allocate all requested space, not more than 5% extra
15348         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15349                 error "bytes $bytes is not $want"
15350 }
15351 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15352
15353 test_150e() {
15354         check_set_fallocate_or_skip
15355
15356         echo "df before:"
15357         $LFS df
15358         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15359         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15360                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15361
15362         # Find OST with Minimum Size
15363         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15364                        sort -un | head -1)
15365
15366         # Get 100MB per OST of the available space to reduce run time
15367         # else 60% of the available space if we are running SLOW tests
15368         if [ $SLOW == "no" ]; then
15369                 local space=$((1024 * 100 * OSTCOUNT))
15370         else
15371                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15372         fi
15373
15374         fallocate -l${space}k $DIR/$tfile ||
15375                 error "fallocate ${space}k $DIR/$tfile failed"
15376         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15377
15378         # get size immediately after fallocate. This should be correctly
15379         # updated
15380         local size=$(stat -c '%s' $DIR/$tfile)
15381         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15382
15383         # Sleep for a while for statfs to get updated. And not pull from cache.
15384         sleep 2
15385
15386         echo "df after fallocate:"
15387         $LFS df
15388
15389         (( size / 1024 == space )) || error "size $size != requested $space"
15390         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15391                 error "used $used < space $space"
15392
15393         rm $DIR/$tfile || error "rm failed"
15394         sync
15395         wait_delete_completed
15396
15397         echo "df after unlink:"
15398         $LFS df
15399 }
15400 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15401
15402 test_150f() {
15403         local size
15404         local blocks
15405         local want_size_before=20480 # in bytes
15406         local want_blocks_before=40 # 512 sized blocks
15407         local want_blocks_after=24  # 512 sized blocks
15408         local length=$(((want_blocks_before - want_blocks_after) * 512))
15409
15410         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15411                 skip "need at least 2.14.0 for fallocate punch"
15412
15413         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15414                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15415         fi
15416
15417         check_set_fallocate_or_skip
15418         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15419
15420         [[ "x$DOM" == "xyes" ]] &&
15421                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15422
15423         echo "Verify fallocate punch: Range within the file range"
15424         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15425                 error "dd failed for bs 4096 and count 5"
15426
15427         # Call fallocate with punch range which is within the file range
15428         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15429                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15430         # client must see changes immediately after fallocate
15431         size=$(stat -c '%s' $DIR/$tfile)
15432         blocks=$(stat -c '%b' $DIR/$tfile)
15433
15434         # Verify punch worked.
15435         (( blocks == want_blocks_after )) ||
15436                 error "punch failed: blocks $blocks != $want_blocks_after"
15437
15438         (( size == want_size_before )) ||
15439                 error "punch failed: size $size != $want_size_before"
15440
15441         # Verify there is hole in file
15442         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15443         # precomputed md5sum
15444         local expect="4a9a834a2db02452929c0a348273b4aa"
15445
15446         cksum=($(md5sum $DIR/$tfile))
15447         [[ "${cksum[0]}" == "$expect" ]] ||
15448                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15449
15450         # Start second sub-case for fallocate punch.
15451         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15452         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15453                 error "dd failed for bs 4096 and count 5"
15454
15455         # Punch range less than block size will have no change in block count
15456         want_blocks_after=40  # 512 sized blocks
15457
15458         # Punch overlaps two blocks and less than blocksize
15459         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15460                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15461         size=$(stat -c '%s' $DIR/$tfile)
15462         blocks=$(stat -c '%b' $DIR/$tfile)
15463
15464         # Verify punch worked.
15465         (( blocks == want_blocks_after )) ||
15466                 error "punch failed: blocks $blocks != $want_blocks_after"
15467
15468         (( size == want_size_before )) ||
15469                 error "punch failed: size $size != $want_size_before"
15470
15471         # Verify if range is really zero'ed out. We expect Zeros.
15472         # precomputed md5sum
15473         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15474         cksum=($(md5sum $DIR/$tfile))
15475         [[ "${cksum[0]}" == "$expect" ]] ||
15476                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15477 }
15478 run_test 150f "Verify fallocate punch functionality"
15479
15480 test_150g() {
15481         local space
15482         local size
15483         local blocks
15484         local blocks_after
15485         local size_after
15486         local BS=4096 # Block size in bytes
15487
15488         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15489                 skip "need at least 2.14.0 for fallocate punch"
15490
15491         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15492                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15493         fi
15494
15495         check_set_fallocate_or_skip
15496         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15497
15498         if [[ "x$DOM" == "xyes" ]]; then
15499                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15500                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15501         else
15502                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15503                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15504         fi
15505
15506         # Get 100MB per OST of the available space to reduce run time
15507         # else 60% of the available space if we are running SLOW tests
15508         if [ $SLOW == "no" ]; then
15509                 space=$((1024 * 100 * OSTCOUNT))
15510         else
15511                 # Find OST with Minimum Size
15512                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15513                         sort -un | head -1)
15514                 echo "min size OST: $space"
15515                 space=$(((space * 60)/100 * OSTCOUNT))
15516         fi
15517         # space in 1k units, round to 4k blocks
15518         local blkcount=$((space * 1024 / $BS))
15519
15520         echo "Verify fallocate punch: Very large Range"
15521         fallocate -l${space}k $DIR/$tfile ||
15522                 error "fallocate ${space}k $DIR/$tfile failed"
15523         # write 1M at the end, start and in the middle
15524         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15525                 error "dd failed: bs $BS count 256"
15526         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15527                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15528         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15529                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15530
15531         # Gather stats.
15532         size=$(stat -c '%s' $DIR/$tfile)
15533
15534         # gather punch length.
15535         local punch_size=$((size - (BS * 2)))
15536
15537         echo "punch_size = $punch_size"
15538         echo "size - punch_size: $((size - punch_size))"
15539         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15540
15541         # Call fallocate to punch all except 2 blocks. We leave the
15542         # first and the last block
15543         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15544         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15545                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15546
15547         size_after=$(stat -c '%s' $DIR/$tfile)
15548         blocks_after=$(stat -c '%b' $DIR/$tfile)
15549
15550         # Verify punch worked.
15551         # Size should be kept
15552         (( size == size_after )) ||
15553                 error "punch failed: size $size != $size_after"
15554
15555         # two 4k data blocks to remain plus possible 1 extra extent block
15556         (( blocks_after <= ((BS / 512) * 3) )) ||
15557                 error "too many blocks remains: $blocks_after"
15558
15559         # Verify that file has hole between the first and the last blocks
15560         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15561         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15562
15563         echo "Hole at [$hole_start, $hole_end)"
15564         (( hole_start == BS )) ||
15565                 error "no hole at offset $BS after punch"
15566
15567         (( hole_end == BS + punch_size )) ||
15568                 error "data at offset $hole_end < $((BS + punch_size))"
15569 }
15570 run_test 150g "Verify fallocate punch on large range"
15571
15572 test_150h() {
15573         local file=$DIR/$tfile
15574         local size
15575
15576         check_set_fallocate_or_skip
15577         statx_supported || skip_env "Test must be statx() syscall supported"
15578
15579         # fallocate() does not update the size information on the MDT
15580         fallocate -l 16K $file || error "failed to fallocate $file"
15581         cancel_lru_locks $OSC
15582         # STATX with cached-always mode will not send glimpse RPCs to OST,
15583         # it uses the caching attrs on the client side as much as possible.
15584         size=$($STATX --cached=always -c %s $file)
15585         [ $size == 16384 ] ||
15586                 error "size after fallocate() is $size, expected 16384"
15587 }
15588 run_test 150h "Verify extend fallocate updates the file size"
15589
15590 #LU-2902 roc_hit was not able to read all values from lproc
15591 function roc_hit_init() {
15592         local list=$(comma_list $(osts_nodes))
15593         local dir=$DIR/$tdir-check
15594         local file=$dir/$tfile
15595         local BEFORE
15596         local AFTER
15597         local idx
15598
15599         test_mkdir $dir
15600         #use setstripe to do a write to every ost
15601         for i in $(seq 0 $((OSTCOUNT-1))); do
15602                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15603                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15604                 idx=$(printf %04x $i)
15605                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15606                         awk '$1 == "cache_access" {sum += $7}
15607                                 END { printf("%0.0f", sum) }')
15608
15609                 cancel_lru_locks osc
15610                 cat $file >/dev/null
15611
15612                 AFTER=$(get_osd_param $list *OST*$idx stats |
15613                         awk '$1 == "cache_access" {sum += $7}
15614                                 END { printf("%0.0f", sum) }')
15615
15616                 echo BEFORE:$BEFORE AFTER:$AFTER
15617                 if ! let "AFTER - BEFORE == 4"; then
15618                         rm -rf $dir
15619                         error "roc_hit is not safe to use"
15620                 fi
15621                 rm $file
15622         done
15623
15624         rm -rf $dir
15625 }
15626
15627 function roc_hit() {
15628         local list=$(comma_list $(osts_nodes))
15629         echo $(get_osd_param $list '' stats |
15630                 awk '$1 == "cache_hit" {sum += $7}
15631                         END { printf("%0.0f", sum) }')
15632 }
15633
15634 function set_cache() {
15635         local on=1
15636
15637         if [ "$2" == "off" ]; then
15638                 on=0;
15639         fi
15640         local list=$(comma_list $(osts_nodes))
15641         set_osd_param $list '' $1_cache_enable $on
15642
15643         cancel_lru_locks osc
15644 }
15645
15646 test_151() {
15647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15648         remote_ost_nodsh && skip "remote OST with nodsh"
15649
15650         local CPAGES=3
15651         local list=$(comma_list $(osts_nodes))
15652
15653         # check whether obdfilter is cache capable at all
15654         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15655                 skip "not cache-capable obdfilter"
15656         fi
15657
15658         # check cache is enabled on all obdfilters
15659         if get_osd_param $list '' read_cache_enable | grep 0; then
15660                 skip "oss cache is disabled"
15661         fi
15662
15663         set_osd_param $list '' writethrough_cache_enable 1
15664
15665         # check write cache is enabled on all obdfilters
15666         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15667                 skip "oss write cache is NOT enabled"
15668         fi
15669
15670         roc_hit_init
15671
15672         #define OBD_FAIL_OBD_NO_LRU  0x609
15673         do_nodes $list $LCTL set_param fail_loc=0x609
15674
15675         # pages should be in the case right after write
15676         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15677                 error "dd failed"
15678
15679         local BEFORE=$(roc_hit)
15680         cancel_lru_locks osc
15681         cat $DIR/$tfile >/dev/null
15682         local AFTER=$(roc_hit)
15683
15684         do_nodes $list $LCTL set_param fail_loc=0
15685
15686         if ! let "AFTER - BEFORE == CPAGES"; then
15687                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15688         fi
15689
15690         cancel_lru_locks osc
15691         # invalidates OST cache
15692         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15693         set_osd_param $list '' read_cache_enable 0
15694         cat $DIR/$tfile >/dev/null
15695
15696         # now data shouldn't be found in the cache
15697         BEFORE=$(roc_hit)
15698         cancel_lru_locks osc
15699         cat $DIR/$tfile >/dev/null
15700         AFTER=$(roc_hit)
15701         if let "AFTER - BEFORE != 0"; then
15702                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15703         fi
15704
15705         set_osd_param $list '' read_cache_enable 1
15706         rm -f $DIR/$tfile
15707 }
15708 run_test 151 "test cache on oss and controls ==============================="
15709
15710 test_152() {
15711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15712
15713         local TF="$TMP/$tfile"
15714
15715         # simulate ENOMEM during write
15716 #define OBD_FAIL_OST_NOMEM      0x226
15717         lctl set_param fail_loc=0x80000226
15718         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15719         cp $TF $DIR/$tfile
15720         sync || error "sync failed"
15721         lctl set_param fail_loc=0
15722
15723         # discard client's cache
15724         cancel_lru_locks osc
15725
15726         # simulate ENOMEM during read
15727         lctl set_param fail_loc=0x80000226
15728         cmp $TF $DIR/$tfile || error "cmp failed"
15729         lctl set_param fail_loc=0
15730
15731         rm -f $TF
15732 }
15733 run_test 152 "test read/write with enomem ============================"
15734
15735 test_153() {
15736         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15737 }
15738 run_test 153 "test if fdatasync does not crash ======================="
15739
15740 dot_lustre_fid_permission_check() {
15741         local fid=$1
15742         local ffid=$MOUNT/.lustre/fid/$fid
15743         local test_dir=$2
15744
15745         echo "stat fid $fid"
15746         stat $ffid || error "stat $ffid failed."
15747         echo "touch fid $fid"
15748         touch $ffid || error "touch $ffid failed."
15749         echo "write to fid $fid"
15750         cat /etc/hosts > $ffid || error "write $ffid failed."
15751         echo "read fid $fid"
15752         diff /etc/hosts $ffid || error "read $ffid failed."
15753         echo "append write to fid $fid"
15754         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15755         echo "rename fid $fid"
15756         mv $ffid $test_dir/$tfile.1 &&
15757                 error "rename $ffid to $tfile.1 should fail."
15758         touch $test_dir/$tfile.1
15759         mv $test_dir/$tfile.1 $ffid &&
15760                 error "rename $tfile.1 to $ffid should fail."
15761         rm -f $test_dir/$tfile.1
15762         echo "truncate fid $fid"
15763         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15764         echo "link fid $fid"
15765         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15766         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15767                 echo "setfacl fid $fid"
15768                 setfacl -R -m u:$USER0:rwx $ffid ||
15769                         error "setfacl $ffid failed"
15770                 echo "getfacl fid $fid"
15771                 getfacl $ffid || error "getfacl $ffid failed."
15772         fi
15773         echo "unlink fid $fid"
15774         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15775         echo "mknod fid $fid"
15776         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15777
15778         fid=[0xf00000400:0x1:0x0]
15779         ffid=$MOUNT/.lustre/fid/$fid
15780
15781         echo "stat non-exist fid $fid"
15782         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15783         echo "write to non-exist fid $fid"
15784         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15785         echo "link new fid $fid"
15786         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15787
15788         mkdir -p $test_dir/$tdir
15789         touch $test_dir/$tdir/$tfile
15790         fid=$($LFS path2fid $test_dir/$tdir)
15791         rc=$?
15792         [ $rc -ne 0 ] &&
15793                 error "error: could not get fid for $test_dir/$dir/$tfile."
15794
15795         ffid=$MOUNT/.lustre/fid/$fid
15796
15797         echo "ls $fid"
15798         ls $ffid || error "ls $ffid failed."
15799         echo "touch $fid/$tfile.1"
15800         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15801
15802         echo "touch $MOUNT/.lustre/fid/$tfile"
15803         touch $MOUNT/.lustre/fid/$tfile && \
15804                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15805
15806         echo "setxattr to $MOUNT/.lustre/fid"
15807         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15808
15809         echo "listxattr for $MOUNT/.lustre/fid"
15810         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15811
15812         echo "delxattr from $MOUNT/.lustre/fid"
15813         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15814
15815         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15816         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15817                 error "touch invalid fid should fail."
15818
15819         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15820         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15821                 error "touch non-normal fid should fail."
15822
15823         echo "rename $tdir to $MOUNT/.lustre/fid"
15824         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15825                 error "rename to $MOUNT/.lustre/fid should fail."
15826
15827         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15828         then            # LU-3547
15829                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15830                 local new_obf_mode=777
15831
15832                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15833                 chmod $new_obf_mode $DIR/.lustre/fid ||
15834                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15835
15836                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15837                 [ $obf_mode -eq $new_obf_mode ] ||
15838                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15839
15840                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15841                 chmod $old_obf_mode $DIR/.lustre/fid ||
15842                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15843         fi
15844
15845         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15846         fid=$($LFS path2fid $test_dir/$tfile-2)
15847
15848         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15849         then # LU-5424
15850                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15851                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15852                         error "create lov data thru .lustre failed"
15853         fi
15854         echo "cp /etc/passwd $test_dir/$tfile-2"
15855         cp /etc/passwd $test_dir/$tfile-2 ||
15856                 error "copy to $test_dir/$tfile-2 failed."
15857         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15858         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15859                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15860
15861         rm -rf $test_dir/tfile.lnk
15862         rm -rf $test_dir/$tfile-2
15863 }
15864
15865 test_154A() {
15866         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15867                 skip "Need MDS version at least 2.4.1"
15868
15869         local tf=$DIR/$tfile
15870         touch $tf
15871
15872         local fid=$($LFS path2fid $tf)
15873         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15874
15875         # check that we get the same pathname back
15876         local rootpath
15877         local found
15878         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15879                 echo "$rootpath $fid"
15880                 found=$($LFS fid2path $rootpath "$fid")
15881                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15882                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15883         done
15884
15885         # check wrong root path format
15886         rootpath=$MOUNT"_wrong"
15887         found=$($LFS fid2path $rootpath "$fid")
15888         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15889 }
15890 run_test 154A "lfs path2fid and fid2path basic checks"
15891
15892 test_154B() {
15893         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15894                 skip "Need MDS version at least 2.4.1"
15895
15896         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15897         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15898         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15899         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15900
15901         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15902         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15903
15904         # check that we get the same pathname
15905         echo "PFID: $PFID, name: $name"
15906         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15907         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15908         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15909                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15910
15911         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15912 }
15913 run_test 154B "verify the ll_decode_linkea tool"
15914
15915 test_154a() {
15916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15917         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15918         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15919                 skip "Need MDS version at least 2.2.51"
15920         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15921
15922         cp /etc/hosts $DIR/$tfile
15923
15924         fid=$($LFS path2fid $DIR/$tfile)
15925         rc=$?
15926         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15927
15928         dot_lustre_fid_permission_check "$fid" $DIR ||
15929                 error "dot lustre permission check $fid failed"
15930
15931         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15932
15933         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15934
15935         touch $MOUNT/.lustre/file &&
15936                 error "creation is not allowed under .lustre"
15937
15938         mkdir $MOUNT/.lustre/dir &&
15939                 error "mkdir is not allowed under .lustre"
15940
15941         rm -rf $DIR/$tfile
15942 }
15943 run_test 154a "Open-by-FID"
15944
15945 test_154b() {
15946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15947         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15949         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15950                 skip "Need MDS version at least 2.2.51"
15951
15952         local remote_dir=$DIR/$tdir/remote_dir
15953         local MDTIDX=1
15954         local rc=0
15955
15956         mkdir -p $DIR/$tdir
15957         $LFS mkdir -i $MDTIDX $remote_dir ||
15958                 error "create remote directory failed"
15959
15960         cp /etc/hosts $remote_dir/$tfile
15961
15962         fid=$($LFS path2fid $remote_dir/$tfile)
15963         rc=$?
15964         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15965
15966         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15967                 error "dot lustre permission check $fid failed"
15968         rm -rf $DIR/$tdir
15969 }
15970 run_test 154b "Open-by-FID for remote directory"
15971
15972 test_154c() {
15973         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15974                 skip "Need MDS version at least 2.4.1"
15975
15976         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15977         local FID1=$($LFS path2fid $DIR/$tfile.1)
15978         local FID2=$($LFS path2fid $DIR/$tfile.2)
15979         local FID3=$($LFS path2fid $DIR/$tfile.3)
15980
15981         local N=1
15982         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15983                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15984                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15985                 local want=FID$N
15986                 [ "$FID" = "${!want}" ] ||
15987                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15988                 N=$((N + 1))
15989         done
15990
15991         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15992         do
15993                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15994                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15995                 N=$((N + 1))
15996         done
15997 }
15998 run_test 154c "lfs path2fid and fid2path multiple arguments"
15999
16000 test_154d() {
16001         remote_mds_nodsh && skip "remote MDS with nodsh"
16002         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16003                 skip "Need MDS version at least 2.5.53"
16004
16005         if remote_mds; then
16006                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16007         else
16008                 nid="0@lo"
16009         fi
16010         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16011         local fd
16012         local cmd
16013
16014         rm -f $DIR/$tfile
16015         touch $DIR/$tfile
16016
16017         local fid=$($LFS path2fid $DIR/$tfile)
16018         # Open the file
16019         fd=$(free_fd)
16020         cmd="exec $fd<$DIR/$tfile"
16021         eval $cmd
16022         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16023         echo "$fid_list" | grep "$fid"
16024         rc=$?
16025
16026         cmd="exec $fd>/dev/null"
16027         eval $cmd
16028         if [ $rc -ne 0 ]; then
16029                 error "FID $fid not found in open files list $fid_list"
16030         fi
16031 }
16032 run_test 154d "Verify open file fid"
16033
16034 test_154e()
16035 {
16036         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16037                 skip "Need MDS version at least 2.6.50"
16038
16039         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16040                 error ".lustre returned by readdir"
16041         fi
16042 }
16043 run_test 154e ".lustre is not returned by readdir"
16044
16045 test_154f() {
16046         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16047
16048         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16049         mkdir_on_mdt0 $DIR/$tdir
16050         # test dirs inherit from its stripe
16051         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16052         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16053         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16054         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16055         touch $DIR/f
16056
16057         # get fid of parents
16058         local FID0=$($LFS path2fid $DIR/$tdir)
16059         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16060         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16061         local FID3=$($LFS path2fid $DIR)
16062
16063         # check that path2fid --parents returns expected <parent_fid>/name
16064         # 1) test for a directory (single parent)
16065         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16066         [ "$parent" == "$FID0/foo1" ] ||
16067                 error "expected parent: $FID0/foo1, got: $parent"
16068
16069         # 2) test for a file with nlink > 1 (multiple parents)
16070         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16071         echo "$parent" | grep -F "$FID1/$tfile" ||
16072                 error "$FID1/$tfile not returned in parent list"
16073         echo "$parent" | grep -F "$FID2/link" ||
16074                 error "$FID2/link not returned in parent list"
16075
16076         # 3) get parent by fid
16077         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16078         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16079         echo "$parent" | grep -F "$FID1/$tfile" ||
16080                 error "$FID1/$tfile not returned in parent list (by fid)"
16081         echo "$parent" | grep -F "$FID2/link" ||
16082                 error "$FID2/link not returned in parent list (by fid)"
16083
16084         # 4) test for entry in root directory
16085         parent=$($LFS path2fid --parents $DIR/f)
16086         echo "$parent" | grep -F "$FID3/f" ||
16087                 error "$FID3/f not returned in parent list"
16088
16089         # 5) test it on root directory
16090         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16091                 error "$MOUNT should not have parents"
16092
16093         # enable xattr caching and check that linkea is correctly updated
16094         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16095         save_lustre_params client "llite.*.xattr_cache" > $save
16096         lctl set_param llite.*.xattr_cache 1
16097
16098         # 6.1) linkea update on rename
16099         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16100
16101         # get parents by fid
16102         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16103         # foo1 should no longer be returned in parent list
16104         echo "$parent" | grep -F "$FID1" &&
16105                 error "$FID1 should no longer be in parent list"
16106         # the new path should appear
16107         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16108                 error "$FID2/$tfile.moved is not in parent list"
16109
16110         # 6.2) linkea update on unlink
16111         rm -f $DIR/$tdir/foo2/link
16112         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16113         # foo2/link should no longer be returned in parent list
16114         echo "$parent" | grep -F "$FID2/link" &&
16115                 error "$FID2/link should no longer be in parent list"
16116         true
16117
16118         rm -f $DIR/f
16119         restore_lustre_params < $save
16120         rm -f $save
16121 }
16122 run_test 154f "get parent fids by reading link ea"
16123
16124 test_154g()
16125 {
16126         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16127            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16128                 skip "Need MDS version at least 2.6.92"
16129
16130         mkdir_on_mdt0 $DIR/$tdir
16131         llapi_fid_test -d $DIR/$tdir
16132 }
16133 run_test 154g "various llapi FID tests"
16134
16135 test_155_small_load() {
16136     local temp=$TMP/$tfile
16137     local file=$DIR/$tfile
16138
16139     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16140         error "dd of=$temp bs=6096 count=1 failed"
16141     cp $temp $file
16142     cancel_lru_locks $OSC
16143     cmp $temp $file || error "$temp $file differ"
16144
16145     $TRUNCATE $temp 6000
16146     $TRUNCATE $file 6000
16147     cmp $temp $file || error "$temp $file differ (truncate1)"
16148
16149     echo "12345" >>$temp
16150     echo "12345" >>$file
16151     cmp $temp $file || error "$temp $file differ (append1)"
16152
16153     echo "12345" >>$temp
16154     echo "12345" >>$file
16155     cmp $temp $file || error "$temp $file differ (append2)"
16156
16157     rm -f $temp $file
16158     true
16159 }
16160
16161 test_155_big_load() {
16162         remote_ost_nodsh && skip "remote OST with nodsh"
16163
16164         local temp=$TMP/$tfile
16165         local file=$DIR/$tfile
16166
16167         free_min_max
16168         local cache_size=$(do_facet ost$((MAXI+1)) \
16169                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16170
16171         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16172         # pre-set value
16173         if [ -z "$cache_size" ]; then
16174                 cache_size=256
16175         fi
16176         local large_file_size=$((cache_size * 2))
16177
16178         echo "OSS cache size: $cache_size KB"
16179         echo "Large file size: $large_file_size KB"
16180
16181         [ $MAXV -le $large_file_size ] &&
16182                 skip_env "max available OST size needs > $large_file_size KB"
16183
16184         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16185
16186         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16187                 error "dd of=$temp bs=$large_file_size count=1k failed"
16188         cp $temp $file
16189         ls -lh $temp $file
16190         cancel_lru_locks osc
16191         cmp $temp $file || error "$temp $file differ"
16192
16193         rm -f $temp $file
16194         true
16195 }
16196
16197 save_writethrough() {
16198         local facets=$(get_facets OST)
16199
16200         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16201 }
16202
16203 test_155a() {
16204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16205
16206         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16207
16208         save_writethrough $p
16209
16210         set_cache read on
16211         set_cache writethrough on
16212         test_155_small_load
16213         restore_lustre_params < $p
16214         rm -f $p
16215 }
16216 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16217
16218 test_155b() {
16219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16220
16221         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16222
16223         save_writethrough $p
16224
16225         set_cache read on
16226         set_cache writethrough off
16227         test_155_small_load
16228         restore_lustre_params < $p
16229         rm -f $p
16230 }
16231 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16232
16233 test_155c() {
16234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16235
16236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16237
16238         save_writethrough $p
16239
16240         set_cache read off
16241         set_cache writethrough on
16242         test_155_small_load
16243         restore_lustre_params < $p
16244         rm -f $p
16245 }
16246 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16247
16248 test_155d() {
16249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16250
16251         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16252
16253         save_writethrough $p
16254
16255         set_cache read off
16256         set_cache writethrough off
16257         test_155_small_load
16258         restore_lustre_params < $p
16259         rm -f $p
16260 }
16261 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16262
16263 test_155e() {
16264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16265
16266         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16267
16268         save_writethrough $p
16269
16270         set_cache read on
16271         set_cache writethrough on
16272         test_155_big_load
16273         restore_lustre_params < $p
16274         rm -f $p
16275 }
16276 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16277
16278 test_155f() {
16279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16280
16281         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16282
16283         save_writethrough $p
16284
16285         set_cache read on
16286         set_cache writethrough off
16287         test_155_big_load
16288         restore_lustre_params < $p
16289         rm -f $p
16290 }
16291 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16292
16293 test_155g() {
16294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16295
16296         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16297
16298         save_writethrough $p
16299
16300         set_cache read off
16301         set_cache writethrough on
16302         test_155_big_load
16303         restore_lustre_params < $p
16304         rm -f $p
16305 }
16306 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16307
16308 test_155h() {
16309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16310
16311         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16312
16313         save_writethrough $p
16314
16315         set_cache read off
16316         set_cache writethrough off
16317         test_155_big_load
16318         restore_lustre_params < $p
16319         rm -f $p
16320 }
16321 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16322
16323 test_156() {
16324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16325         remote_ost_nodsh && skip "remote OST with nodsh"
16326         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16327                 skip "stats not implemented on old servers"
16328         [ "$ost1_FSTYPE" = "zfs" ] &&
16329                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16330
16331         local CPAGES=3
16332         local BEFORE
16333         local AFTER
16334         local file="$DIR/$tfile"
16335         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16336
16337         save_writethrough $p
16338         roc_hit_init
16339
16340         log "Turn on read and write cache"
16341         set_cache read on
16342         set_cache writethrough on
16343
16344         log "Write data and read it back."
16345         log "Read should be satisfied from the cache."
16346         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16347         BEFORE=$(roc_hit)
16348         cancel_lru_locks osc
16349         cat $file >/dev/null
16350         AFTER=$(roc_hit)
16351         if ! let "AFTER - BEFORE == CPAGES"; then
16352                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16353         else
16354                 log "cache hits: before: $BEFORE, after: $AFTER"
16355         fi
16356
16357         log "Read again; it should be satisfied from the cache."
16358         BEFORE=$AFTER
16359         cancel_lru_locks osc
16360         cat $file >/dev/null
16361         AFTER=$(roc_hit)
16362         if ! let "AFTER - BEFORE == CPAGES"; then
16363                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16364         else
16365                 log "cache hits:: before: $BEFORE, after: $AFTER"
16366         fi
16367
16368         log "Turn off the read cache and turn on the write cache"
16369         set_cache read off
16370         set_cache writethrough on
16371
16372         log "Read again; it should be satisfied from the cache."
16373         BEFORE=$(roc_hit)
16374         cancel_lru_locks osc
16375         cat $file >/dev/null
16376         AFTER=$(roc_hit)
16377         if ! let "AFTER - BEFORE == CPAGES"; then
16378                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16379         else
16380                 log "cache hits:: before: $BEFORE, after: $AFTER"
16381         fi
16382
16383         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16384                 # > 2.12.56 uses pagecache if cached
16385                 log "Read again; it should not be satisfied from the cache."
16386                 BEFORE=$AFTER
16387                 cancel_lru_locks osc
16388                 cat $file >/dev/null
16389                 AFTER=$(roc_hit)
16390                 if ! let "AFTER - BEFORE == 0"; then
16391                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16392                 else
16393                         log "cache hits:: before: $BEFORE, after: $AFTER"
16394                 fi
16395         fi
16396
16397         log "Write data and read it back."
16398         log "Read should be satisfied from the cache."
16399         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16400         BEFORE=$(roc_hit)
16401         cancel_lru_locks osc
16402         cat $file >/dev/null
16403         AFTER=$(roc_hit)
16404         if ! let "AFTER - BEFORE == CPAGES"; then
16405                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16406         else
16407                 log "cache hits:: before: $BEFORE, after: $AFTER"
16408         fi
16409
16410         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16411                 # > 2.12.56 uses pagecache if cached
16412                 log "Read again; it should not be satisfied from the cache."
16413                 BEFORE=$AFTER
16414                 cancel_lru_locks osc
16415                 cat $file >/dev/null
16416                 AFTER=$(roc_hit)
16417                 if ! let "AFTER - BEFORE == 0"; then
16418                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16419                 else
16420                         log "cache hits:: before: $BEFORE, after: $AFTER"
16421                 fi
16422         fi
16423
16424         log "Turn off read and write cache"
16425         set_cache read off
16426         set_cache writethrough off
16427
16428         log "Write data and read it back"
16429         log "It should not be satisfied from the cache."
16430         rm -f $file
16431         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16432         cancel_lru_locks osc
16433         BEFORE=$(roc_hit)
16434         cat $file >/dev/null
16435         AFTER=$(roc_hit)
16436         if ! let "AFTER - BEFORE == 0"; then
16437                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16438         else
16439                 log "cache hits:: before: $BEFORE, after: $AFTER"
16440         fi
16441
16442         log "Turn on the read cache and turn off the write cache"
16443         set_cache read on
16444         set_cache writethrough off
16445
16446         log "Write data and read it back"
16447         log "It should not be satisfied from the cache."
16448         rm -f $file
16449         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16450         BEFORE=$(roc_hit)
16451         cancel_lru_locks osc
16452         cat $file >/dev/null
16453         AFTER=$(roc_hit)
16454         if ! let "AFTER - BEFORE == 0"; then
16455                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16456         else
16457                 log "cache hits:: before: $BEFORE, after: $AFTER"
16458         fi
16459
16460         log "Read again; it should be satisfied from the cache."
16461         BEFORE=$(roc_hit)
16462         cancel_lru_locks osc
16463         cat $file >/dev/null
16464         AFTER=$(roc_hit)
16465         if ! let "AFTER - BEFORE == CPAGES"; then
16466                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16467         else
16468                 log "cache hits:: before: $BEFORE, after: $AFTER"
16469         fi
16470
16471         restore_lustre_params < $p
16472         rm -f $p $file
16473 }
16474 run_test 156 "Verification of tunables"
16475
16476 test_160a() {
16477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16478         remote_mds_nodsh && skip "remote MDS with nodsh"
16479         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16480                 skip "Need MDS version at least 2.2.0"
16481
16482         changelog_register || error "changelog_register failed"
16483         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16484         changelog_users $SINGLEMDS | grep -q $cl_user ||
16485                 error "User $cl_user not found in changelog_users"
16486
16487         mkdir_on_mdt0 $DIR/$tdir
16488
16489         # change something
16490         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16491         changelog_clear 0 || error "changelog_clear failed"
16492         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16493         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16494         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16495         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16496         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16497         rm $DIR/$tdir/pics/desktop.jpg
16498
16499         echo "verifying changelog mask"
16500         changelog_chmask "-MKDIR"
16501         changelog_chmask "-CLOSE"
16502
16503         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16504         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16505
16506         changelog_chmask "+MKDIR"
16507         changelog_chmask "+CLOSE"
16508
16509         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16510         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16511
16512         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16513         CLOSES=$(changelog_dump | grep -c "CLOSE")
16514         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16515         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16516
16517         # verify contents
16518         echo "verifying target fid"
16519         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16520         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16521         [ "$fidc" == "$fidf" ] ||
16522                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16523         echo "verifying parent fid"
16524         # The FID returned from the Changelog may be the directory shard on
16525         # a different MDT, and not the FID returned by path2fid on the parent.
16526         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16527         # since this is what will matter when recreating this file in the tree.
16528         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16529         local pathp=$($LFS fid2path $MOUNT "$fidp")
16530         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16531                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16532
16533         echo "getting records for $cl_user"
16534         changelog_users $SINGLEMDS
16535         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16536         local nclr=3
16537         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16538                 error "changelog_clear failed"
16539         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16540         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16541         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16542                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16543
16544         local min0_rec=$(changelog_users $SINGLEMDS |
16545                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16546         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16547                           awk '{ print $1; exit; }')
16548
16549         changelog_dump | tail -n 5
16550         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16551         [ $first_rec == $((min0_rec + 1)) ] ||
16552                 error "first index should be $min0_rec + 1 not $first_rec"
16553
16554         # LU-3446 changelog index reset on MDT restart
16555         local cur_rec1=$(changelog_users $SINGLEMDS |
16556                          awk '/^current.index:/ { print $NF }')
16557         changelog_clear 0 ||
16558                 error "clear all changelog records for $cl_user failed"
16559         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16560         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16561                 error "Fail to start $SINGLEMDS"
16562         local cur_rec2=$(changelog_users $SINGLEMDS |
16563                          awk '/^current.index:/ { print $NF }')
16564         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16565         [ $cur_rec1 == $cur_rec2 ] ||
16566                 error "current index should be $cur_rec1 not $cur_rec2"
16567
16568         echo "verifying users from this test are deregistered"
16569         changelog_deregister || error "changelog_deregister failed"
16570         changelog_users $SINGLEMDS | grep -q $cl_user &&
16571                 error "User '$cl_user' still in changelog_users"
16572
16573         # lctl get_param -n mdd.*.changelog_users
16574         # current_index: 144
16575         # ID    index (idle seconds)
16576         # cl3   144   (2) mask=<list>
16577         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16578                 # this is the normal case where all users were deregistered
16579                 # make sure no new records are added when no users are present
16580                 local last_rec1=$(changelog_users $SINGLEMDS |
16581                                   awk '/^current.index:/ { print $NF }')
16582                 touch $DIR/$tdir/chloe
16583                 local last_rec2=$(changelog_users $SINGLEMDS |
16584                                   awk '/^current.index:/ { print $NF }')
16585                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16586                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16587         else
16588                 # any changelog users must be leftovers from a previous test
16589                 changelog_users $SINGLEMDS
16590                 echo "other changelog users; can't verify off"
16591         fi
16592 }
16593 run_test 160a "changelog sanity"
16594
16595 test_160b() { # LU-3587
16596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16597         remote_mds_nodsh && skip "remote MDS with nodsh"
16598         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16599                 skip "Need MDS version at least 2.2.0"
16600
16601         changelog_register || error "changelog_register failed"
16602         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16603         changelog_users $SINGLEMDS | grep -q $cl_user ||
16604                 error "User '$cl_user' not found in changelog_users"
16605
16606         local longname1=$(str_repeat a 255)
16607         local longname2=$(str_repeat b 255)
16608
16609         cd $DIR
16610         echo "creating very long named file"
16611         touch $longname1 || error "create of '$longname1' failed"
16612         echo "renaming very long named file"
16613         mv $longname1 $longname2
16614
16615         changelog_dump | grep RENME | tail -n 5
16616         rm -f $longname2
16617 }
16618 run_test 160b "Verify that very long rename doesn't crash in changelog"
16619
16620 test_160c() {
16621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16622         remote_mds_nodsh && skip "remote MDS with nodsh"
16623
16624         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16625                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16626                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16627                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16628
16629         local rc=0
16630
16631         # Registration step
16632         changelog_register || error "changelog_register failed"
16633
16634         rm -rf $DIR/$tdir
16635         mkdir -p $DIR/$tdir
16636         $MCREATE $DIR/$tdir/foo_160c
16637         changelog_chmask "-TRUNC"
16638         $TRUNCATE $DIR/$tdir/foo_160c 200
16639         changelog_chmask "+TRUNC"
16640         $TRUNCATE $DIR/$tdir/foo_160c 199
16641         changelog_dump | tail -n 5
16642         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16643         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16644 }
16645 run_test 160c "verify that changelog log catch the truncate event"
16646
16647 test_160d() {
16648         remote_mds_nodsh && skip "remote MDS with nodsh"
16649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16651         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16652                 skip "Need MDS version at least 2.7.60"
16653
16654         # Registration step
16655         changelog_register || error "changelog_register failed"
16656
16657         mkdir -p $DIR/$tdir/migrate_dir
16658         changelog_clear 0 || error "changelog_clear failed"
16659
16660         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16661         changelog_dump | tail -n 5
16662         local migrates=$(changelog_dump | grep -c "MIGRT")
16663         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16664 }
16665 run_test 160d "verify that changelog log catch the migrate event"
16666
16667 test_160e() {
16668         remote_mds_nodsh && skip "remote MDS with nodsh"
16669
16670         # Create a user
16671         changelog_register || error "changelog_register failed"
16672
16673         local MDT0=$(facet_svc $SINGLEMDS)
16674         local rc
16675
16676         # No user (expect fail)
16677         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16678         rc=$?
16679         if [ $rc -eq 0 ]; then
16680                 error "Should fail without user"
16681         elif [ $rc -ne 4 ]; then
16682                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16683         fi
16684
16685         # Delete a future user (expect fail)
16686         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16687         rc=$?
16688         if [ $rc -eq 0 ]; then
16689                 error "Deleted non-existant user cl77"
16690         elif [ $rc -ne 2 ]; then
16691                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16692         fi
16693
16694         # Clear to a bad index (1 billion should be safe)
16695         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16696         rc=$?
16697
16698         if [ $rc -eq 0 ]; then
16699                 error "Successfully cleared to invalid CL index"
16700         elif [ $rc -ne 22 ]; then
16701                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16702         fi
16703 }
16704 run_test 160e "changelog negative testing (should return errors)"
16705
16706 test_160f() {
16707         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16708         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16709                 skip "Need MDS version at least 2.10.56"
16710
16711         local mdts=$(comma_list $(mdts_nodes))
16712
16713         # Create a user
16714         changelog_register || error "first changelog_register failed"
16715         changelog_register || error "second changelog_register failed"
16716         local cl_users
16717         declare -A cl_user1
16718         declare -A cl_user2
16719         local user_rec1
16720         local user_rec2
16721         local i
16722
16723         # generate some changelog records to accumulate on each MDT
16724         # use all_char because created files should be evenly distributed
16725         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16726                 error "test_mkdir $tdir failed"
16727         log "$(date +%s): creating first files"
16728         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16729                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16730                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16731         done
16732
16733         # check changelogs have been generated
16734         local start=$SECONDS
16735         local idle_time=$((MDSCOUNT * 5 + 5))
16736         local nbcl=$(changelog_dump | wc -l)
16737         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16738
16739         for param in "changelog_max_idle_time=$idle_time" \
16740                      "changelog_gc=1" \
16741                      "changelog_min_gc_interval=2" \
16742                      "changelog_min_free_cat_entries=3"; do
16743                 local MDT0=$(facet_svc $SINGLEMDS)
16744                 local var="${param%=*}"
16745                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16746
16747                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16748                 do_nodes $mdts $LCTL set_param mdd.*.$param
16749         done
16750
16751         # force cl_user2 to be idle (1st part), but also cancel the
16752         # cl_user1 records so that it is not evicted later in the test.
16753         local sleep1=$((idle_time / 2))
16754         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16755         sleep $sleep1
16756
16757         # simulate changelog catalog almost full
16758         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16759         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16760
16761         for i in $(seq $MDSCOUNT); do
16762                 cl_users=(${CL_USERS[mds$i]})
16763                 cl_user1[mds$i]="${cl_users[0]}"
16764                 cl_user2[mds$i]="${cl_users[1]}"
16765
16766                 [ -n "${cl_user1[mds$i]}" ] ||
16767                         error "mds$i: no user registered"
16768                 [ -n "${cl_user2[mds$i]}" ] ||
16769                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16770
16771                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16772                 [ -n "$user_rec1" ] ||
16773                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16774                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16775                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16776                 [ -n "$user_rec2" ] ||
16777                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16778                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16779                      "$user_rec1 + 2 == $user_rec2"
16780                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16781                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16782                               "$user_rec1 + 2, but is $user_rec2"
16783                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16784                 [ -n "$user_rec2" ] ||
16785                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16786                 [ $user_rec1 == $user_rec2 ] ||
16787                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16788                               "$user_rec1, but is $user_rec2"
16789         done
16790
16791         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16792         local sleep2=$((idle_time - (SECONDS - start) + 1))
16793         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16794         sleep $sleep2
16795
16796         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16797         # cl_user1 should be OK because it recently processed records.
16798         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16799         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16800                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16801                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16802         done
16803
16804         # ensure gc thread is done
16805         for i in $(mdts_nodes); do
16806                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16807                         error "$i: GC-thread not done"
16808         done
16809
16810         local first_rec
16811         for (( i = 1; i <= MDSCOUNT; i++ )); do
16812                 # check cl_user1 still registered
16813                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16815                 # check cl_user2 unregistered
16816                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16817                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16818
16819                 # check changelogs are present and starting at $user_rec1 + 1
16820                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16821                 [ -n "$user_rec1" ] ||
16822                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16823                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16824                             awk '{ print $1; exit; }')
16825
16826                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16827                 [ $((user_rec1 + 1)) == $first_rec ] ||
16828                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16829         done
16830 }
16831 run_test 160f "changelog garbage collect (timestamped users)"
16832
16833 test_160g() {
16834         remote_mds_nodsh && skip "remote MDS with nodsh"
16835         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16836                 skip "Need MDS version at least 2.14.55"
16837
16838         local mdts=$(comma_list $(mdts_nodes))
16839
16840         # Create a user
16841         changelog_register || error "first changelog_register failed"
16842         changelog_register || error "second changelog_register failed"
16843         local cl_users
16844         declare -A cl_user1
16845         declare -A cl_user2
16846         local user_rec1
16847         local user_rec2
16848         local i
16849
16850         # generate some changelog records to accumulate on each MDT
16851         # use all_char because created files should be evenly distributed
16852         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16853                 error "test_mkdir $tdir failed"
16854         for ((i = 0; i < MDSCOUNT; i++)); do
16855                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16856                         error "create $DIR/$tdir/d$i.1 failed"
16857         done
16858
16859         # check changelogs have been generated
16860         local nbcl=$(changelog_dump | wc -l)
16861         (( $nbcl > 0 )) || error "no changelogs found"
16862
16863         # reduce the max_idle_indexes value to make sure we exceed it
16864         for param in "changelog_max_idle_indexes=2" \
16865                      "changelog_gc=1" \
16866                      "changelog_min_gc_interval=2"; do
16867                 local MDT0=$(facet_svc $SINGLEMDS)
16868                 local var="${param%=*}"
16869                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16870
16871                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16872                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16873                         error "unable to set mdd.*.$param"
16874         done
16875
16876         local start=$SECONDS
16877         for i in $(seq $MDSCOUNT); do
16878                 cl_users=(${CL_USERS[mds$i]})
16879                 cl_user1[mds$i]="${cl_users[0]}"
16880                 cl_user2[mds$i]="${cl_users[1]}"
16881
16882                 [ -n "${cl_user1[mds$i]}" ] ||
16883                         error "mds$i: user1 is not registered"
16884                 [ -n "${cl_user2[mds$i]}" ] ||
16885                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16886
16887                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16888                 [ -n "$user_rec1" ] ||
16889                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16890                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16891                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16892                 [ -n "$user_rec2" ] ||
16893                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16894                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16895                      "$user_rec1 + 2 == $user_rec2"
16896                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16897                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16898                               "expected $user_rec1 + 2, but is $user_rec2"
16899                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16900                 [ -n "$user_rec2" ] ||
16901                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16902                 [ $user_rec1 == $user_rec2 ] ||
16903                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16904                               "expected $user_rec1, but is $user_rec2"
16905         done
16906
16907         # ensure we are past the previous changelog_min_gc_interval set above
16908         local sleep2=$((start + 2 - SECONDS))
16909         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16910         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16911         # cl_user1 should be OK because it recently processed records.
16912         for ((i = 0; i < MDSCOUNT; i++)); do
16913                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16914                         error "create $DIR/$tdir/d$i.3 failed"
16915         done
16916
16917         # ensure gc thread is done
16918         for i in $(mdts_nodes); do
16919                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16920                         error "$i: GC-thread not done"
16921         done
16922
16923         local first_rec
16924         for (( i = 1; i <= MDSCOUNT; i++ )); do
16925                 # check cl_user1 still registered
16926                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16927                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16928                 # check cl_user2 unregistered
16929                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16930                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16931
16932                 # check changelogs are present and starting at $user_rec1 + 1
16933                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16934                 [ -n "$user_rec1" ] ||
16935                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16936                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16937                             awk '{ print $1; exit; }')
16938
16939                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16940                 [ $((user_rec1 + 1)) == $first_rec ] ||
16941                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16942         done
16943 }
16944 run_test 160g "changelog garbage collect on idle records"
16945
16946 test_160h() {
16947         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16948         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16949                 skip "Need MDS version at least 2.10.56"
16950
16951         local mdts=$(comma_list $(mdts_nodes))
16952
16953         # Create a user
16954         changelog_register || error "first changelog_register failed"
16955         changelog_register || error "second changelog_register failed"
16956         local cl_users
16957         declare -A cl_user1
16958         declare -A cl_user2
16959         local user_rec1
16960         local user_rec2
16961         local i
16962
16963         # generate some changelog records to accumulate on each MDT
16964         # use all_char because created files should be evenly distributed
16965         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16966                 error "test_mkdir $tdir failed"
16967         for ((i = 0; i < MDSCOUNT; i++)); do
16968                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16969                         error "create $DIR/$tdir/d$i.1 failed"
16970         done
16971
16972         # check changelogs have been generated
16973         local nbcl=$(changelog_dump | wc -l)
16974         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16975
16976         for param in "changelog_max_idle_time=10" \
16977                      "changelog_gc=1" \
16978                      "changelog_min_gc_interval=2"; do
16979                 local MDT0=$(facet_svc $SINGLEMDS)
16980                 local var="${param%=*}"
16981                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16982
16983                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16984                 do_nodes $mdts $LCTL set_param mdd.*.$param
16985         done
16986
16987         # force cl_user2 to be idle (1st part)
16988         sleep 9
16989
16990         for i in $(seq $MDSCOUNT); do
16991                 cl_users=(${CL_USERS[mds$i]})
16992                 cl_user1[mds$i]="${cl_users[0]}"
16993                 cl_user2[mds$i]="${cl_users[1]}"
16994
16995                 [ -n "${cl_user1[mds$i]}" ] ||
16996                         error "mds$i: no user registered"
16997                 [ -n "${cl_user2[mds$i]}" ] ||
16998                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16999
17000                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17001                 [ -n "$user_rec1" ] ||
17002                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17003                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17004                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17005                 [ -n "$user_rec2" ] ||
17006                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17007                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17008                      "$user_rec1 + 2 == $user_rec2"
17009                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17010                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17011                               "$user_rec1 + 2, but is $user_rec2"
17012                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17013                 [ -n "$user_rec2" ] ||
17014                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17015                 [ $user_rec1 == $user_rec2 ] ||
17016                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17017                               "$user_rec1, but is $user_rec2"
17018         done
17019
17020         # force cl_user2 to be idle (2nd part) and to reach
17021         # changelog_max_idle_time
17022         sleep 2
17023
17024         # force each GC-thread start and block then
17025         # one per MDT/MDD, set fail_val accordingly
17026         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17027         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17028
17029         # generate more changelogs to trigger fail_loc
17030         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17031                 error "create $DIR/$tdir/${tfile}bis failed"
17032
17033         # stop MDT to stop GC-thread, should be done in back-ground as it will
17034         # block waiting for the thread to be released and exit
17035         declare -A stop_pids
17036         for i in $(seq $MDSCOUNT); do
17037                 stop mds$i &
17038                 stop_pids[mds$i]=$!
17039         done
17040
17041         for i in $(mdts_nodes); do
17042                 local facet
17043                 local nb=0
17044                 local facets=$(facets_up_on_host $i)
17045
17046                 for facet in ${facets//,/ }; do
17047                         if [[ $facet == mds* ]]; then
17048                                 nb=$((nb + 1))
17049                         fi
17050                 done
17051                 # ensure each MDS's gc threads are still present and all in "R"
17052                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17053                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17054                         error "$i: expected $nb GC-thread"
17055                 wait_update $i \
17056                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17057                         "R" 20 ||
17058                         error "$i: GC-thread not found in R-state"
17059                 # check umounts of each MDT on MDS have reached kthread_stop()
17060                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17061                         error "$i: expected $nb umount"
17062                 wait_update $i \
17063                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17064                         error "$i: umount not found in D-state"
17065         done
17066
17067         # release all GC-threads
17068         do_nodes $mdts $LCTL set_param fail_loc=0
17069
17070         # wait for MDT stop to complete
17071         for i in $(seq $MDSCOUNT); do
17072                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17073         done
17074
17075         # XXX
17076         # may try to check if any orphan changelog records are present
17077         # via ldiskfs/zfs and llog_reader...
17078
17079         # re-start/mount MDTs
17080         for i in $(seq $MDSCOUNT); do
17081                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17082                         error "Fail to start mds$i"
17083         done
17084
17085         local first_rec
17086         for i in $(seq $MDSCOUNT); do
17087                 # check cl_user1 still registered
17088                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17089                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17090                 # check cl_user2 unregistered
17091                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17092                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17093
17094                 # check changelogs are present and starting at $user_rec1 + 1
17095                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17096                 [ -n "$user_rec1" ] ||
17097                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17098                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17099                             awk '{ print $1; exit; }')
17100
17101                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17102                 [ $((user_rec1 + 1)) == $first_rec ] ||
17103                         error "mds$i: first index should be $user_rec1 + 1, " \
17104                               "but is $first_rec"
17105         done
17106 }
17107 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17108               "during mount"
17109
17110 test_160i() {
17111
17112         local mdts=$(comma_list $(mdts_nodes))
17113
17114         changelog_register || error "first changelog_register failed"
17115
17116         # generate some changelog records to accumulate on each MDT
17117         # use all_char because created files should be evenly distributed
17118         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17119                 error "test_mkdir $tdir failed"
17120         for ((i = 0; i < MDSCOUNT; i++)); do
17121                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17122                         error "create $DIR/$tdir/d$i.1 failed"
17123         done
17124
17125         # check changelogs have been generated
17126         local nbcl=$(changelog_dump | wc -l)
17127         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17128
17129         # simulate race between register and unregister
17130         # XXX as fail_loc is set per-MDS, with DNE configs the race
17131         # simulation will only occur for one MDT per MDS and for the
17132         # others the normal race scenario will take place
17133         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17134         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17135         do_nodes $mdts $LCTL set_param fail_val=1
17136
17137         # unregister 1st user
17138         changelog_deregister &
17139         local pid1=$!
17140         # wait some time for deregister work to reach race rdv
17141         sleep 2
17142         # register 2nd user
17143         changelog_register || error "2nd user register failed"
17144
17145         wait $pid1 || error "1st user deregister failed"
17146
17147         local i
17148         local last_rec
17149         declare -A LAST_REC
17150         for i in $(seq $MDSCOUNT); do
17151                 if changelog_users mds$i | grep "^cl"; then
17152                         # make sure new records are added with one user present
17153                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17154                                           awk '/^current.index:/ { print $NF }')
17155                 else
17156                         error "mds$i has no user registered"
17157                 fi
17158         done
17159
17160         # generate more changelog records to accumulate on each MDT
17161         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17162                 error "create $DIR/$tdir/${tfile}bis failed"
17163
17164         for i in $(seq $MDSCOUNT); do
17165                 last_rec=$(changelog_users $SINGLEMDS |
17166                            awk '/^current.index:/ { print $NF }')
17167                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17168                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17169                         error "changelogs are off on mds$i"
17170         done
17171 }
17172 run_test 160i "changelog user register/unregister race"
17173
17174 test_160j() {
17175         remote_mds_nodsh && skip "remote MDS with nodsh"
17176         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17177                 skip "Need MDS version at least 2.12.56"
17178
17179         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17180         stack_trap "umount $MOUNT2" EXIT
17181
17182         changelog_register || error "first changelog_register failed"
17183         stack_trap "changelog_deregister" EXIT
17184
17185         # generate some changelog
17186         # use all_char because created files should be evenly distributed
17187         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17188                 error "mkdir $tdir failed"
17189         for ((i = 0; i < MDSCOUNT; i++)); do
17190                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17191                         error "create $DIR/$tdir/d$i.1 failed"
17192         done
17193
17194         # open the changelog device
17195         exec 3>/dev/changelog-$FSNAME-MDT0000
17196         stack_trap "exec 3>&-" EXIT
17197         exec 4</dev/changelog-$FSNAME-MDT0000
17198         stack_trap "exec 4<&-" EXIT
17199
17200         # umount the first lustre mount
17201         umount $MOUNT
17202         stack_trap "mount_client $MOUNT" EXIT
17203
17204         # read changelog, which may or may not fail, but should not crash
17205         cat <&4 >/dev/null
17206
17207         # clear changelog
17208         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17209         changelog_users $SINGLEMDS | grep -q $cl_user ||
17210                 error "User $cl_user not found in changelog_users"
17211
17212         printf 'clear:'$cl_user':0' >&3
17213 }
17214 run_test 160j "client can be umounted while its chanangelog is being used"
17215
17216 test_160k() {
17217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17218         remote_mds_nodsh && skip "remote MDS with nodsh"
17219
17220         mkdir -p $DIR/$tdir/1/1
17221
17222         changelog_register || error "changelog_register failed"
17223         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17224
17225         changelog_users $SINGLEMDS | grep -q $cl_user ||
17226                 error "User '$cl_user' not found in changelog_users"
17227 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17228         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17229         rmdir $DIR/$tdir/1/1 & sleep 1
17230         mkdir $DIR/$tdir/2
17231         touch $DIR/$tdir/2/2
17232         rm -rf $DIR/$tdir/2
17233
17234         wait
17235         sleep 4
17236
17237         changelog_dump | grep rmdir || error "rmdir not recorded"
17238 }
17239 run_test 160k "Verify that changelog records are not lost"
17240
17241 # Verifies that a file passed as a parameter has recently had an operation
17242 # performed on it that has generated an MTIME changelog which contains the
17243 # correct parent FID. As files might reside on a different MDT from the
17244 # parent directory in DNE configurations, the FIDs are translated to paths
17245 # before being compared, which should be identical
17246 compare_mtime_changelog() {
17247         local file="${1}"
17248         local mdtidx
17249         local mtime
17250         local cl_fid
17251         local pdir
17252         local dir
17253
17254         mdtidx=$($LFS getstripe --mdt-index $file)
17255         mdtidx=$(printf "%04x" $mdtidx)
17256
17257         # Obtain the parent FID from the MTIME changelog
17258         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17259         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17260
17261         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17262         [ -z "$cl_fid" ] && error "parent FID not present"
17263
17264         # Verify that the path for the parent FID is the same as the path for
17265         # the test directory
17266         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17267
17268         dir=$(dirname $1)
17269
17270         [[ "${pdir%/}" == "$dir" ]] ||
17271                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17272 }
17273
17274 test_160l() {
17275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17276
17277         remote_mds_nodsh && skip "remote MDS with nodsh"
17278         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17279                 skip "Need MDS version at least 2.13.55"
17280
17281         local cl_user
17282
17283         changelog_register || error "changelog_register failed"
17284         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17285
17286         changelog_users $SINGLEMDS | grep -q $cl_user ||
17287                 error "User '$cl_user' not found in changelog_users"
17288
17289         # Clear some types so that MTIME changelogs are generated
17290         changelog_chmask "-CREAT"
17291         changelog_chmask "-CLOSE"
17292
17293         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17294
17295         # Test CL_MTIME during setattr
17296         touch $DIR/$tdir/$tfile
17297         compare_mtime_changelog $DIR/$tdir/$tfile
17298
17299         # Test CL_MTIME during close
17300         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17301         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17302 }
17303 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17304
17305 test_160m() {
17306         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17307         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17308                 skip "Need MDS version at least 2.14.51"
17309         local cl_users
17310         local cl_user1
17311         local cl_user2
17312         local pid1
17313
17314         # Create a user
17315         changelog_register || error "first changelog_register failed"
17316         changelog_register || error "second changelog_register failed"
17317
17318         cl_users=(${CL_USERS[mds1]})
17319         cl_user1="${cl_users[0]}"
17320         cl_user2="${cl_users[1]}"
17321         # generate some changelog records to accumulate on MDT0
17322         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17323         createmany -m $DIR/$tdir/$tfile 50 ||
17324                 error "create $DIR/$tdir/$tfile failed"
17325         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17326         rm -f $DIR/$tdir
17327
17328         # check changelogs have been generated
17329         local nbcl=$(changelog_dump | wc -l)
17330         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17331
17332 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17333         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17334
17335         __changelog_clear mds1 $cl_user1 +10
17336         __changelog_clear mds1 $cl_user2 0 &
17337         pid1=$!
17338         sleep 2
17339         __changelog_clear mds1 $cl_user1 0 ||
17340                 error "fail to cancel record for $cl_user1"
17341         wait $pid1
17342         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17343 }
17344 run_test 160m "Changelog clear race"
17345
17346 test_160n() {
17347         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17348         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17349                 skip "Need MDS version at least 2.14.51"
17350         local cl_users
17351         local cl_user1
17352         local cl_user2
17353         local pid1
17354         local first_rec
17355         local last_rec=0
17356
17357         # Create a user
17358         changelog_register || error "first changelog_register failed"
17359
17360         cl_users=(${CL_USERS[mds1]})
17361         cl_user1="${cl_users[0]}"
17362
17363         # generate some changelog records to accumulate on MDT0
17364         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17365         first_rec=$(changelog_users $SINGLEMDS |
17366                         awk '/^current.index:/ { print $NF }')
17367         while (( last_rec < (( first_rec + 65000)) )); do
17368                 createmany -m $DIR/$tdir/$tfile 10000 ||
17369                         error "create $DIR/$tdir/$tfile failed"
17370
17371                 for i in $(seq 0 10000); do
17372                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17373                                 > /dev/null
17374                 done
17375
17376                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17377                         error "unlinkmany failed unlink"
17378                 last_rec=$(changelog_users $SINGLEMDS |
17379                         awk '/^current.index:/ { print $NF }')
17380                 echo last record $last_rec
17381                 (( last_rec == 0 )) && error "no changelog found"
17382         done
17383
17384 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17385         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17386
17387         __changelog_clear mds1 $cl_user1 0 &
17388         pid1=$!
17389         sleep 2
17390         __changelog_clear mds1 $cl_user1 0 ||
17391                 error "fail to cancel record for $cl_user1"
17392         wait $pid1
17393         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17394 }
17395 run_test 160n "Changelog destroy race"
17396
17397 test_160o() {
17398         local mdt="$(facet_svc $SINGLEMDS)"
17399
17400         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17401         remote_mds_nodsh && skip "remote MDS with nodsh"
17402         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17403                 skip "Need MDS version at least 2.14.52"
17404
17405         changelog_register --user test_160o -m unlnk+close+open ||
17406                 error "changelog_register failed"
17407
17408         do_facet $SINGLEMDS $LCTL --device $mdt \
17409                                 changelog_register -u "Tt3_-#" &&
17410                 error "bad symbols in name should fail"
17411
17412         do_facet $SINGLEMDS $LCTL --device $mdt \
17413                                 changelog_register -u test_160o &&
17414                 error "the same name registration should fail"
17415
17416         do_facet $SINGLEMDS $LCTL --device $mdt \
17417                         changelog_register -u test_160toolongname &&
17418                 error "too long name registration should fail"
17419
17420         changelog_chmask "MARK+HSM"
17421         lctl get_param mdd.*.changelog*mask
17422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17423         changelog_users $SINGLEMDS | grep -q $cl_user ||
17424                 error "User $cl_user not found in changelog_users"
17425         #verify username
17426         echo $cl_user | grep -q test_160o ||
17427                 error "User $cl_user has no specific name 'test160o'"
17428
17429         # change something
17430         changelog_clear 0 || error "changelog_clear failed"
17431         # generate some changelog records to accumulate on MDT0
17432         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17433         touch $DIR/$tdir/$tfile                 # open 1
17434
17435         OPENS=$(changelog_dump | grep -c "OPEN")
17436         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17437
17438         # must be no MKDIR it wasn't set as user mask
17439         MKDIR=$(changelog_dump | grep -c "MKDIR")
17440         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17441
17442         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17443                                 mdd.$mdt.changelog_current_mask -n)
17444         # register maskless user
17445         changelog_register || error "changelog_register failed"
17446         # effective mask should be not changed because it is not minimal
17447         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17448                                 mdd.$mdt.changelog_current_mask -n)
17449         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17450         # set server mask to minimal value
17451         changelog_chmask "MARK"
17452         # check effective mask again, should be treated as DEFMASK now
17453         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17454                                 mdd.$mdt.changelog_current_mask -n)
17455         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17456
17457         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17458                 # set server mask back to some value
17459                 changelog_chmask "CLOSE,UNLNK"
17460                 # check effective mask again, should not remain as DEFMASK
17461                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17462                                 mdd.$mdt.changelog_current_mask -n)
17463                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17464         fi
17465
17466         do_facet $SINGLEMDS $LCTL --device $mdt \
17467                                 changelog_deregister -u test_160o ||
17468                 error "cannot deregister by name"
17469 }
17470 run_test 160o "changelog user name and mask"
17471
17472 test_160p() {
17473         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17474         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17475                 skip "Need MDS version at least 2.14.51"
17476         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17477         local cl_users
17478         local cl_user1
17479         local entry_count
17480
17481         # Create a user
17482         changelog_register || error "first changelog_register failed"
17483
17484         cl_users=(${CL_USERS[mds1]})
17485         cl_user1="${cl_users[0]}"
17486
17487         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17488         createmany -m $DIR/$tdir/$tfile 50 ||
17489                 error "create $DIR/$tdir/$tfile failed"
17490         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17491         rm -rf $DIR/$tdir
17492
17493         # check changelogs have been generated
17494         entry_count=$(changelog_dump | wc -l)
17495         ((entry_count != 0)) || error "no changelog entries found"
17496
17497         # remove changelog_users and check that orphan entries are removed
17498         stop mds1
17499         local dev=$(mdsdevname 1)
17500         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17501         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17502         entry_count=$(changelog_dump | wc -l)
17503         ((entry_count == 0)) ||
17504                 error "found $entry_count changelog entries, expected none"
17505 }
17506 run_test 160p "Changelog orphan cleanup with no users"
17507
17508 test_160q() {
17509         local mdt="$(facet_svc $SINGLEMDS)"
17510         local clu
17511
17512         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17513         remote_mds_nodsh && skip "remote MDS with nodsh"
17514         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17515                 skip "Need MDS version at least 2.14.54"
17516
17517         # set server mask to minimal value like server init does
17518         changelog_chmask "MARK"
17519         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17520                 error "changelog_register failed"
17521         # check effective mask again, should be treated as DEFMASK now
17522         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17523                                 mdd.$mdt.changelog_current_mask -n)
17524         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17525                 error "changelog_deregister failed"
17526         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17527 }
17528 run_test 160q "changelog effective mask is DEFMASK if not set"
17529
17530 test_160s() {
17531         remote_mds_nodsh && skip "remote MDS with nodsh"
17532         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17533                 skip "Need MDS version at least 2.14.55"
17534
17535         local mdts=$(comma_list $(mdts_nodes))
17536
17537         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17538         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17539                                        fail_val=$((24 * 3600 * 10))
17540
17541         # Create a user which is 10 days old
17542         changelog_register || error "first changelog_register failed"
17543         local cl_users
17544         declare -A cl_user1
17545         local i
17546
17547         # generate some changelog records to accumulate on each MDT
17548         # use all_char because created files should be evenly distributed
17549         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17550                 error "test_mkdir $tdir failed"
17551         for ((i = 0; i < MDSCOUNT; i++)); do
17552                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17553                         error "create $DIR/$tdir/d$i.1 failed"
17554         done
17555
17556         # check changelogs have been generated
17557         local nbcl=$(changelog_dump | wc -l)
17558         (( nbcl > 0 )) || error "no changelogs found"
17559
17560         # reduce the max_idle_indexes value to make sure we exceed it
17561         for param in "changelog_max_idle_indexes=2097446912" \
17562                      "changelog_max_idle_time=2592000" \
17563                      "changelog_gc=1" \
17564                      "changelog_min_gc_interval=2"; do
17565                 local MDT0=$(facet_svc $SINGLEMDS)
17566                 local var="${param%=*}"
17567                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17568
17569                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17570                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17571                         error "unable to set mdd.*.$param"
17572         done
17573
17574         local start=$SECONDS
17575         for i in $(seq $MDSCOUNT); do
17576                 cl_users=(${CL_USERS[mds$i]})
17577                 cl_user1[mds$i]="${cl_users[0]}"
17578
17579                 [[ -n "${cl_user1[mds$i]}" ]] ||
17580                         error "mds$i: no user registered"
17581         done
17582
17583         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17584         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17585
17586         # ensure we are past the previous changelog_min_gc_interval set above
17587         local sleep2=$((start + 2 - SECONDS))
17588         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17589
17590         # Generate one more changelog to trigger GC
17591         for ((i = 0; i < MDSCOUNT; i++)); do
17592                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17593                         error "create $DIR/$tdir/d$i.3 failed"
17594         done
17595
17596         # ensure gc thread is done
17597         for node in $(mdts_nodes); do
17598                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17599                         error "$node: GC-thread not done"
17600         done
17601
17602         do_nodes $mdts $LCTL set_param fail_loc=0
17603
17604         for (( i = 1; i <= MDSCOUNT; i++ )); do
17605                 # check cl_user1 is purged
17606                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17607                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17608         done
17609         return 0
17610 }
17611 run_test 160s "changelog garbage collect on idle records * time"
17612
17613 test_160t() {
17614         remote_mds_nodsh && skip "remote MDS with nodsh"
17615         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17616                 skip "Need MDS version at least 2.15.50"
17617
17618         local MDT0=$(facet_svc $SINGLEMDS)
17619         local cl_users
17620         local cl_user1
17621         local cl_user2
17622         local start
17623
17624         changelog_register --user user1 -m all ||
17625                 error "user1 failed to register"
17626
17627         mkdir_on_mdt0 $DIR/$tdir
17628         # create default overstripe to maximize changelog size
17629         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17630         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17631         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17632
17633         # user2 consumes less records so less space
17634         changelog_register --user user2 || error "user2 failed to register"
17635         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17636         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17637
17638         # check changelogs have been generated
17639         local nbcl=$(changelog_dump | wc -l)
17640         (( nbcl > 0 )) || error "no changelogs found"
17641
17642         # reduce the changelog_min_gc_interval to force check
17643         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17644                 local var="${param%=*}"
17645                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17646
17647                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17648                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17649                         error "unable to set mdd.*.$param"
17650         done
17651
17652         start=$SECONDS
17653         cl_users=(${CL_USERS[mds1]})
17654         cl_user1="${cl_users[0]}"
17655         cl_user2="${cl_users[1]}"
17656
17657         [[ -n $cl_user1 ]] ||
17658                 error "mds1: user #1 isn't registered"
17659         [[ -n $cl_user2 ]] ||
17660                 error "mds1: user #2 isn't registered"
17661
17662         # ensure we are past the previous changelog_min_gc_interval set above
17663         local sleep2=$((start + 2 - SECONDS))
17664         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17665
17666         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17667         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17668                         fail_val=$(((llog_size1 + llog_size2) / 2))
17669
17670         # Generate more changelog to trigger GC
17671         createmany -o $DIR/$tdir/u3_ 4 ||
17672                 error "create failed for more files"
17673
17674         # ensure gc thread is done
17675         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17676                 error "mds1: GC-thread not done"
17677
17678         do_facet mds1 $LCTL set_param fail_loc=0
17679
17680         # check cl_user1 is purged
17681         changelog_users mds1 | grep -q "$cl_user1" &&
17682                 error "User $cl_user1 is registered"
17683         # check cl_user2 is not purged
17684         changelog_users mds1 | grep -q "$cl_user2" ||
17685                 error "User $cl_user2 is not registered"
17686 }
17687 run_test 160t "changelog garbage collect on lack of space"
17688
17689 test_161a() {
17690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17691
17692         test_mkdir -c1 $DIR/$tdir
17693         cp /etc/hosts $DIR/$tdir/$tfile
17694         test_mkdir -c1 $DIR/$tdir/foo1
17695         test_mkdir -c1 $DIR/$tdir/foo2
17696         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17697         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17698         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17699         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17700         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17701         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17702                 $LFS fid2path $DIR $FID
17703                 error "bad link ea"
17704         fi
17705         # middle
17706         rm $DIR/$tdir/foo2/zachary
17707         # last
17708         rm $DIR/$tdir/foo2/thor
17709         # first
17710         rm $DIR/$tdir/$tfile
17711         # rename
17712         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17713         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17714                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17715         rm $DIR/$tdir/foo2/maggie
17716
17717         # overflow the EA
17718         local longname=$tfile.avg_len_is_thirty_two_
17719         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17720                 error_noexit 'failed to unlink many hardlinks'" EXIT
17721         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17722                 error "failed to hardlink many files"
17723         links=$($LFS fid2path $DIR $FID | wc -l)
17724         echo -n "${links}/1000 links in link EA"
17725         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17726 }
17727 run_test 161a "link ea sanity"
17728
17729 test_161b() {
17730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17731         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17732
17733         local MDTIDX=1
17734         local remote_dir=$DIR/$tdir/remote_dir
17735
17736         mkdir -p $DIR/$tdir
17737         $LFS mkdir -i $MDTIDX $remote_dir ||
17738                 error "create remote directory failed"
17739
17740         cp /etc/hosts $remote_dir/$tfile
17741         mkdir -p $remote_dir/foo1
17742         mkdir -p $remote_dir/foo2
17743         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17744         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17745         ln $remote_dir/$tfile $remote_dir/foo1/luna
17746         ln $remote_dir/$tfile $remote_dir/foo2/thor
17747
17748         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17749                      tr -d ']')
17750         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17751                 $LFS fid2path $DIR $FID
17752                 error "bad link ea"
17753         fi
17754         # middle
17755         rm $remote_dir/foo2/zachary
17756         # last
17757         rm $remote_dir/foo2/thor
17758         # first
17759         rm $remote_dir/$tfile
17760         # rename
17761         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17762         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17763         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17764                 $LFS fid2path $DIR $FID
17765                 error "bad link rename"
17766         fi
17767         rm $remote_dir/foo2/maggie
17768
17769         # overflow the EA
17770         local longname=filename_avg_len_is_thirty_two_
17771         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17772                 error "failed to hardlink many files"
17773         links=$($LFS fid2path $DIR $FID | wc -l)
17774         echo -n "${links}/1000 links in link EA"
17775         [[ ${links} -gt 60 ]] ||
17776                 error "expected at least 60 links in link EA"
17777         unlinkmany $remote_dir/foo2/$longname 1000 ||
17778         error "failed to unlink many hardlinks"
17779 }
17780 run_test 161b "link ea sanity under remote directory"
17781
17782 test_161c() {
17783         remote_mds_nodsh && skip "remote MDS with nodsh"
17784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17785         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17786                 skip "Need MDS version at least 2.1.5"
17787
17788         # define CLF_RENAME_LAST 0x0001
17789         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17790         changelog_register || error "changelog_register failed"
17791
17792         rm -rf $DIR/$tdir
17793         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17794         touch $DIR/$tdir/foo_161c
17795         touch $DIR/$tdir/bar_161c
17796         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17797         changelog_dump | grep RENME | tail -n 5
17798         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17799         changelog_clear 0 || error "changelog_clear failed"
17800         if [ x$flags != "x0x1" ]; then
17801                 error "flag $flags is not 0x1"
17802         fi
17803
17804         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17805         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17806         touch $DIR/$tdir/foo_161c
17807         touch $DIR/$tdir/bar_161c
17808         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17809         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17810         changelog_dump | grep RENME | tail -n 5
17811         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17812         changelog_clear 0 || error "changelog_clear failed"
17813         if [ x$flags != "x0x0" ]; then
17814                 error "flag $flags is not 0x0"
17815         fi
17816         echo "rename overwrite a target having nlink > 1," \
17817                 "changelog record has flags of $flags"
17818
17819         # rename doesn't overwrite a target (changelog flag 0x0)
17820         touch $DIR/$tdir/foo_161c
17821         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17822         changelog_dump | grep RENME | tail -n 5
17823         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17824         changelog_clear 0 || error "changelog_clear failed"
17825         if [ x$flags != "x0x0" ]; then
17826                 error "flag $flags is not 0x0"
17827         fi
17828         echo "rename doesn't overwrite a target," \
17829                 "changelog record has flags of $flags"
17830
17831         # define CLF_UNLINK_LAST 0x0001
17832         # unlink a file having nlink = 1 (changelog flag 0x1)
17833         rm -f $DIR/$tdir/foo2_161c
17834         changelog_dump | grep UNLNK | tail -n 5
17835         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17836         changelog_clear 0 || error "changelog_clear failed"
17837         if [ x$flags != "x0x1" ]; then
17838                 error "flag $flags is not 0x1"
17839         fi
17840         echo "unlink a file having nlink = 1," \
17841                 "changelog record has flags of $flags"
17842
17843         # unlink a file having nlink > 1 (changelog flag 0x0)
17844         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17845         rm -f $DIR/$tdir/foobar_161c
17846         changelog_dump | grep UNLNK | tail -n 5
17847         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17848         changelog_clear 0 || error "changelog_clear failed"
17849         if [ x$flags != "x0x0" ]; then
17850                 error "flag $flags is not 0x0"
17851         fi
17852         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17853 }
17854 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17855
17856 test_161d() {
17857         remote_mds_nodsh && skip "remote MDS with nodsh"
17858         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17859
17860         local pid
17861         local fid
17862
17863         changelog_register || error "changelog_register failed"
17864
17865         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17866         # interfer with $MOUNT/.lustre/fid/ access
17867         mkdir $DIR/$tdir
17868         [[ $? -eq 0 ]] || error "mkdir failed"
17869
17870         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17871         $LCTL set_param fail_loc=0x8000140c
17872         # 5s pause
17873         $LCTL set_param fail_val=5
17874
17875         # create file
17876         echo foofoo > $DIR/$tdir/$tfile &
17877         pid=$!
17878
17879         # wait for create to be delayed
17880         sleep 2
17881
17882         ps -p $pid
17883         [[ $? -eq 0 ]] || error "create should be blocked"
17884
17885         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17886         stack_trap "rm -f $tempfile"
17887         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17888         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17889         # some delay may occur during ChangeLog publishing and file read just
17890         # above, that could allow file write to happen finally
17891         [[ -s $tempfile ]] && echo "file should be empty"
17892
17893         $LCTL set_param fail_loc=0
17894
17895         wait $pid
17896         [[ $? -eq 0 ]] || error "create failed"
17897 }
17898 run_test 161d "create with concurrent .lustre/fid access"
17899
17900 check_path() {
17901         local expected="$1"
17902         shift
17903         local fid="$2"
17904
17905         local path
17906         path=$($LFS fid2path "$@")
17907         local rc=$?
17908
17909         if [ $rc -ne 0 ]; then
17910                 error "path looked up of '$expected' failed: rc=$rc"
17911         elif [ "$path" != "$expected" ]; then
17912                 error "path looked up '$path' instead of '$expected'"
17913         else
17914                 echo "FID '$fid' resolves to path '$path' as expected"
17915         fi
17916 }
17917
17918 test_162a() { # was test_162
17919         test_mkdir -p -c1 $DIR/$tdir/d2
17920         touch $DIR/$tdir/d2/$tfile
17921         touch $DIR/$tdir/d2/x1
17922         touch $DIR/$tdir/d2/x2
17923         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17924         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17925         # regular file
17926         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17927         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17928
17929         # softlink
17930         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17931         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17932         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17933
17934         # softlink to wrong file
17935         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17936         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17937         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17938
17939         # hardlink
17940         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17941         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17942         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17943         # fid2path dir/fsname should both work
17944         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17945         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17946
17947         # hardlink count: check that there are 2 links
17948         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17949         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17950
17951         # hardlink indexing: remove the first link
17952         rm $DIR/$tdir/d2/p/q/r/hlink
17953         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17954 }
17955 run_test 162a "path lookup sanity"
17956
17957 test_162b() {
17958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17960
17961         mkdir $DIR/$tdir
17962         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17963                                 error "create striped dir failed"
17964
17965         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17966                                         tail -n 1 | awk '{print $2}')
17967         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17968
17969         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17970         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17971
17972         # regular file
17973         for ((i=0;i<5;i++)); do
17974                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17975                         error "get fid for f$i failed"
17976                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17977
17978                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17979                         error "get fid for d$i failed"
17980                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17981         done
17982
17983         return 0
17984 }
17985 run_test 162b "striped directory path lookup sanity"
17986
17987 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17988 test_162c() {
17989         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17990                 skip "Need MDS version at least 2.7.51"
17991
17992         local lpath=$tdir.local
17993         local rpath=$tdir.remote
17994
17995         test_mkdir $DIR/$lpath
17996         test_mkdir $DIR/$rpath
17997
17998         for ((i = 0; i <= 101; i++)); do
17999                 lpath="$lpath/$i"
18000                 mkdir $DIR/$lpath
18001                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18002                         error "get fid for local directory $DIR/$lpath failed"
18003                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18004
18005                 rpath="$rpath/$i"
18006                 test_mkdir $DIR/$rpath
18007                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18008                         error "get fid for remote directory $DIR/$rpath failed"
18009                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18010         done
18011
18012         return 0
18013 }
18014 run_test 162c "fid2path works with paths 100 or more directories deep"
18015
18016 oalr_event_count() {
18017         local event="${1}"
18018         local trace="${2}"
18019
18020         awk -v name="${FSNAME}-OST0000" \
18021             -v event="${event}" \
18022             '$1 == "TRACE" && $2 == event && $3 == name' \
18023             "${trace}" |
18024         wc -l
18025 }
18026
18027 oalr_expect_event_count() {
18028         local event="${1}"
18029         local trace="${2}"
18030         local expect="${3}"
18031         local count
18032
18033         count=$(oalr_event_count "${event}" "${trace}")
18034         if ((count == expect)); then
18035                 return 0
18036         fi
18037
18038         error_noexit "${event} event count was '${count}', expected ${expect}"
18039         cat "${trace}" >&2
18040         exit 1
18041 }
18042
18043 cleanup_165() {
18044         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18045         stop ost1
18046         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18047 }
18048
18049 setup_165() {
18050         sync # Flush previous IOs so we can count log entries.
18051         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18052         stack_trap cleanup_165 EXIT
18053 }
18054
18055 test_165a() {
18056         local trace="/tmp/${tfile}.trace"
18057         local rc
18058         local count
18059
18060         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18061                 skip "OFD access log unsupported"
18062
18063         setup_165
18064         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18065         sleep 5
18066
18067         do_facet ost1 ofd_access_log_reader --list
18068         stop ost1
18069
18070         do_facet ost1 killall -TERM ofd_access_log_reader
18071         wait
18072         rc=$?
18073
18074         if ((rc != 0)); then
18075                 error "ofd_access_log_reader exited with rc = '${rc}'"
18076         fi
18077
18078         # Parse trace file for discovery events:
18079         oalr_expect_event_count alr_log_add "${trace}" 1
18080         oalr_expect_event_count alr_log_eof "${trace}" 1
18081         oalr_expect_event_count alr_log_free "${trace}" 1
18082 }
18083 run_test 165a "ofd access log discovery"
18084
18085 test_165b() {
18086         local trace="/tmp/${tfile}.trace"
18087         local file="${DIR}/${tfile}"
18088         local pfid1
18089         local pfid2
18090         local -a entry
18091         local rc
18092         local count
18093         local size
18094         local flags
18095
18096         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18097                 skip "OFD access log unsupported"
18098
18099         setup_165
18100         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18101         sleep 5
18102
18103         do_facet ost1 ofd_access_log_reader --list
18104
18105         lfs setstripe -c 1 -i 0 "${file}"
18106         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18107                 error "cannot create '${file}'"
18108
18109         sleep 5
18110         do_facet ost1 killall -TERM ofd_access_log_reader
18111         wait
18112         rc=$?
18113
18114         if ((rc != 0)); then
18115                 error "ofd_access_log_reader exited with rc = '${rc}'"
18116         fi
18117
18118         oalr_expect_event_count alr_log_entry "${trace}" 1
18119
18120         pfid1=$($LFS path2fid "${file}")
18121
18122         # 1     2             3   4    5     6   7    8    9     10
18123         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18124         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18125
18126         echo "entry = '${entry[*]}'" >&2
18127
18128         pfid2=${entry[4]}
18129         if [[ "${pfid1}" != "${pfid2}" ]]; then
18130                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18131         fi
18132
18133         size=${entry[8]}
18134         if ((size != 1048576)); then
18135                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18136         fi
18137
18138         flags=${entry[10]}
18139         if [[ "${flags}" != "w" ]]; then
18140                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18141         fi
18142
18143         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18144         sleep 5
18145
18146         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18147                 error "cannot read '${file}'"
18148         sleep 5
18149
18150         do_facet ost1 killall -TERM ofd_access_log_reader
18151         wait
18152         rc=$?
18153
18154         if ((rc != 0)); then
18155                 error "ofd_access_log_reader exited with rc = '${rc}'"
18156         fi
18157
18158         oalr_expect_event_count alr_log_entry "${trace}" 1
18159
18160         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18161         echo "entry = '${entry[*]}'" >&2
18162
18163         pfid2=${entry[4]}
18164         if [[ "${pfid1}" != "${pfid2}" ]]; then
18165                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18166         fi
18167
18168         size=${entry[8]}
18169         if ((size != 524288)); then
18170                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18171         fi
18172
18173         flags=${entry[10]}
18174         if [[ "${flags}" != "r" ]]; then
18175                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18176         fi
18177 }
18178 run_test 165b "ofd access log entries are produced and consumed"
18179
18180 test_165c() {
18181         local trace="/tmp/${tfile}.trace"
18182         local file="${DIR}/${tdir}/${tfile}"
18183
18184         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18185                 skip "OFD access log unsupported"
18186
18187         test_mkdir "${DIR}/${tdir}"
18188
18189         setup_165
18190         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18191         sleep 5
18192
18193         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18194
18195         # 4096 / 64 = 64. Create twice as many entries.
18196         for ((i = 0; i < 128; i++)); do
18197                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18198                         error "cannot create file"
18199         done
18200
18201         sync
18202
18203         do_facet ost1 killall -TERM ofd_access_log_reader
18204         wait
18205         rc=$?
18206         if ((rc != 0)); then
18207                 error "ofd_access_log_reader exited with rc = '${rc}'"
18208         fi
18209
18210         unlinkmany  "${file}-%d" 128
18211 }
18212 run_test 165c "full ofd access logs do not block IOs"
18213
18214 oal_get_read_count() {
18215         local stats="$1"
18216
18217         # STATS lustre-OST0001 alr_read_count 1
18218
18219         do_facet ost1 cat "${stats}" |
18220         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18221              END { print count; }'
18222 }
18223
18224 oal_expect_read_count() {
18225         local stats="$1"
18226         local count
18227         local expect="$2"
18228
18229         # Ask ofd_access_log_reader to write stats.
18230         do_facet ost1 killall -USR1 ofd_access_log_reader
18231
18232         # Allow some time for things to happen.
18233         sleep 1
18234
18235         count=$(oal_get_read_count "${stats}")
18236         if ((count == expect)); then
18237                 return 0
18238         fi
18239
18240         error_noexit "bad read count, got ${count}, expected ${expect}"
18241         do_facet ost1 cat "${stats}" >&2
18242         exit 1
18243 }
18244
18245 test_165d() {
18246         local stats="/tmp/${tfile}.stats"
18247         local file="${DIR}/${tdir}/${tfile}"
18248         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18249
18250         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18251                 skip "OFD access log unsupported"
18252
18253         test_mkdir "${DIR}/${tdir}"
18254
18255         setup_165
18256         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18257         sleep 5
18258
18259         lfs setstripe -c 1 -i 0 "${file}"
18260
18261         do_facet ost1 lctl set_param "${param}=rw"
18262         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18263                 error "cannot create '${file}'"
18264         oal_expect_read_count "${stats}" 1
18265
18266         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18267                 error "cannot read '${file}'"
18268         oal_expect_read_count "${stats}" 2
18269
18270         do_facet ost1 lctl set_param "${param}=r"
18271         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18272                 error "cannot create '${file}'"
18273         oal_expect_read_count "${stats}" 2
18274
18275         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18276                 error "cannot read '${file}'"
18277         oal_expect_read_count "${stats}" 3
18278
18279         do_facet ost1 lctl set_param "${param}=w"
18280         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18281                 error "cannot create '${file}'"
18282         oal_expect_read_count "${stats}" 4
18283
18284         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18285                 error "cannot read '${file}'"
18286         oal_expect_read_count "${stats}" 4
18287
18288         do_facet ost1 lctl set_param "${param}=0"
18289         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18290                 error "cannot create '${file}'"
18291         oal_expect_read_count "${stats}" 4
18292
18293         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18294                 error "cannot read '${file}'"
18295         oal_expect_read_count "${stats}" 4
18296
18297         do_facet ost1 killall -TERM ofd_access_log_reader
18298         wait
18299         rc=$?
18300         if ((rc != 0)); then
18301                 error "ofd_access_log_reader exited with rc = '${rc}'"
18302         fi
18303 }
18304 run_test 165d "ofd_access_log mask works"
18305
18306 test_165e() {
18307         local stats="/tmp/${tfile}.stats"
18308         local file0="${DIR}/${tdir}-0/${tfile}"
18309         local file1="${DIR}/${tdir}-1/${tfile}"
18310
18311         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18312                 skip "OFD access log unsupported"
18313
18314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18315
18316         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18317         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18318
18319         lfs setstripe -c 1 -i 0 "${file0}"
18320         lfs setstripe -c 1 -i 0 "${file1}"
18321
18322         setup_165
18323         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18324         sleep 5
18325
18326         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18327                 error "cannot create '${file0}'"
18328         sync
18329         oal_expect_read_count "${stats}" 0
18330
18331         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18332                 error "cannot create '${file1}'"
18333         sync
18334         oal_expect_read_count "${stats}" 1
18335
18336         do_facet ost1 killall -TERM ofd_access_log_reader
18337         wait
18338         rc=$?
18339         if ((rc != 0)); then
18340                 error "ofd_access_log_reader exited with rc = '${rc}'"
18341         fi
18342 }
18343 run_test 165e "ofd_access_log MDT index filter works"
18344
18345 test_165f() {
18346         local trace="/tmp/${tfile}.trace"
18347         local rc
18348         local count
18349
18350         setup_165
18351         do_facet ost1 timeout 60 ofd_access_log_reader \
18352                 --exit-on-close --debug=- --trace=- > "${trace}" &
18353         sleep 5
18354         stop ost1
18355
18356         wait
18357         rc=$?
18358
18359         if ((rc != 0)); then
18360                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18361                 cat "${trace}"
18362                 exit 1
18363         fi
18364 }
18365 run_test 165f "ofd_access_log_reader --exit-on-close works"
18366
18367 test_169() {
18368         # do directio so as not to populate the page cache
18369         log "creating a 10 Mb file"
18370         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18371                 error "multiop failed while creating a file"
18372         log "starting reads"
18373         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18374         log "truncating the file"
18375         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18376                 error "multiop failed while truncating the file"
18377         log "killing dd"
18378         kill %+ || true # reads might have finished
18379         echo "wait until dd is finished"
18380         wait
18381         log "removing the temporary file"
18382         rm -rf $DIR/$tfile || error "tmp file removal failed"
18383 }
18384 run_test 169 "parallel read and truncate should not deadlock"
18385
18386 test_170() {
18387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18388
18389         $LCTL clear     # bug 18514
18390         $LCTL debug_daemon start $TMP/${tfile}_log_good
18391         touch $DIR/$tfile
18392         $LCTL debug_daemon stop
18393         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18394                 error "sed failed to read log_good"
18395
18396         $LCTL debug_daemon start $TMP/${tfile}_log_good
18397         rm -rf $DIR/$tfile
18398         $LCTL debug_daemon stop
18399
18400         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18401                error "lctl df log_bad failed"
18402
18403         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18404         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18405
18406         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18407         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18408
18409         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18410                 error "bad_line good_line1 good_line2 are empty"
18411
18412         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18413         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18414         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18415
18416         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18417         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18418         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18419
18420         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18421                 error "bad_line_new good_line_new are empty"
18422
18423         local expected_good=$((good_line1 + good_line2*2))
18424
18425         rm -f $TMP/${tfile}*
18426         # LU-231, short malformed line may not be counted into bad lines
18427         if [ $bad_line -ne $bad_line_new ] &&
18428                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18429                 error "expected $bad_line bad lines, but got $bad_line_new"
18430                 return 1
18431         fi
18432
18433         if [ $expected_good -ne $good_line_new ]; then
18434                 error "expected $expected_good good lines, but got $good_line_new"
18435                 return 2
18436         fi
18437         true
18438 }
18439 run_test 170 "test lctl df to handle corrupted log ====================="
18440
18441 test_171() { # bug20592
18442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18443
18444         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18445         $LCTL set_param fail_loc=0x50e
18446         $LCTL set_param fail_val=3000
18447         multiop_bg_pause $DIR/$tfile O_s || true
18448         local MULTIPID=$!
18449         kill -USR1 $MULTIPID
18450         # cause log dump
18451         sleep 3
18452         wait $MULTIPID
18453         if dmesg | grep "recursive fault"; then
18454                 error "caught a recursive fault"
18455         fi
18456         $LCTL set_param fail_loc=0
18457         true
18458 }
18459 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18460
18461 test_172() {
18462
18463         #define OBD_FAIL_OBD_CLEANUP  0x60e
18464         $LCTL set_param fail_loc=0x60e
18465         umount $MOUNT || error "umount $MOUNT failed"
18466         stack_trap "mount_client $MOUNT"
18467
18468         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18469                 error "no client OBDs are remained"
18470
18471         $LCTL dl | while read devno state type name foo; do
18472                 case $type in
18473                 lov|osc|lmv|mdc)
18474                         $LCTL --device $name cleanup
18475                         $LCTL --device $name detach
18476                         ;;
18477                 *)
18478                         # skip server devices
18479                         ;;
18480                 esac
18481         done
18482
18483         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18484                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18485                 error "some client OBDs are still remained"
18486         fi
18487
18488 }
18489 run_test 172 "manual device removal with lctl cleanup/detach ======"
18490
18491 # it would be good to share it with obdfilter-survey/iokit-libecho code
18492 setup_obdecho_osc () {
18493         local rc=0
18494         local ost_nid=$1
18495         local obdfilter_name=$2
18496         echo "Creating new osc for $obdfilter_name on $ost_nid"
18497         # make sure we can find loopback nid
18498         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18499
18500         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18501                            ${obdfilter_name}_osc_UUID || rc=2; }
18502         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18503                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18504         return $rc
18505 }
18506
18507 cleanup_obdecho_osc () {
18508         local obdfilter_name=$1
18509         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18510         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18511         return 0
18512 }
18513
18514 obdecho_test() {
18515         local OBD=$1
18516         local node=$2
18517         local pages=${3:-64}
18518         local rc=0
18519         local id
18520
18521         local count=10
18522         local obd_size=$(get_obd_size $node $OBD)
18523         local page_size=$(get_page_size $node)
18524         if [[ -n "$obd_size" ]]; then
18525                 local new_count=$((obd_size / (pages * page_size / 1024)))
18526                 [[ $new_count -ge $count ]] || count=$new_count
18527         fi
18528
18529         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18530         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18531                            rc=2; }
18532         if [ $rc -eq 0 ]; then
18533             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18534             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18535         fi
18536         echo "New object id is $id"
18537         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18538                            rc=4; }
18539         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18540                            "test_brw $count w v $pages $id" || rc=4; }
18541         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18542                            rc=4; }
18543         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18544                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18545         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18546                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18547         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18548         return $rc
18549 }
18550
18551 test_180a() {
18552         skip "obdecho on osc is no longer supported"
18553 }
18554 run_test 180a "test obdecho on osc"
18555
18556 test_180b() {
18557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18558         remote_ost_nodsh && skip "remote OST with nodsh"
18559
18560         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18561                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18562                 error "failed to load module obdecho"
18563
18564         local target=$(do_facet ost1 $LCTL dl |
18565                        awk '/obdfilter/ { print $4; exit; }')
18566
18567         if [ -n "$target" ]; then
18568                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18569         else
18570                 do_facet ost1 $LCTL dl
18571                 error "there is no obdfilter target on ost1"
18572         fi
18573 }
18574 run_test 180b "test obdecho directly on obdfilter"
18575
18576 test_180c() { # LU-2598
18577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18578         remote_ost_nodsh && skip "remote OST with nodsh"
18579         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18580                 skip "Need MDS version at least 2.4.0"
18581
18582         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18583                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18584                 error "failed to load module obdecho"
18585
18586         local target=$(do_facet ost1 $LCTL dl |
18587                        awk '/obdfilter/ { print $4; exit; }')
18588
18589         if [ -n "$target" ]; then
18590                 local pages=16384 # 64MB bulk I/O RPC size
18591
18592                 obdecho_test "$target" ost1 "$pages" ||
18593                         error "obdecho_test with pages=$pages failed with $?"
18594         else
18595                 do_facet ost1 $LCTL dl
18596                 error "there is no obdfilter target on ost1"
18597         fi
18598 }
18599 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18600
18601 test_181() { # bug 22177
18602         test_mkdir $DIR/$tdir
18603         # create enough files to index the directory
18604         createmany -o $DIR/$tdir/foobar 4000
18605         # print attributes for debug purpose
18606         lsattr -d .
18607         # open dir
18608         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18609         MULTIPID=$!
18610         # remove the files & current working dir
18611         unlinkmany $DIR/$tdir/foobar 4000
18612         rmdir $DIR/$tdir
18613         kill -USR1 $MULTIPID
18614         wait $MULTIPID
18615         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18616         return 0
18617 }
18618 run_test 181 "Test open-unlinked dir ========================"
18619
18620 test_182a() {
18621         local fcount=1000
18622         local tcount=10
18623
18624         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18625
18626         $LCTL set_param mdc.*.rpc_stats=clear
18627
18628         for (( i = 0; i < $tcount; i++ )) ; do
18629                 mkdir $DIR/$tdir/$i
18630         done
18631
18632         for (( i = 0; i < $tcount; i++ )) ; do
18633                 createmany -o $DIR/$tdir/$i/f- $fcount &
18634         done
18635         wait
18636
18637         for (( i = 0; i < $tcount; i++ )) ; do
18638                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18639         done
18640         wait
18641
18642         $LCTL get_param mdc.*.rpc_stats
18643
18644         rm -rf $DIR/$tdir
18645 }
18646 run_test 182a "Test parallel modify metadata operations from mdc"
18647
18648 test_182b() {
18649         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18650         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18651         local dcount=1000
18652         local tcount=10
18653         local stime
18654         local etime
18655         local delta
18656
18657         do_facet mds1 $LCTL list_param \
18658                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18659                 skip "MDS lacks parallel RPC handling"
18660
18661         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18662
18663         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18664                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18665
18666         stime=$(date +%s)
18667         createmany -i 0 -d $DIR/$tdir/t- $tcount
18668
18669         for (( i = 0; i < $tcount; i++ )) ; do
18670                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18671         done
18672         wait
18673         etime=$(date +%s)
18674         delta=$((etime - stime))
18675         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18676
18677         stime=$(date +%s)
18678         for (( i = 0; i < $tcount; i++ )) ; do
18679                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18680         done
18681         wait
18682         etime=$(date +%s)
18683         delta=$((etime - stime))
18684         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18685
18686         rm -rf $DIR/$tdir
18687
18688         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18689
18690         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18691
18692         stime=$(date +%s)
18693         createmany -i 0 -d $DIR/$tdir/t- $tcount
18694
18695         for (( i = 0; i < $tcount; i++ )) ; do
18696                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18697         done
18698         wait
18699         etime=$(date +%s)
18700         delta=$((etime - stime))
18701         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18702
18703         stime=$(date +%s)
18704         for (( i = 0; i < $tcount; i++ )) ; do
18705                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18706         done
18707         wait
18708         etime=$(date +%s)
18709         delta=$((etime - stime))
18710         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18711
18712         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18713 }
18714 run_test 182b "Test parallel modify metadata operations from osp"
18715
18716 test_183() { # LU-2275
18717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18718         remote_mds_nodsh && skip "remote MDS with nodsh"
18719         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18720                 skip "Need MDS version at least 2.3.56"
18721
18722         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18723         echo aaa > $DIR/$tdir/$tfile
18724
18725 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18726         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18727
18728         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18729         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18730
18731         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18732
18733         # Flush negative dentry cache
18734         touch $DIR/$tdir/$tfile
18735
18736         # We are not checking for any leaked references here, they'll
18737         # become evident next time we do cleanup with module unload.
18738         rm -rf $DIR/$tdir
18739 }
18740 run_test 183 "No crash or request leak in case of strange dispositions ========"
18741
18742 # test suite 184 is for LU-2016, LU-2017
18743 test_184a() {
18744         check_swap_layouts_support
18745
18746         dir0=$DIR/$tdir/$testnum
18747         test_mkdir -p -c1 $dir0
18748         ref1=/etc/passwd
18749         ref2=/etc/group
18750         file1=$dir0/f1
18751         file2=$dir0/f2
18752         $LFS setstripe -c1 $file1
18753         cp $ref1 $file1
18754         $LFS setstripe -c2 $file2
18755         cp $ref2 $file2
18756         gen1=$($LFS getstripe -g $file1)
18757         gen2=$($LFS getstripe -g $file2)
18758
18759         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18760         gen=$($LFS getstripe -g $file1)
18761         [[ $gen1 != $gen ]] ||
18762                 error "Layout generation on $file1 does not change"
18763         gen=$($LFS getstripe -g $file2)
18764         [[ $gen2 != $gen ]] ||
18765                 error "Layout generation on $file2 does not change"
18766
18767         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18768         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18769
18770         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18771 }
18772 run_test 184a "Basic layout swap"
18773
18774 test_184b() {
18775         check_swap_layouts_support
18776
18777         dir0=$DIR/$tdir/$testnum
18778         mkdir -p $dir0 || error "creating dir $dir0"
18779         file1=$dir0/f1
18780         file2=$dir0/f2
18781         file3=$dir0/f3
18782         dir1=$dir0/d1
18783         dir2=$dir0/d2
18784         mkdir $dir1 $dir2
18785         $LFS setstripe -c1 $file1
18786         $LFS setstripe -c2 $file2
18787         $LFS setstripe -c1 $file3
18788         chown $RUNAS_ID $file3
18789         gen1=$($LFS getstripe -g $file1)
18790         gen2=$($LFS getstripe -g $file2)
18791
18792         $LFS swap_layouts $dir1 $dir2 &&
18793                 error "swap of directories layouts should fail"
18794         $LFS swap_layouts $dir1 $file1 &&
18795                 error "swap of directory and file layouts should fail"
18796         $RUNAS $LFS swap_layouts $file1 $file2 &&
18797                 error "swap of file we cannot write should fail"
18798         $LFS swap_layouts $file1 $file3 &&
18799                 error "swap of file with different owner should fail"
18800         /bin/true # to clear error code
18801 }
18802 run_test 184b "Forbidden layout swap (will generate errors)"
18803
18804 test_184c() {
18805         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18806         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18807         check_swap_layouts_support
18808         check_swap_layout_no_dom $DIR
18809
18810         local dir0=$DIR/$tdir/$testnum
18811         mkdir -p $dir0 || error "creating dir $dir0"
18812
18813         local ref1=$dir0/ref1
18814         local ref2=$dir0/ref2
18815         local file1=$dir0/file1
18816         local file2=$dir0/file2
18817         # create a file large enough for the concurrent test
18818         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18819         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18820         echo "ref file size: ref1($(stat -c %s $ref1))," \
18821              "ref2($(stat -c %s $ref2))"
18822
18823         cp $ref2 $file2
18824         dd if=$ref1 of=$file1 bs=16k &
18825         local DD_PID=$!
18826
18827         # Make sure dd starts to copy file, but wait at most 5 seconds
18828         local loops=0
18829         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18830
18831         $LFS swap_layouts $file1 $file2
18832         local rc=$?
18833         wait $DD_PID
18834         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18835         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18836
18837         # how many bytes copied before swapping layout
18838         local copied=$(stat -c %s $file2)
18839         local remaining=$(stat -c %s $ref1)
18840         remaining=$((remaining - copied))
18841         echo "Copied $copied bytes before swapping layout..."
18842
18843         cmp -n $copied $file1 $ref2 | grep differ &&
18844                 error "Content mismatch [0, $copied) of ref2 and file1"
18845         cmp -n $copied $file2 $ref1 ||
18846                 error "Content mismatch [0, $copied) of ref1 and file2"
18847         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18848                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18849
18850         # clean up
18851         rm -f $ref1 $ref2 $file1 $file2
18852 }
18853 run_test 184c "Concurrent write and layout swap"
18854
18855 test_184d() {
18856         check_swap_layouts_support
18857         check_swap_layout_no_dom $DIR
18858         [ -z "$(which getfattr 2>/dev/null)" ] &&
18859                 skip_env "no getfattr command"
18860
18861         local file1=$DIR/$tdir/$tfile-1
18862         local file2=$DIR/$tdir/$tfile-2
18863         local file3=$DIR/$tdir/$tfile-3
18864         local lovea1
18865         local lovea2
18866
18867         mkdir -p $DIR/$tdir
18868         touch $file1 || error "create $file1 failed"
18869         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18870                 error "create $file2 failed"
18871         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18872                 error "create $file3 failed"
18873         lovea1=$(get_layout_param $file1)
18874
18875         $LFS swap_layouts $file2 $file3 ||
18876                 error "swap $file2 $file3 layouts failed"
18877         $LFS swap_layouts $file1 $file2 ||
18878                 error "swap $file1 $file2 layouts failed"
18879
18880         lovea2=$(get_layout_param $file2)
18881         echo "$lovea1"
18882         echo "$lovea2"
18883         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18884
18885         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18886         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18887 }
18888 run_test 184d "allow stripeless layouts swap"
18889
18890 test_184e() {
18891         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18892                 skip "Need MDS version at least 2.6.94"
18893         check_swap_layouts_support
18894         check_swap_layout_no_dom $DIR
18895         [ -z "$(which getfattr 2>/dev/null)" ] &&
18896                 skip_env "no getfattr command"
18897
18898         local file1=$DIR/$tdir/$tfile-1
18899         local file2=$DIR/$tdir/$tfile-2
18900         local file3=$DIR/$tdir/$tfile-3
18901         local lovea
18902
18903         mkdir -p $DIR/$tdir
18904         touch $file1 || error "create $file1 failed"
18905         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18906                 error "create $file2 failed"
18907         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18908                 error "create $file3 failed"
18909
18910         $LFS swap_layouts $file1 $file2 ||
18911                 error "swap $file1 $file2 layouts failed"
18912
18913         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18914         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18915
18916         echo 123 > $file1 || error "Should be able to write into $file1"
18917
18918         $LFS swap_layouts $file1 $file3 ||
18919                 error "swap $file1 $file3 layouts failed"
18920
18921         echo 123 > $file1 || error "Should be able to write into $file1"
18922
18923         rm -rf $file1 $file2 $file3
18924 }
18925 run_test 184e "Recreate layout after stripeless layout swaps"
18926
18927 test_184f() {
18928         # Create a file with name longer than sizeof(struct stat) ==
18929         # 144 to see if we can get chars from the file name to appear
18930         # in the returned striping. Note that 'f' == 0x66.
18931         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18932
18933         mkdir -p $DIR/$tdir
18934         mcreate $DIR/$tdir/$file
18935         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18936                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18937         fi
18938 }
18939 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18940
18941 test_185() { # LU-2441
18942         # LU-3553 - no volatile file support in old servers
18943         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18944                 skip "Need MDS version at least 2.3.60"
18945
18946         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18947         touch $DIR/$tdir/spoo
18948         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18949         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18950                 error "cannot create/write a volatile file"
18951         [ "$FILESET" == "" ] &&
18952         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18953                 error "FID is still valid after close"
18954
18955         multiop_bg_pause $DIR/$tdir vVw4096_c
18956         local multi_pid=$!
18957
18958         local OLD_IFS=$IFS
18959         IFS=":"
18960         local fidv=($fid)
18961         IFS=$OLD_IFS
18962         # assume that the next FID for this client is sequential, since stdout
18963         # is unfortunately eaten by multiop_bg_pause
18964         local n=$((${fidv[1]} + 1))
18965         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18966         if [ "$FILESET" == "" ]; then
18967                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18968                         error "FID is missing before close"
18969         fi
18970         kill -USR1 $multi_pid
18971         # 1 second delay, so if mtime change we will see it
18972         sleep 1
18973         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18974         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18975 }
18976 run_test 185 "Volatile file support"
18977
18978 function create_check_volatile() {
18979         local idx=$1
18980         local tgt
18981
18982         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18983         local PID=$!
18984         sleep 1
18985         local FID=$(cat /tmp/${tfile}.fid)
18986         [ "$FID" == "" ] && error "can't get FID for volatile"
18987         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18988         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18989         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18990         kill -USR1 $PID
18991         wait
18992         sleep 1
18993         cancel_lru_locks mdc # flush opencache
18994         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18995         return 0
18996 }
18997
18998 test_185a(){
18999         # LU-12516 - volatile creation via .lustre
19000         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19001                 skip "Need MDS version at least 2.3.55"
19002
19003         create_check_volatile 0
19004         [ $MDSCOUNT -lt 2 ] && return 0
19005
19006         # DNE case
19007         create_check_volatile 1
19008
19009         return 0
19010 }
19011 run_test 185a "Volatile file creation in .lustre/fid/"
19012
19013 test_187a() {
19014         remote_mds_nodsh && skip "remote MDS with nodsh"
19015         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19016                 skip "Need MDS version at least 2.3.0"
19017
19018         local dir0=$DIR/$tdir/$testnum
19019         mkdir -p $dir0 || error "creating dir $dir0"
19020
19021         local file=$dir0/file1
19022         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19023         local dv1=$($LFS data_version $file)
19024         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19025         local dv2=$($LFS data_version $file)
19026         [[ $dv1 != $dv2 ]] ||
19027                 error "data version did not change on write $dv1 == $dv2"
19028
19029         # clean up
19030         rm -f $file1
19031 }
19032 run_test 187a "Test data version change"
19033
19034 test_187b() {
19035         remote_mds_nodsh && skip "remote MDS with nodsh"
19036         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19037                 skip "Need MDS version at least 2.3.0"
19038
19039         local dir0=$DIR/$tdir/$testnum
19040         mkdir -p $dir0 || error "creating dir $dir0"
19041
19042         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19043         [[ ${DV[0]} != ${DV[1]} ]] ||
19044                 error "data version did not change on write"\
19045                       " ${DV[0]} == ${DV[1]}"
19046
19047         # clean up
19048         rm -f $file1
19049 }
19050 run_test 187b "Test data version change on volatile file"
19051
19052 test_200() {
19053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19054         remote_mgs_nodsh && skip "remote MGS with nodsh"
19055         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19056
19057         local POOL=${POOL:-cea1}
19058         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19059         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19060         # Pool OST targets
19061         local first_ost=0
19062         local last_ost=$(($OSTCOUNT - 1))
19063         local ost_step=2
19064         local ost_list=$(seq $first_ost $ost_step $last_ost)
19065         local ost_range="$first_ost $last_ost $ost_step"
19066         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19067         local file_dir=$POOL_ROOT/file_tst
19068         local subdir=$test_path/subdir
19069         local rc=0
19070
19071         while : ; do
19072                 # former test_200a test_200b
19073                 pool_add $POOL                          || { rc=$? ; break; }
19074                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19075                 # former test_200c test_200d
19076                 mkdir -p $test_path
19077                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19078                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19079                 mkdir -p $subdir
19080                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19081                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19082                                                         || { rc=$? ; break; }
19083                 # former test_200e test_200f
19084                 local files=$((OSTCOUNT*3))
19085                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19086                                                         || { rc=$? ; break; }
19087                 pool_create_files $POOL $file_dir $files "$ost_list" \
19088                                                         || { rc=$? ; break; }
19089                 # former test_200g test_200h
19090                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19091                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19092
19093                 # former test_201a test_201b test_201c
19094                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19095
19096                 local f=$test_path/$tfile
19097                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19098                 pool_remove $POOL $f                    || { rc=$? ; break; }
19099                 break
19100         done
19101
19102         destroy_test_pools
19103
19104         return $rc
19105 }
19106 run_test 200 "OST pools"
19107
19108 # usage: default_attr <count | size | offset>
19109 default_attr() {
19110         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19111 }
19112
19113 # usage: check_default_stripe_attr
19114 check_default_stripe_attr() {
19115         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19116         case $1 in
19117         --stripe-count|-c)
19118                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19119         --stripe-size|-S)
19120                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19121         --stripe-index|-i)
19122                 EXPECTED=-1;;
19123         *)
19124                 error "unknown getstripe attr '$1'"
19125         esac
19126
19127         [ $ACTUAL == $EXPECTED ] ||
19128                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19129 }
19130
19131 test_204a() {
19132         test_mkdir $DIR/$tdir
19133         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19134
19135         check_default_stripe_attr --stripe-count
19136         check_default_stripe_attr --stripe-size
19137         check_default_stripe_attr --stripe-index
19138 }
19139 run_test 204a "Print default stripe attributes"
19140
19141 test_204b() {
19142         test_mkdir $DIR/$tdir
19143         $LFS setstripe --stripe-count 1 $DIR/$tdir
19144
19145         check_default_stripe_attr --stripe-size
19146         check_default_stripe_attr --stripe-index
19147 }
19148 run_test 204b "Print default stripe size and offset"
19149
19150 test_204c() {
19151         test_mkdir $DIR/$tdir
19152         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19153
19154         check_default_stripe_attr --stripe-count
19155         check_default_stripe_attr --stripe-index
19156 }
19157 run_test 204c "Print default stripe count and offset"
19158
19159 test_204d() {
19160         test_mkdir $DIR/$tdir
19161         $LFS setstripe --stripe-index 0 $DIR/$tdir
19162
19163         check_default_stripe_attr --stripe-count
19164         check_default_stripe_attr --stripe-size
19165 }
19166 run_test 204d "Print default stripe count and size"
19167
19168 test_204e() {
19169         test_mkdir $DIR/$tdir
19170         $LFS setstripe -d $DIR/$tdir
19171
19172         check_default_stripe_attr --stripe-count --raw
19173         check_default_stripe_attr --stripe-size --raw
19174         check_default_stripe_attr --stripe-index --raw
19175 }
19176 run_test 204e "Print raw stripe attributes"
19177
19178 test_204f() {
19179         test_mkdir $DIR/$tdir
19180         $LFS setstripe --stripe-count 1 $DIR/$tdir
19181
19182         check_default_stripe_attr --stripe-size --raw
19183         check_default_stripe_attr --stripe-index --raw
19184 }
19185 run_test 204f "Print raw stripe size and offset"
19186
19187 test_204g() {
19188         test_mkdir $DIR/$tdir
19189         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19190
19191         check_default_stripe_attr --stripe-count --raw
19192         check_default_stripe_attr --stripe-index --raw
19193 }
19194 run_test 204g "Print raw stripe count and offset"
19195
19196 test_204h() {
19197         test_mkdir $DIR/$tdir
19198         $LFS setstripe --stripe-index 0 $DIR/$tdir
19199
19200         check_default_stripe_attr --stripe-count --raw
19201         check_default_stripe_attr --stripe-size --raw
19202 }
19203 run_test 204h "Print raw stripe count and size"
19204
19205 # Figure out which job scheduler is being used, if any,
19206 # or use a fake one
19207 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19208         JOBENV=SLURM_JOB_ID
19209 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19210         JOBENV=LSB_JOBID
19211 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19212         JOBENV=PBS_JOBID
19213 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19214         JOBENV=LOADL_STEP_ID
19215 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19216         JOBENV=JOB_ID
19217 else
19218         $LCTL list_param jobid_name > /dev/null 2>&1
19219         if [ $? -eq 0 ]; then
19220                 JOBENV=nodelocal
19221         else
19222                 JOBENV=FAKE_JOBID
19223         fi
19224 fi
19225 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19226
19227 verify_jobstats() {
19228         local cmd=($1)
19229         shift
19230         local facets="$@"
19231
19232 # we don't really need to clear the stats for this test to work, since each
19233 # command has a unique jobid, but it makes debugging easier if needed.
19234 #       for facet in $facets; do
19235 #               local dev=$(convert_facet2label $facet)
19236 #               # clear old jobstats
19237 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19238 #       done
19239
19240         # use a new JobID for each test, or we might see an old one
19241         [ "$JOBENV" = "FAKE_JOBID" ] &&
19242                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19243
19244         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19245
19246         [ "$JOBENV" = "nodelocal" ] && {
19247                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19248                 $LCTL set_param jobid_name=$FAKE_JOBID
19249                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19250         }
19251
19252         log "Test: ${cmd[*]}"
19253         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19254
19255         if [ $JOBENV = "FAKE_JOBID" ]; then
19256                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19257         else
19258                 ${cmd[*]}
19259         fi
19260
19261         # all files are created on OST0000
19262         for facet in $facets; do
19263                 local stats="*.$(convert_facet2label $facet).job_stats"
19264
19265                 # strip out libtool wrappers for in-tree executables
19266                 if (( $(do_facet $facet lctl get_param $stats |
19267                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19268                         do_facet $facet lctl get_param $stats
19269                         error "No jobstats for $JOBVAL found on $facet::$stats"
19270                 fi
19271         done
19272 }
19273
19274 jobstats_set() {
19275         local new_jobenv=$1
19276
19277         set_persistent_param_and_check client "jobid_var" \
19278                 "$FSNAME.sys.jobid_var" $new_jobenv
19279 }
19280
19281 test_205a() { # Job stats
19282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19283         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19284                 skip "Need MDS version with at least 2.7.1"
19285         remote_mgs_nodsh && skip "remote MGS with nodsh"
19286         remote_mds_nodsh && skip "remote MDS with nodsh"
19287         remote_ost_nodsh && skip "remote OST with nodsh"
19288         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19289                 skip "Server doesn't support jobstats"
19290         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19291
19292         local old_jobenv=$($LCTL get_param -n jobid_var)
19293         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19294
19295         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19296                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19297         else
19298                 stack_trap "do_facet mgs $PERM_CMD \
19299                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19300         fi
19301         changelog_register
19302
19303         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19304                                 mdt.*.job_cleanup_interval | head -n 1)
19305         local new_interval=5
19306         do_facet $SINGLEMDS \
19307                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19308         stack_trap "do_facet $SINGLEMDS \
19309                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19310         local start=$SECONDS
19311
19312         local cmd
19313         # mkdir
19314         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19315         verify_jobstats "$cmd" "$SINGLEMDS"
19316         # rmdir
19317         cmd="rmdir $DIR/$tdir"
19318         verify_jobstats "$cmd" "$SINGLEMDS"
19319         # mkdir on secondary MDT
19320         if [ $MDSCOUNT -gt 1 ]; then
19321                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19322                 verify_jobstats "$cmd" "mds2"
19323         fi
19324         # mknod
19325         cmd="mknod $DIR/$tfile c 1 3"
19326         verify_jobstats "$cmd" "$SINGLEMDS"
19327         # unlink
19328         cmd="rm -f $DIR/$tfile"
19329         verify_jobstats "$cmd" "$SINGLEMDS"
19330         # create all files on OST0000 so verify_jobstats can find OST stats
19331         # open & close
19332         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19333         verify_jobstats "$cmd" "$SINGLEMDS"
19334         # setattr
19335         cmd="touch $DIR/$tfile"
19336         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19337         # write
19338         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19339         verify_jobstats "$cmd" "ost1"
19340         # read
19341         cancel_lru_locks osc
19342         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19343         verify_jobstats "$cmd" "ost1"
19344         # truncate
19345         cmd="$TRUNCATE $DIR/$tfile 0"
19346         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19347         # rename
19348         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19349         verify_jobstats "$cmd" "$SINGLEMDS"
19350         # jobstats expiry - sleep until old stats should be expired
19351         local left=$((new_interval + 5 - (SECONDS - start)))
19352         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19353                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19354                         "0" $left
19355         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19356         verify_jobstats "$cmd" "$SINGLEMDS"
19357         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19358             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19359
19360         # Ensure that jobid are present in changelog (if supported by MDS)
19361         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19362                 changelog_dump | tail -10
19363                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19364                 [ $jobids -eq 9 ] ||
19365                         error "Wrong changelog jobid count $jobids != 9"
19366
19367                 # LU-5862
19368                 JOBENV="disable"
19369                 jobstats_set $JOBENV
19370                 touch $DIR/$tfile
19371                 changelog_dump | grep $tfile
19372                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19373                 [ $jobids -eq 0 ] ||
19374                         error "Unexpected jobids when jobid_var=$JOBENV"
19375         fi
19376
19377         # test '%j' access to environment variable - if supported
19378         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19379                 JOBENV="JOBCOMPLEX"
19380                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19381
19382                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19383         fi
19384
19385         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19386                 JOBENV="JOBCOMPLEX"
19387                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19388
19389                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19390         fi
19391
19392         # test '%j' access to per-session jobid - if supported
19393         if lctl list_param jobid_this_session > /dev/null 2>&1
19394         then
19395                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19396                 lctl set_param jobid_this_session=$USER
19397
19398                 JOBENV="JOBCOMPLEX"
19399                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19400
19401                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19402         fi
19403 }
19404 run_test 205a "Verify job stats"
19405
19406 # LU-13117, LU-13597
19407 test_205b() {
19408         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19409                 skip "Need MDS version at least 2.13.54.91"
19410
19411         local job_stats="mdt.*.job_stats"
19412         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19413
19414         do_facet mds1 $LCTL set_param $job_stats=clear
19415
19416         # Setting jobid_var to USER might not be supported
19417         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19418         $LCTL set_param jobid_var=USER || true
19419         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19420         $LCTL set_param jobid_name="%j.%e.%u"
19421
19422         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19423         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19424                 { do_facet mds1 $LCTL get_param $job_stats;
19425                   error "Unexpected jobid found"; }
19426         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19427                 { do_facet mds1 $LCTL get_param $job_stats;
19428                   error "wrong job_stats format found"; }
19429
19430         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19431                 echo "MDS does not yet escape jobid" && return 0
19432         $LCTL set_param jobid_var=TEST205b
19433         env -i TEST205b="has sp" touch $DIR/$tfile.2
19434         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19435                 { do_facet mds1 $LCTL get_param $job_stats;
19436                   error "jobid not escaped"; }
19437 }
19438 run_test 205b "Verify job stats jobid and output format"
19439
19440 # LU-13733
19441 test_205c() {
19442         $LCTL set_param llite.*.stats=0
19443         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19444         $LCTL get_param llite.*.stats
19445         $LCTL get_param llite.*.stats | grep \
19446                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19447                         error "wrong client stats format found"
19448 }
19449 run_test 205c "Verify client stats format"
19450
19451 test_205d() {
19452         local file=$DIR/$tdir/$tfile
19453
19454         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19455                 skip "need lustre >= 2.15.53 for lljobstat"
19456         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19457                 skip "need lustre >= 2.15.53 for lljobstat"
19458         verify_yaml_available || skip_env "YAML verification not installed"
19459
19460         test_mkdir -i 0 $DIR/$tdir
19461         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19462
19463         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19464                 error "failed to write data to $file"
19465         mv $file $file.2
19466
19467         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19468         echo -n 'verify rename_stats...'
19469         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19470                 verify_yaml || error "rename_stats is not valid YAML"
19471         echo " OK"
19472
19473         echo -n 'verify mdt job_stats...'
19474         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19475                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19476         echo " OK"
19477
19478         echo -n 'verify ost job_stats...'
19479         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19480                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19481         echo " OK"
19482 }
19483 run_test 205d "verify the format of some stats files"
19484
19485 test_205e() {
19486         local ops_comma
19487         local file=$DIR/$tdir/$tfile
19488
19489         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19490                 skip "need lustre >= 2.15.53 for lljobstat"
19491         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19492                 skip "need lustre >= 2.15.53 for lljobstat"
19493         verify_yaml_available || skip_env "YAML verification not installed"
19494
19495         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19496
19497         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19498                 error "failed to create $file on ost1"
19499         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19500                 error "failed to write data to $file"
19501
19502         do_facet mds1 "$LCTL get_param *.*.job_stats"
19503         do_facet ost1 "$LCTL get_param *.*.job_stats"
19504
19505         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19506         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19507                 error "The output of lljobstat is not an valid YAML"
19508
19509         # verify that job dd.0 does exist and has some ops on ost1
19510         # typically this line is like:
19511         # - dd.0:            {ops: 20, ...}
19512         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19513                     awk '$2=="dd.0:" {print $4}')
19514
19515         (( ${ops_comma%,} >= 10 )) ||
19516                 error "cannot find job dd.0 with ops >= 10"
19517 }
19518 run_test 205e "verify the output of lljobstat"
19519
19520 # LU-1480, LU-1773 and LU-1657
19521 test_206() {
19522         mkdir -p $DIR/$tdir
19523         $LFS setstripe -c -1 $DIR/$tdir
19524 #define OBD_FAIL_LOV_INIT 0x1403
19525         $LCTL set_param fail_loc=0xa0001403
19526         $LCTL set_param fail_val=1
19527         touch $DIR/$tdir/$tfile || true
19528 }
19529 run_test 206 "fail lov_init_raid0() doesn't lbug"
19530
19531 test_207a() {
19532         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19533         local fsz=`stat -c %s $DIR/$tfile`
19534         cancel_lru_locks mdc
19535
19536         # do not return layout in getattr intent
19537 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19538         $LCTL set_param fail_loc=0x170
19539         local sz=`stat -c %s $DIR/$tfile`
19540
19541         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19542
19543         rm -rf $DIR/$tfile
19544 }
19545 run_test 207a "can refresh layout at glimpse"
19546
19547 test_207b() {
19548         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19549         local cksum=`md5sum $DIR/$tfile`
19550         local fsz=`stat -c %s $DIR/$tfile`
19551         cancel_lru_locks mdc
19552         cancel_lru_locks osc
19553
19554         # do not return layout in getattr intent
19555 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19556         $LCTL set_param fail_loc=0x171
19557
19558         # it will refresh layout after the file is opened but before read issues
19559         echo checksum is "$cksum"
19560         echo "$cksum" |md5sum -c --quiet || error "file differs"
19561
19562         rm -rf $DIR/$tfile
19563 }
19564 run_test 207b "can refresh layout at open"
19565
19566 test_208() {
19567         # FIXME: in this test suite, only RD lease is used. This is okay
19568         # for now as only exclusive open is supported. After generic lease
19569         # is done, this test suite should be revised. - Jinshan
19570
19571         remote_mds_nodsh && skip "remote MDS with nodsh"
19572         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19573                 skip "Need MDS version at least 2.4.52"
19574
19575         echo "==== test 1: verify get lease work"
19576         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19577
19578         echo "==== test 2: verify lease can be broken by upcoming open"
19579         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19580         local PID=$!
19581         sleep 2
19582
19583         $MULTIOP $DIR/$tfile oO_RDWR:c
19584         kill -USR1 $PID && wait $PID || error "break lease error"
19585
19586         echo "==== test 3: verify lease can't be granted if an open already exists"
19587         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19588         local PID=$!
19589         sleep 2
19590
19591         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19592         kill -USR1 $PID && wait $PID || error "open file error"
19593
19594         echo "==== test 4: lease can sustain over recovery"
19595         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19596         PID=$!
19597         sleep 2
19598
19599         fail mds1
19600
19601         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19602
19603         echo "==== test 5: lease broken can't be regained by replay"
19604         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19605         PID=$!
19606         sleep 2
19607
19608         # open file to break lease and then recovery
19609         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19610         fail mds1
19611
19612         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19613
19614         rm -f $DIR/$tfile
19615 }
19616 run_test 208 "Exclusive open"
19617
19618 test_209() {
19619         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19620                 skip_env "must have disp_stripe"
19621
19622         touch $DIR/$tfile
19623         sync; sleep 5; sync;
19624
19625         echo 3 > /proc/sys/vm/drop_caches
19626         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19627                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19628         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19629
19630         # open/close 500 times
19631         for i in $(seq 500); do
19632                 cat $DIR/$tfile
19633         done
19634
19635         echo 3 > /proc/sys/vm/drop_caches
19636         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19637                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19638         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19639
19640         echo "before: $req_before, after: $req_after"
19641         [ $((req_after - req_before)) -ge 300 ] &&
19642                 error "open/close requests are not freed"
19643         return 0
19644 }
19645 run_test 209 "read-only open/close requests should be freed promptly"
19646
19647 test_210() {
19648         local pid
19649
19650         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19651         pid=$!
19652         sleep 1
19653
19654         $LFS getstripe $DIR/$tfile
19655         kill -USR1 $pid
19656         wait $pid || error "multiop failed"
19657
19658         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19659         pid=$!
19660         sleep 1
19661
19662         $LFS getstripe $DIR/$tfile
19663         kill -USR1 $pid
19664         wait $pid || error "multiop failed"
19665 }
19666 run_test 210 "lfs getstripe does not break leases"
19667
19668 test_212() {
19669         size=`date +%s`
19670         size=$((size % 8192 + 1))
19671         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19672         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19673         rm -f $DIR/f212 $DIR/f212.xyz
19674 }
19675 run_test 212 "Sendfile test ============================================"
19676
19677 test_213() {
19678         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19679         cancel_lru_locks osc
19680         lctl set_param fail_loc=0x8000040f
19681         # generate a read lock
19682         cat $DIR/$tfile > /dev/null
19683         # write to the file, it will try to cancel the above read lock.
19684         cat /etc/hosts >> $DIR/$tfile
19685 }
19686 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19687
19688 test_214() { # for bug 20133
19689         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19690         for (( i=0; i < 340; i++ )) ; do
19691                 touch $DIR/$tdir/d214c/a$i
19692         done
19693
19694         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19695         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19696         ls $DIR/d214c || error "ls $DIR/d214c failed"
19697         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19698         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19699 }
19700 run_test 214 "hash-indexed directory test - bug 20133"
19701
19702 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19703 create_lnet_proc_files() {
19704         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19705 }
19706
19707 # counterpart of create_lnet_proc_files
19708 remove_lnet_proc_files() {
19709         rm -f $TMP/lnet_$1.sys
19710 }
19711
19712 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19713 # 3rd arg as regexp for body
19714 check_lnet_proc_stats() {
19715         local l=$(cat "$TMP/lnet_$1" |wc -l)
19716         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19717
19718         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19719 }
19720
19721 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19722 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19723 # optional and can be regexp for 2nd line (lnet.routes case)
19724 check_lnet_proc_entry() {
19725         local blp=2          # blp stands for 'position of 1st line of body'
19726         [ -z "$5" ] || blp=3 # lnet.routes case
19727
19728         local l=$(cat "$TMP/lnet_$1" |wc -l)
19729         # subtracting one from $blp because the body can be empty
19730         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19731
19732         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19733                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19734
19735         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19736                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19737
19738         # bail out if any unexpected line happened
19739         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19740         [ "$?" != 0 ] || error "$2 misformatted"
19741 }
19742
19743 test_215() { # for bugs 18102, 21079, 21517
19744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19745
19746         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19747         local P='[1-9][0-9]*'           # positive numeric
19748         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19749         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19750         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19751         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19752
19753         local L1 # regexp for 1st line
19754         local L2 # regexp for 2nd line (optional)
19755         local BR # regexp for the rest (body)
19756
19757         # lnet.stats should look as 11 space-separated non-negative numerics
19758         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19759         create_lnet_proc_files "stats"
19760         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19761         remove_lnet_proc_files "stats"
19762
19763         # lnet.routes should look like this:
19764         # Routing disabled/enabled
19765         # net hops priority state router
19766         # where net is a string like tcp0, hops > 0, priority >= 0,
19767         # state is up/down,
19768         # router is a string like 192.168.1.1@tcp2
19769         L1="^Routing (disabled|enabled)$"
19770         L2="^net +hops +priority +state +router$"
19771         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19772         create_lnet_proc_files "routes"
19773         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19774         remove_lnet_proc_files "routes"
19775
19776         # lnet.routers should look like this:
19777         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19778         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19779         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19780         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19781         L1="^ref +rtr_ref +alive +router$"
19782         BR="^$P +$P +(up|down) +$NID$"
19783         create_lnet_proc_files "routers"
19784         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19785         remove_lnet_proc_files "routers"
19786
19787         # lnet.peers should look like this:
19788         # nid refs state last max rtr min tx min queue
19789         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19790         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19791         # numeric (0 or >0 or <0), queue >= 0.
19792         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19793         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19794         create_lnet_proc_files "peers"
19795         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19796         remove_lnet_proc_files "peers"
19797
19798         # lnet.buffers  should look like this:
19799         # pages count credits min
19800         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19801         L1="^pages +count +credits +min$"
19802         BR="^ +$N +$N +$I +$I$"
19803         create_lnet_proc_files "buffers"
19804         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19805         remove_lnet_proc_files "buffers"
19806
19807         # lnet.nis should look like this:
19808         # nid status alive refs peer rtr max tx min
19809         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19810         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19811         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19812         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19813         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19814         create_lnet_proc_files "nis"
19815         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19816         remove_lnet_proc_files "nis"
19817
19818         # can we successfully write to lnet.stats?
19819         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19820 }
19821 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19822
19823 test_216() { # bug 20317
19824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19825         remote_ost_nodsh && skip "remote OST with nodsh"
19826
19827         local node
19828         local facets=$(get_facets OST)
19829         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19830
19831         save_lustre_params client "osc.*.contention_seconds" > $p
19832         save_lustre_params $facets \
19833                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19834         save_lustre_params $facets \
19835                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19836         save_lustre_params $facets \
19837                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19838         clear_stats osc.*.osc_stats
19839
19840         # agressive lockless i/o settings
19841         do_nodes $(comma_list $(osts_nodes)) \
19842                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19843                         ldlm.namespaces.filter-*.contended_locks=0 \
19844                         ldlm.namespaces.filter-*.contention_seconds=60"
19845         lctl set_param -n osc.*.contention_seconds=60
19846
19847         $DIRECTIO write $DIR/$tfile 0 10 4096
19848         $CHECKSTAT -s 40960 $DIR/$tfile
19849
19850         # disable lockless i/o
19851         do_nodes $(comma_list $(osts_nodes)) \
19852                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19853                         ldlm.namespaces.filter-*.contended_locks=32 \
19854                         ldlm.namespaces.filter-*.contention_seconds=0"
19855         lctl set_param -n osc.*.contention_seconds=0
19856         clear_stats osc.*.osc_stats
19857
19858         dd if=/dev/zero of=$DIR/$tfile count=0
19859         $CHECKSTAT -s 0 $DIR/$tfile
19860
19861         restore_lustre_params <$p
19862         rm -f $p
19863         rm $DIR/$tfile
19864 }
19865 run_test 216 "check lockless direct write updates file size and kms correctly"
19866
19867 test_217() { # bug 22430
19868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19869
19870         local node
19871         local nid
19872
19873         for node in $(nodes_list); do
19874                 nid=$(host_nids_address $node $NETTYPE)
19875                 if [[ $nid = *-* ]] ; then
19876                         echo "lctl ping $(h2nettype $nid)"
19877                         lctl ping $(h2nettype $nid)
19878                 else
19879                         echo "skipping $node (no hyphen detected)"
19880                 fi
19881         done
19882 }
19883 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19884
19885 test_218() {
19886        # do directio so as not to populate the page cache
19887        log "creating a 10 Mb file"
19888        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19889        log "starting reads"
19890        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19891        log "truncating the file"
19892        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19893        log "killing dd"
19894        kill %+ || true # reads might have finished
19895        echo "wait until dd is finished"
19896        wait
19897        log "removing the temporary file"
19898        rm -rf $DIR/$tfile || error "tmp file removal failed"
19899 }
19900 run_test 218 "parallel read and truncate should not deadlock"
19901
19902 test_219() {
19903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19904
19905         # write one partial page
19906         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19907         # set no grant so vvp_io_commit_write will do sync write
19908         $LCTL set_param fail_loc=0x411
19909         # write a full page at the end of file
19910         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19911
19912         $LCTL set_param fail_loc=0
19913         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19914         $LCTL set_param fail_loc=0x411
19915         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19916
19917         # LU-4201
19918         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19919         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19920 }
19921 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19922
19923 test_220() { #LU-325
19924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19925         remote_ost_nodsh && skip "remote OST with nodsh"
19926         remote_mds_nodsh && skip "remote MDS with nodsh"
19927         remote_mgs_nodsh && skip "remote MGS with nodsh"
19928
19929         local OSTIDX=0
19930
19931         # create on MDT0000 so the last_id and next_id are correct
19932         mkdir_on_mdt0 $DIR/$tdir
19933         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19934         OST=${OST%_UUID}
19935
19936         # on the mdt's osc
19937         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19938         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19939                         osp.$mdtosc_proc1.prealloc_last_id)
19940         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19941                         osp.$mdtosc_proc1.prealloc_next_id)
19942
19943         $LFS df -i
19944
19945         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19946         #define OBD_FAIL_OST_ENOINO              0x229
19947         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19948         create_pool $FSNAME.$TESTNAME || return 1
19949         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19950
19951         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19952
19953         MDSOBJS=$((last_id - next_id))
19954         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19955
19956         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19957         echo "OST still has $count kbytes free"
19958
19959         echo "create $MDSOBJS files @next_id..."
19960         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19961
19962         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19963                         osp.$mdtosc_proc1.prealloc_last_id)
19964         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19965                         osp.$mdtosc_proc1.prealloc_next_id)
19966
19967         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19968         $LFS df -i
19969
19970         echo "cleanup..."
19971
19972         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19973         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19974
19975         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19976                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19977         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19978                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19979         echo "unlink $MDSOBJS files @$next_id..."
19980         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19981 }
19982 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19983
19984 test_221() {
19985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19986
19987         dd if=`which date` of=$MOUNT/date oflag=sync
19988         chmod +x $MOUNT/date
19989
19990         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19991         $LCTL set_param fail_loc=0x80001401
19992
19993         $MOUNT/date > /dev/null
19994         rm -f $MOUNT/date
19995 }
19996 run_test 221 "make sure fault and truncate race to not cause OOM"
19997
19998 test_222a () {
19999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20000
20001         rm -rf $DIR/$tdir
20002         test_mkdir $DIR/$tdir
20003         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20004         createmany -o $DIR/$tdir/$tfile 10
20005         cancel_lru_locks mdc
20006         cancel_lru_locks osc
20007         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20008         $LCTL set_param fail_loc=0x31a
20009         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20010         $LCTL set_param fail_loc=0
20011         rm -r $DIR/$tdir
20012 }
20013 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20014
20015 test_222b () {
20016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20017
20018         rm -rf $DIR/$tdir
20019         test_mkdir $DIR/$tdir
20020         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20021         createmany -o $DIR/$tdir/$tfile 10
20022         cancel_lru_locks mdc
20023         cancel_lru_locks osc
20024         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20025         $LCTL set_param fail_loc=0x31a
20026         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20027         $LCTL set_param fail_loc=0
20028 }
20029 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20030
20031 test_223 () {
20032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20033
20034         rm -rf $DIR/$tdir
20035         test_mkdir $DIR/$tdir
20036         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20037         createmany -o $DIR/$tdir/$tfile 10
20038         cancel_lru_locks mdc
20039         cancel_lru_locks osc
20040         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20041         $LCTL set_param fail_loc=0x31b
20042         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20043         $LCTL set_param fail_loc=0
20044         rm -r $DIR/$tdir
20045 }
20046 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20047
20048 test_224a() { # LU-1039, MRP-303
20049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20050         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20051         $LCTL set_param fail_loc=0x508
20052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20053         $LCTL set_param fail_loc=0
20054         df $DIR
20055 }
20056 run_test 224a "Don't panic on bulk IO failure"
20057
20058 test_224bd_sub() { # LU-1039, MRP-303
20059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20060         local timeout=$1
20061
20062         shift
20063         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20064
20065         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20066
20067         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20068         cancel_lru_locks osc
20069         set_checksums 0
20070         stack_trap "set_checksums $ORIG_CSUM" EXIT
20071         local at_max_saved=0
20072
20073         # adaptive timeouts may prevent seeing the issue
20074         if at_is_enabled; then
20075                 at_max_saved=$(at_max_get mds)
20076                 at_max_set 0 mds client
20077                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20078         fi
20079
20080         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20081         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20082         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20083
20084         do_facet ost1 $LCTL set_param fail_loc=0
20085         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20086         df $DIR
20087 }
20088
20089 test_224b() {
20090         test_224bd_sub 3 error "dd failed"
20091 }
20092 run_test 224b "Don't panic on bulk IO failure"
20093
20094 test_224c() { # LU-6441
20095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20096         remote_mds_nodsh && skip "remote MDS with nodsh"
20097
20098         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20099         save_writethrough $p
20100         set_cache writethrough on
20101
20102         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20103         local at_max=$($LCTL get_param -n at_max)
20104         local timeout=$($LCTL get_param -n timeout)
20105         local test_at="at_max"
20106         local param_at="$FSNAME.sys.at_max"
20107         local test_timeout="timeout"
20108         local param_timeout="$FSNAME.sys.timeout"
20109
20110         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20111
20112         set_persistent_param_and_check client "$test_at" "$param_at" 0
20113         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20114
20115         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20116         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20117         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20118         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20119         sync
20120         do_facet ost1 "$LCTL set_param fail_loc=0"
20121
20122         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20123         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20124                 $timeout
20125
20126         $LCTL set_param -n $pages_per_rpc
20127         restore_lustre_params < $p
20128         rm -f $p
20129 }
20130 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20131
20132 test_224d() { # LU-11169
20133         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20134 }
20135 run_test 224d "Don't corrupt data on bulk IO timeout"
20136
20137 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20138 test_225a () {
20139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20140         if [ -z ${MDSSURVEY} ]; then
20141                 skip_env "mds-survey not found"
20142         fi
20143         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20144                 skip "Need MDS version at least 2.2.51"
20145
20146         local mds=$(facet_host $SINGLEMDS)
20147         local target=$(do_nodes $mds 'lctl dl' |
20148                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20149
20150         local cmd1="file_count=1000 thrhi=4"
20151         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20152         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20153         local cmd="$cmd1 $cmd2 $cmd3"
20154
20155         rm -f ${TMP}/mds_survey*
20156         echo + $cmd
20157         eval $cmd || error "mds-survey with zero-stripe failed"
20158         cat ${TMP}/mds_survey*
20159         rm -f ${TMP}/mds_survey*
20160 }
20161 run_test 225a "Metadata survey sanity with zero-stripe"
20162
20163 test_225b () {
20164         if [ -z ${MDSSURVEY} ]; then
20165                 skip_env "mds-survey not found"
20166         fi
20167         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20168                 skip "Need MDS version at least 2.2.51"
20169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20170         remote_mds_nodsh && skip "remote MDS with nodsh"
20171         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20172                 skip_env "Need to mount OST to test"
20173         fi
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=1"
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 stripe_count failed"
20187         cat ${TMP}/mds_survey*
20188         rm -f ${TMP}/mds_survey*
20189 }
20190 run_test 225b "Metadata survey sanity with stripe_count = 1"
20191
20192 mcreate_path2fid () {
20193         local mode=$1
20194         local major=$2
20195         local minor=$3
20196         local name=$4
20197         local desc=$5
20198         local path=$DIR/$tdir/$name
20199         local fid
20200         local rc
20201         local fid_path
20202
20203         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20204                 error "cannot create $desc"
20205
20206         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20207         rc=$?
20208         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20209
20210         fid_path=$($LFS fid2path $MOUNT $fid)
20211         rc=$?
20212         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20213
20214         [ "$path" == "$fid_path" ] ||
20215                 error "fid2path returned $fid_path, expected $path"
20216
20217         echo "pass with $path and $fid"
20218 }
20219
20220 test_226a () {
20221         rm -rf $DIR/$tdir
20222         mkdir -p $DIR/$tdir
20223
20224         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20225         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20226         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20227         mcreate_path2fid 0040666 0 0 dir "directory"
20228         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20229         mcreate_path2fid 0100666 0 0 file "regular file"
20230         mcreate_path2fid 0120666 0 0 link "symbolic link"
20231         mcreate_path2fid 0140666 0 0 sock "socket"
20232 }
20233 run_test 226a "call path2fid and fid2path on files of all type"
20234
20235 test_226b () {
20236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20237
20238         local MDTIDX=1
20239
20240         rm -rf $DIR/$tdir
20241         mkdir -p $DIR/$tdir
20242         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20243                 error "create remote directory failed"
20244         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20245         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20246                                 "character special file (null)"
20247         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20248                                 "character special file (no device)"
20249         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20250         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20251                                 "block special file (loop)"
20252         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20253         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20254         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20255 }
20256 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20257
20258 test_226c () {
20259         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20260         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20261                 skip "Need MDS version at least 2.13.55"
20262
20263         local submnt=/mnt/submnt
20264         local srcfile=/etc/passwd
20265         local dstfile=$submnt/passwd
20266         local path
20267         local fid
20268
20269         rm -rf $DIR/$tdir
20270         rm -rf $submnt
20271         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20272                 error "create remote directory failed"
20273         mkdir -p $submnt || error "create $submnt failed"
20274         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20275                 error "mount $submnt failed"
20276         stack_trap "umount $submnt" EXIT
20277
20278         cp $srcfile $dstfile
20279         fid=$($LFS path2fid $dstfile)
20280         path=$($LFS fid2path $submnt "$fid")
20281         [ "$path" = "$dstfile" ] ||
20282                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20283 }
20284 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20285
20286 # LU-1299 Executing or running ldd on a truncated executable does not
20287 # cause an out-of-memory condition.
20288 test_227() {
20289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20290         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20291
20292         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20293         chmod +x $MOUNT/date
20294
20295         $MOUNT/date > /dev/null
20296         ldd $MOUNT/date > /dev/null
20297         rm -f $MOUNT/date
20298 }
20299 run_test 227 "running truncated executable does not cause OOM"
20300
20301 # LU-1512 try to reuse idle OI blocks
20302 test_228a() {
20303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20304         remote_mds_nodsh && skip "remote MDS with nodsh"
20305         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20306
20307         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20308         local myDIR=$DIR/$tdir
20309
20310         mkdir -p $myDIR
20311         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20312         $LCTL set_param fail_loc=0x80001002
20313         createmany -o $myDIR/t- 10000
20314         $LCTL set_param fail_loc=0
20315         # The guard is current the largest FID holder
20316         touch $myDIR/guard
20317         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20318                     tr -d '[')
20319         local IDX=$(($SEQ % 64))
20320
20321         do_facet $SINGLEMDS sync
20322         # Make sure journal flushed.
20323         sleep 6
20324         local blk1=$(do_facet $SINGLEMDS \
20325                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20326                      grep Blockcount | awk '{print $4}')
20327
20328         # Remove old files, some OI blocks will become idle.
20329         unlinkmany $myDIR/t- 10000
20330         # Create new files, idle OI blocks should be reused.
20331         createmany -o $myDIR/t- 2000
20332         do_facet $SINGLEMDS sync
20333         # Make sure journal flushed.
20334         sleep 6
20335         local blk2=$(do_facet $SINGLEMDS \
20336                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20337                      grep Blockcount | awk '{print $4}')
20338
20339         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20340 }
20341 run_test 228a "try to reuse idle OI blocks"
20342
20343 test_228b() {
20344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20345         remote_mds_nodsh && skip "remote MDS with nodsh"
20346         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20347
20348         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20349         local myDIR=$DIR/$tdir
20350
20351         mkdir -p $myDIR
20352         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20353         $LCTL set_param fail_loc=0x80001002
20354         createmany -o $myDIR/t- 10000
20355         $LCTL set_param fail_loc=0
20356         # The guard is current the largest FID holder
20357         touch $myDIR/guard
20358         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20359                     tr -d '[')
20360         local IDX=$(($SEQ % 64))
20361
20362         do_facet $SINGLEMDS sync
20363         # Make sure journal flushed.
20364         sleep 6
20365         local blk1=$(do_facet $SINGLEMDS \
20366                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20367                      grep Blockcount | awk '{print $4}')
20368
20369         # Remove old files, some OI blocks will become idle.
20370         unlinkmany $myDIR/t- 10000
20371
20372         # stop the MDT
20373         stop $SINGLEMDS || error "Fail to stop MDT."
20374         # remount the MDT
20375         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20376                 error "Fail to start MDT."
20377
20378         client_up || error "Fail to df."
20379         # Create new files, idle OI blocks should be reused.
20380         createmany -o $myDIR/t- 2000
20381         do_facet $SINGLEMDS sync
20382         # Make sure journal flushed.
20383         sleep 6
20384         local blk2=$(do_facet $SINGLEMDS \
20385                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20386                      grep Blockcount | awk '{print $4}')
20387
20388         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20389 }
20390 run_test 228b "idle OI blocks can be reused after MDT restart"
20391
20392 #LU-1881
20393 test_228c() {
20394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20395         remote_mds_nodsh && skip "remote MDS with nodsh"
20396         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20397
20398         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20399         local myDIR=$DIR/$tdir
20400
20401         mkdir -p $myDIR
20402         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20403         $LCTL set_param fail_loc=0x80001002
20404         # 20000 files can guarantee there are index nodes in the OI file
20405         createmany -o $myDIR/t- 20000
20406         $LCTL set_param fail_loc=0
20407         # The guard is current the largest FID holder
20408         touch $myDIR/guard
20409         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20410                     tr -d '[')
20411         local IDX=$(($SEQ % 64))
20412
20413         do_facet $SINGLEMDS sync
20414         # Make sure journal flushed.
20415         sleep 6
20416         local blk1=$(do_facet $SINGLEMDS \
20417                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20418                      grep Blockcount | awk '{print $4}')
20419
20420         # Remove old files, some OI blocks will become idle.
20421         unlinkmany $myDIR/t- 20000
20422         rm -f $myDIR/guard
20423         # The OI file should become empty now
20424
20425         # Create new files, idle OI blocks should be reused.
20426         createmany -o $myDIR/t- 2000
20427         do_facet $SINGLEMDS sync
20428         # Make sure journal flushed.
20429         sleep 6
20430         local blk2=$(do_facet $SINGLEMDS \
20431                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20432                      grep Blockcount | awk '{print $4}')
20433
20434         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20435 }
20436 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20437
20438 test_229() { # LU-2482, LU-3448
20439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20440         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20441         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20442                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20443
20444         rm -f $DIR/$tfile
20445
20446         # Create a file with a released layout and stripe count 2.
20447         $MULTIOP $DIR/$tfile H2c ||
20448                 error "failed to create file with released layout"
20449
20450         $LFS getstripe -v $DIR/$tfile
20451
20452         local pattern=$($LFS getstripe -L $DIR/$tfile)
20453         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20454
20455         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20456                 error "getstripe"
20457         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20458         stat $DIR/$tfile || error "failed to stat released file"
20459
20460         chown $RUNAS_ID $DIR/$tfile ||
20461                 error "chown $RUNAS_ID $DIR/$tfile failed"
20462
20463         chgrp $RUNAS_ID $DIR/$tfile ||
20464                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20465
20466         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20467         rm $DIR/$tfile || error "failed to remove released file"
20468 }
20469 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20470
20471 test_230a() {
20472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20474         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20475                 skip "Need MDS version at least 2.11.52"
20476
20477         local MDTIDX=1
20478
20479         test_mkdir $DIR/$tdir
20480         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20481         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20482         [ $mdt_idx -ne 0 ] &&
20483                 error "create local directory on wrong MDT $mdt_idx"
20484
20485         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20486                         error "create remote directory failed"
20487         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20488         [ $mdt_idx -ne $MDTIDX ] &&
20489                 error "create remote directory on wrong MDT $mdt_idx"
20490
20491         createmany -o $DIR/$tdir/test_230/t- 10 ||
20492                 error "create files on remote directory failed"
20493         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20494         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20495         rm -r $DIR/$tdir || error "unlink remote directory failed"
20496 }
20497 run_test 230a "Create remote directory and files under the remote directory"
20498
20499 test_230b() {
20500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20502         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20503                 skip "Need MDS version at least 2.11.52"
20504
20505         local MDTIDX=1
20506         local mdt_index
20507         local i
20508         local file
20509         local pid
20510         local stripe_count
20511         local migrate_dir=$DIR/$tdir/migrate_dir
20512         local other_dir=$DIR/$tdir/other_dir
20513
20514         test_mkdir $DIR/$tdir
20515         test_mkdir -i0 -c1 $migrate_dir
20516         test_mkdir -i0 -c1 $other_dir
20517         for ((i=0; i<10; i++)); do
20518                 mkdir -p $migrate_dir/dir_${i}
20519                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20520                         error "create files under remote dir failed $i"
20521         done
20522
20523         cp /etc/passwd $migrate_dir/$tfile
20524         cp /etc/passwd $other_dir/$tfile
20525         chattr +SAD $migrate_dir
20526         chattr +SAD $migrate_dir/$tfile
20527
20528         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20529         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20530         local old_dir_mode=$(stat -c%f $migrate_dir)
20531         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20532
20533         mkdir -p $migrate_dir/dir_default_stripe2
20534         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20535         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20536
20537         mkdir -p $other_dir
20538         ln $migrate_dir/$tfile $other_dir/luna
20539         ln $migrate_dir/$tfile $migrate_dir/sofia
20540         ln $other_dir/$tfile $migrate_dir/david
20541         ln -s $migrate_dir/$tfile $other_dir/zachary
20542         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20543         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20544
20545         local len
20546         local lnktgt
20547
20548         # inline symlink
20549         for len in 58 59 60; do
20550                 lnktgt=$(str_repeat 'l' $len)
20551                 touch $migrate_dir/$lnktgt
20552                 ln -s $lnktgt $migrate_dir/${len}char_ln
20553         done
20554
20555         # PATH_MAX
20556         for len in 4094 4095; do
20557                 lnktgt=$(str_repeat 'l' $len)
20558                 ln -s $lnktgt $migrate_dir/${len}char_ln
20559         done
20560
20561         # NAME_MAX
20562         for len in 254 255; do
20563                 touch $migrate_dir/$(str_repeat 'l' $len)
20564         done
20565
20566         $LFS migrate -m $MDTIDX $migrate_dir ||
20567                 error "fails on migrating remote dir to MDT1"
20568
20569         echo "migratate to MDT1, then checking.."
20570         for ((i = 0; i < 10; i++)); do
20571                 for file in $(find $migrate_dir/dir_${i}); do
20572                         mdt_index=$($LFS getstripe -m $file)
20573                         # broken symlink getstripe will fail
20574                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20575                                 error "$file is not on MDT${MDTIDX}"
20576                 done
20577         done
20578
20579         # the multiple link file should still in MDT0
20580         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20581         [ $mdt_index == 0 ] ||
20582                 error "$file is not on MDT${MDTIDX}"
20583
20584         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20585         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20586                 error " expect $old_dir_flag get $new_dir_flag"
20587
20588         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20589         [ "$old_file_flag" = "$new_file_flag" ] ||
20590                 error " expect $old_file_flag get $new_file_flag"
20591
20592         local new_dir_mode=$(stat -c%f $migrate_dir)
20593         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20594                 error "expect mode $old_dir_mode get $new_dir_mode"
20595
20596         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20597         [ "$old_file_mode" = "$new_file_mode" ] ||
20598                 error "expect mode $old_file_mode get $new_file_mode"
20599
20600         diff /etc/passwd $migrate_dir/$tfile ||
20601                 error "$tfile different after migration"
20602
20603         diff /etc/passwd $other_dir/luna ||
20604                 error "luna different after migration"
20605
20606         diff /etc/passwd $migrate_dir/sofia ||
20607                 error "sofia different after migration"
20608
20609         diff /etc/passwd $migrate_dir/david ||
20610                 error "david different after migration"
20611
20612         diff /etc/passwd $other_dir/zachary ||
20613                 error "zachary different after migration"
20614
20615         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20616                 error "${tfile}_ln different after migration"
20617
20618         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20619                 error "${tfile}_ln_other different after migration"
20620
20621         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20622         [ $stripe_count = 2 ] ||
20623                 error "dir strpe_count $d != 2 after migration."
20624
20625         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20626         [ $stripe_count = 2 ] ||
20627                 error "file strpe_count $d != 2 after migration."
20628
20629         #migrate back to MDT0
20630         MDTIDX=0
20631
20632         $LFS migrate -m $MDTIDX $migrate_dir ||
20633                 error "fails on migrating remote dir to MDT0"
20634
20635         echo "migrate back to MDT0, checking.."
20636         for file in $(find $migrate_dir); do
20637                 mdt_index=$($LFS getstripe -m $file)
20638                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20639                         error "$file is not on MDT${MDTIDX}"
20640         done
20641
20642         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20643         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20644                 error " expect $old_dir_flag get $new_dir_flag"
20645
20646         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20647         [ "$old_file_flag" = "$new_file_flag" ] ||
20648                 error " expect $old_file_flag get $new_file_flag"
20649
20650         local new_dir_mode=$(stat -c%f $migrate_dir)
20651         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20652                 error "expect mode $old_dir_mode get $new_dir_mode"
20653
20654         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20655         [ "$old_file_mode" = "$new_file_mode" ] ||
20656                 error "expect mode $old_file_mode get $new_file_mode"
20657
20658         diff /etc/passwd ${migrate_dir}/$tfile ||
20659                 error "$tfile different after migration"
20660
20661         diff /etc/passwd ${other_dir}/luna ||
20662                 error "luna different after migration"
20663
20664         diff /etc/passwd ${migrate_dir}/sofia ||
20665                 error "sofia different after migration"
20666
20667         diff /etc/passwd ${other_dir}/zachary ||
20668                 error "zachary different after migration"
20669
20670         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20671                 error "${tfile}_ln different after migration"
20672
20673         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20674                 error "${tfile}_ln_other different after migration"
20675
20676         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20677         [ $stripe_count = 2 ] ||
20678                 error "dir strpe_count $d != 2 after migration."
20679
20680         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20681         [ $stripe_count = 2 ] ||
20682                 error "file strpe_count $d != 2 after migration."
20683
20684         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20685 }
20686 run_test 230b "migrate directory"
20687
20688 test_230c() {
20689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20691         remote_mds_nodsh && skip "remote MDS with nodsh"
20692         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20693                 skip "Need MDS version at least 2.11.52"
20694
20695         local MDTIDX=1
20696         local total=3
20697         local mdt_index
20698         local file
20699         local migrate_dir=$DIR/$tdir/migrate_dir
20700
20701         #If migrating directory fails in the middle, all entries of
20702         #the directory is still accessiable.
20703         test_mkdir $DIR/$tdir
20704         test_mkdir -i0 -c1 $migrate_dir
20705         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20706         stat $migrate_dir
20707         createmany -o $migrate_dir/f $total ||
20708                 error "create files under ${migrate_dir} failed"
20709
20710         # fail after migrating top dir, and this will fail only once, so the
20711         # first sub file migration will fail (currently f3), others succeed.
20712         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20713         do_facet mds1 lctl set_param fail_loc=0x1801
20714         local t=$(ls $migrate_dir | wc -l)
20715         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20716                 error "migrate should fail"
20717         local u=$(ls $migrate_dir | wc -l)
20718         [ "$u" == "$t" ] || error "$u != $t during migration"
20719
20720         # add new dir/file should succeed
20721         mkdir $migrate_dir/dir ||
20722                 error "mkdir failed under migrating directory"
20723         touch $migrate_dir/file ||
20724                 error "create file failed under migrating directory"
20725
20726         # add file with existing name should fail
20727         for file in $migrate_dir/f*; do
20728                 stat $file > /dev/null || error "stat $file failed"
20729                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20730                         error "open(O_CREAT|O_EXCL) $file should fail"
20731                 $MULTIOP $file m && error "create $file should fail"
20732                 touch $DIR/$tdir/remote_dir/$tfile ||
20733                         error "touch $tfile failed"
20734                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20735                         error "link $file should fail"
20736                 mdt_index=$($LFS getstripe -m $file)
20737                 if [ $mdt_index == 0 ]; then
20738                         # file failed to migrate is not allowed to rename to
20739                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20740                                 error "rename to $file should fail"
20741                 else
20742                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20743                                 error "rename to $file failed"
20744                 fi
20745                 echo hello >> $file || error "write $file failed"
20746         done
20747
20748         # resume migration with different options should fail
20749         $LFS migrate -m 0 $migrate_dir &&
20750                 error "migrate -m 0 $migrate_dir should fail"
20751
20752         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20753                 error "migrate -c 2 $migrate_dir should fail"
20754
20755         # resume migration should succeed
20756         $LFS migrate -m $MDTIDX $migrate_dir ||
20757                 error "migrate $migrate_dir failed"
20758
20759         echo "Finish migration, then checking.."
20760         for file in $(find $migrate_dir); do
20761                 mdt_index=$($LFS getstripe -m $file)
20762                 [ $mdt_index == $MDTIDX ] ||
20763                         error "$file is not on MDT${MDTIDX}"
20764         done
20765
20766         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20767 }
20768 run_test 230c "check directory accessiblity if migration failed"
20769
20770 test_230d() {
20771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20772         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20773         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20774                 skip "Need MDS version at least 2.11.52"
20775         # LU-11235
20776         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20777
20778         local migrate_dir=$DIR/$tdir/migrate_dir
20779         local old_index
20780         local new_index
20781         local old_count
20782         local new_count
20783         local new_hash
20784         local mdt_index
20785         local i
20786         local j
20787
20788         old_index=$((RANDOM % MDSCOUNT))
20789         old_count=$((MDSCOUNT - old_index))
20790         new_index=$((RANDOM % MDSCOUNT))
20791         new_count=$((MDSCOUNT - new_index))
20792         new_hash=1 # for all_char
20793
20794         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20795         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20796
20797         test_mkdir $DIR/$tdir
20798         test_mkdir -i $old_index -c $old_count $migrate_dir
20799
20800         for ((i=0; i<100; i++)); do
20801                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20802                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20803                         error "create files under remote dir failed $i"
20804         done
20805
20806         echo -n "Migrate from MDT$old_index "
20807         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20808         echo -n "to MDT$new_index"
20809         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20810         echo
20811
20812         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20813         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20814                 error "migrate remote dir error"
20815
20816         echo "Finish migration, then checking.."
20817         for file in $(find $migrate_dir -maxdepth 1); do
20818                 mdt_index=$($LFS getstripe -m $file)
20819                 if [ $mdt_index -lt $new_index ] ||
20820                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20821                         error "$file is on MDT$mdt_index"
20822                 fi
20823         done
20824
20825         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20826 }
20827 run_test 230d "check migrate big directory"
20828
20829 test_230e() {
20830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20831         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20832         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20833                 skip "Need MDS version at least 2.11.52"
20834
20835         local i
20836         local j
20837         local a_fid
20838         local b_fid
20839
20840         mkdir_on_mdt0 $DIR/$tdir
20841         mkdir $DIR/$tdir/migrate_dir
20842         mkdir $DIR/$tdir/other_dir
20843         touch $DIR/$tdir/migrate_dir/a
20844         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20845         ls $DIR/$tdir/other_dir
20846
20847         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20848                 error "migrate dir fails"
20849
20850         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20851         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20852
20853         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20854         [ $mdt_index == 0 ] || error "a is not on MDT0"
20855
20856         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20857                 error "migrate dir fails"
20858
20859         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20860         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20861
20862         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20863         [ $mdt_index == 1 ] || error "a is not on MDT1"
20864
20865         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20866         [ $mdt_index == 1 ] || error "b is not on MDT1"
20867
20868         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20869         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20870
20871         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20872
20873         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20874 }
20875 run_test 230e "migrate mulitple local link files"
20876
20877 test_230f() {
20878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20880         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20881                 skip "Need MDS version at least 2.11.52"
20882
20883         local a_fid
20884         local ln_fid
20885
20886         mkdir -p $DIR/$tdir
20887         mkdir $DIR/$tdir/migrate_dir
20888         $LFS mkdir -i1 $DIR/$tdir/other_dir
20889         touch $DIR/$tdir/migrate_dir/a
20890         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20891         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20892         ls $DIR/$tdir/other_dir
20893
20894         # a should be migrated to MDT1, since no other links on MDT0
20895         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20896                 error "#1 migrate dir fails"
20897         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20898         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20899         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20900         [ $mdt_index == 1 ] || error "a is not on MDT1"
20901
20902         # a should stay on MDT1, because it is a mulitple link file
20903         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20904                 error "#2 migrate dir fails"
20905         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20906         [ $mdt_index == 1 ] || error "a is not on MDT1"
20907
20908         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20909                 error "#3 migrate dir fails"
20910
20911         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20912         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20913         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20914
20915         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20916         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20917
20918         # a should be migrated to MDT0, since no other links on MDT1
20919         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20920                 error "#4 migrate dir fails"
20921         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20922         [ $mdt_index == 0 ] || error "a is not on MDT0"
20923
20924         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20925 }
20926 run_test 230f "migrate mulitple remote link files"
20927
20928 test_230g() {
20929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20931         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20932                 skip "Need MDS version at least 2.11.52"
20933
20934         mkdir -p $DIR/$tdir/migrate_dir
20935
20936         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20937                 error "migrating dir to non-exist MDT succeeds"
20938         true
20939 }
20940 run_test 230g "migrate dir to non-exist MDT"
20941
20942 test_230h() {
20943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20946                 skip "Need MDS version at least 2.11.52"
20947
20948         local mdt_index
20949
20950         mkdir -p $DIR/$tdir/migrate_dir
20951
20952         $LFS migrate -m1 $DIR &&
20953                 error "migrating mountpoint1 should fail"
20954
20955         $LFS migrate -m1 $DIR/$tdir/.. &&
20956                 error "migrating mountpoint2 should fail"
20957
20958         # same as mv
20959         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20960                 error "migrating $tdir/migrate_dir/.. should fail"
20961
20962         true
20963 }
20964 run_test 230h "migrate .. and root"
20965
20966 test_230i() {
20967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20969         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20970                 skip "Need MDS version at least 2.11.52"
20971
20972         mkdir -p $DIR/$tdir/migrate_dir
20973
20974         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20975                 error "migration fails with a tailing slash"
20976
20977         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20978                 error "migration fails with two tailing slashes"
20979 }
20980 run_test 230i "lfs migrate -m tolerates trailing slashes"
20981
20982 test_230j() {
20983         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20984         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20985                 skip "Need MDS version at least 2.11.52"
20986
20987         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20988         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20989                 error "create $tfile failed"
20990         cat /etc/passwd > $DIR/$tdir/$tfile
20991
20992         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20993
20994         cmp /etc/passwd $DIR/$tdir/$tfile ||
20995                 error "DoM file mismatch after migration"
20996 }
20997 run_test 230j "DoM file data not changed after dir migration"
20998
20999 test_230k() {
21000         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21001         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21002                 skip "Need MDS version at least 2.11.56"
21003
21004         local total=20
21005         local files_on_starting_mdt=0
21006
21007         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21008         $LFS getdirstripe $DIR/$tdir
21009         for i in $(seq $total); do
21010                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21011                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21012                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21013         done
21014
21015         echo "$files_on_starting_mdt files on MDT0"
21016
21017         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21018         $LFS getdirstripe $DIR/$tdir
21019
21020         files_on_starting_mdt=0
21021         for i in $(seq $total); do
21022                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21023                         error "file $tfile.$i mismatch after migration"
21024                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21025                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21026         done
21027
21028         echo "$files_on_starting_mdt files on MDT1 after migration"
21029         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21030
21031         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21032         $LFS getdirstripe $DIR/$tdir
21033
21034         files_on_starting_mdt=0
21035         for i in $(seq $total); do
21036                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21037                         error "file $tfile.$i mismatch after 2nd migration"
21038                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21039                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21040         done
21041
21042         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21043         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21044
21045         true
21046 }
21047 run_test 230k "file data not changed after dir migration"
21048
21049 test_230l() {
21050         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21051         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21052                 skip "Need MDS version at least 2.11.56"
21053
21054         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21055         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21056                 error "create files under remote dir failed $i"
21057         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21058 }
21059 run_test 230l "readdir between MDTs won't crash"
21060
21061 test_230m() {
21062         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21063         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21064                 skip "Need MDS version at least 2.11.56"
21065
21066         local MDTIDX=1
21067         local mig_dir=$DIR/$tdir/migrate_dir
21068         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21069         local shortstr="b"
21070         local val
21071
21072         echo "Creating files and dirs with xattrs"
21073         test_mkdir $DIR/$tdir
21074         test_mkdir -i0 -c1 $mig_dir
21075         mkdir $mig_dir/dir
21076         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21077                 error "cannot set xattr attr1 on dir"
21078         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21079                 error "cannot set xattr attr2 on dir"
21080         touch $mig_dir/dir/f0
21081         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21082                 error "cannot set xattr attr1 on file"
21083         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21084                 error "cannot set xattr attr2 on file"
21085         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21086         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21087         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21088         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21089         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21090         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21091         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21092         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21093         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21094
21095         echo "Migrating to MDT1"
21096         $LFS migrate -m $MDTIDX $mig_dir ||
21097                 error "fails on migrating dir to MDT1"
21098
21099         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21100         echo "Checking xattrs"
21101         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21102         [ "$val" = $longstr ] ||
21103                 error "expecting xattr1 $longstr on dir, found $val"
21104         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21105         [ "$val" = $shortstr ] ||
21106                 error "expecting xattr2 $shortstr on dir, found $val"
21107         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21108         [ "$val" = $longstr ] ||
21109                 error "expecting xattr1 $longstr on file, found $val"
21110         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21111         [ "$val" = $shortstr ] ||
21112                 error "expecting xattr2 $shortstr on file, found $val"
21113 }
21114 run_test 230m "xattrs not changed after dir migration"
21115
21116 test_230n() {
21117         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21118         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21119                 skip "Need MDS version at least 2.13.53"
21120
21121         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21122         cat /etc/hosts > $DIR/$tdir/$tfile
21123         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21124         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21125
21126         cmp /etc/hosts $DIR/$tdir/$tfile ||
21127                 error "File data mismatch after migration"
21128 }
21129 run_test 230n "Dir migration with mirrored file"
21130
21131 test_230o() {
21132         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21133         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21134                 skip "Need MDS version at least 2.13.52"
21135
21136         local mdts=$(comma_list $(mdts_nodes))
21137         local timeout=100
21138         local restripe_status
21139         local delta
21140         local i
21141
21142         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21143
21144         # in case "crush" hash type is not set
21145         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21146
21147         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21148                            mdt.*MDT0000.enable_dir_restripe)
21149         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21150         stack_trap "do_nodes $mdts $LCTL set_param \
21151                     mdt.*.enable_dir_restripe=$restripe_status"
21152
21153         mkdir $DIR/$tdir
21154         createmany -m $DIR/$tdir/f 100 ||
21155                 error "create files under remote dir failed $i"
21156         createmany -d $DIR/$tdir/d 100 ||
21157                 error "create dirs under remote dir failed $i"
21158
21159         for i in $(seq 2 $MDSCOUNT); do
21160                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21161                 $LFS setdirstripe -c $i $DIR/$tdir ||
21162                         error "split -c $i $tdir failed"
21163                 wait_update $HOSTNAME \
21164                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21165                         error "dir split not finished"
21166                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21167                         awk '/migrate/ {sum += $2} END { print sum }')
21168                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21169                 # delta is around total_files/stripe_count
21170                 (( $delta < 200 / (i - 1) + 4 )) ||
21171                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21172         done
21173 }
21174 run_test 230o "dir split"
21175
21176 test_230p() {
21177         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21178         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21179                 skip "Need MDS version at least 2.13.52"
21180
21181         local mdts=$(comma_list $(mdts_nodes))
21182         local timeout=100
21183         local restripe_status
21184         local delta
21185         local c
21186
21187         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21188
21189         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21190
21191         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21192                            mdt.*MDT0000.enable_dir_restripe)
21193         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21194         stack_trap "do_nodes $mdts $LCTL set_param \
21195                     mdt.*.enable_dir_restripe=$restripe_status"
21196
21197         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21198         createmany -m $DIR/$tdir/f 100 ||
21199                 error "create files under remote dir failed"
21200         createmany -d $DIR/$tdir/d 100 ||
21201                 error "create dirs under remote dir failed"
21202
21203         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21204                 local mdt_hash="crush"
21205
21206                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21207                 $LFS setdirstripe -c $c $DIR/$tdir ||
21208                         error "split -c $c $tdir failed"
21209                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21210                         mdt_hash="$mdt_hash,fixed"
21211                 elif [ $c -eq 1 ]; then
21212                         mdt_hash="none"
21213                 fi
21214                 wait_update $HOSTNAME \
21215                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21216                         error "dir merge not finished"
21217                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21218                         awk '/migrate/ {sum += $2} END { print sum }')
21219                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21220                 # delta is around total_files/stripe_count
21221                 (( delta < 200 / c + 4 )) ||
21222                         error "$delta files migrated >= $((200 / c + 4))"
21223         done
21224 }
21225 run_test 230p "dir merge"
21226
21227 test_230q() {
21228         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21229         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21230                 skip "Need MDS version at least 2.13.52"
21231
21232         local mdts=$(comma_list $(mdts_nodes))
21233         local saved_threshold=$(do_facet mds1 \
21234                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21235         local saved_delta=$(do_facet mds1 \
21236                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21237         local threshold=100
21238         local delta=2
21239         local total=0
21240         local stripe_count=0
21241         local stripe_index
21242         local nr_files
21243         local create
21244
21245         # test with fewer files on ZFS
21246         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21247
21248         stack_trap "do_nodes $mdts $LCTL set_param \
21249                     mdt.*.dir_split_count=$saved_threshold"
21250         stack_trap "do_nodes $mdts $LCTL set_param \
21251                     mdt.*.dir_split_delta=$saved_delta"
21252         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21253         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21254         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21255         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21256         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21257         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21258
21259         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21260         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21261
21262         create=$((threshold * 3 / 2))
21263         while [ $stripe_count -lt $MDSCOUNT ]; do
21264                 createmany -m $DIR/$tdir/f $total $create ||
21265                         error "create sub files failed"
21266                 stat $DIR/$tdir > /dev/null
21267                 total=$((total + create))
21268                 stripe_count=$((stripe_count + delta))
21269                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21270
21271                 wait_update $HOSTNAME \
21272                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21273                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21274
21275                 wait_update $HOSTNAME \
21276                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21277                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21278
21279                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21280                 echo "$nr_files/$total files on MDT$stripe_index after split"
21281                 # allow 10% margin of imbalance with crush hash
21282                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21283                         error "$nr_files files on MDT$stripe_index after split"
21284
21285                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21286                 [ $nr_files -eq $total ] ||
21287                         error "total sub files $nr_files != $total"
21288         done
21289
21290         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21291
21292         echo "fixed layout directory won't auto split"
21293         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21294         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21295                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21296         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21297                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21298 }
21299 run_test 230q "dir auto split"
21300
21301 test_230r() {
21302         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21303         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21304         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21305                 skip "Need MDS version at least 2.13.54"
21306
21307         # maximum amount of local locks:
21308         # parent striped dir - 2 locks
21309         # new stripe in parent to migrate to - 1 lock
21310         # source and target - 2 locks
21311         # Total 5 locks for regular file
21312         mkdir -p $DIR/$tdir
21313         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21314         touch $DIR/$tdir/dir1/eee
21315
21316         # create 4 hardlink for 4 more locks
21317         # Total: 9 locks > RS_MAX_LOCKS (8)
21318         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21319         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21320         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21321         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21322         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21323         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21324         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21325         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21326
21327         cancel_lru_locks mdc
21328
21329         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21330                 error "migrate dir fails"
21331
21332         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21333 }
21334 run_test 230r "migrate with too many local locks"
21335
21336 test_230s() {
21337         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21338                 skip "Need MDS version at least 2.14.52"
21339
21340         local mdts=$(comma_list $(mdts_nodes))
21341         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21342                                 mdt.*MDT0000.enable_dir_restripe)
21343
21344         stack_trap "do_nodes $mdts $LCTL set_param \
21345                     mdt.*.enable_dir_restripe=$restripe_status"
21346
21347         local st
21348         for st in 0 1; do
21349                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21350                 test_mkdir $DIR/$tdir
21351                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21352                         error "$LFS mkdir should return EEXIST if target exists"
21353                 rmdir $DIR/$tdir
21354         done
21355 }
21356 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21357
21358 test_230t()
21359 {
21360         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21361         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21362                 skip "Need MDS version at least 2.14.50"
21363
21364         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21365         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21366         $LFS project -p 1 -s $DIR/$tdir ||
21367                 error "set $tdir project id failed"
21368         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21369                 error "set subdir project id failed"
21370         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21371 }
21372 run_test 230t "migrate directory with project ID set"
21373
21374 test_230u()
21375 {
21376         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21377         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21378                 skip "Need MDS version at least 2.14.53"
21379
21380         local count
21381
21382         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21383         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21384         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21385         for i in $(seq 0 $((MDSCOUNT - 1))); do
21386                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21387                 echo "$count dirs migrated to MDT$i"
21388         done
21389         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21390         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21391 }
21392 run_test 230u "migrate directory by QOS"
21393
21394 test_230v()
21395 {
21396         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21397         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21398                 skip "Need MDS version at least 2.14.53"
21399
21400         local count
21401
21402         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21403         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21404         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21405         for i in $(seq 0 $((MDSCOUNT - 1))); do
21406                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21407                 echo "$count subdirs migrated to MDT$i"
21408                 (( i == 3 )) && (( count > 0 )) &&
21409                         error "subdir shouldn't be migrated to MDT3"
21410         done
21411         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21412         (( count == 3 )) || error "dirs migrated to $count MDTs"
21413 }
21414 run_test 230v "subdir migrated to the MDT where its parent is located"
21415
21416 test_230w() {
21417         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21418         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21419                 skip "Need MDS version at least 2.15.0"
21420
21421         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21422         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21423         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21424
21425         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21426                 error "migrate failed"
21427
21428         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21429                 error "$tdir stripe count mismatch"
21430
21431         for i in $(seq 0 9); do
21432                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21433                         error "d$i is striped"
21434         done
21435 }
21436 run_test 230w "non-recursive mode dir migration"
21437
21438 test_230x() {
21439         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21440         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21441                 skip "Need MDS version at least 2.15.0"
21442
21443         mkdir -p $DIR/$tdir || error "mkdir failed"
21444         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21445
21446         local mdt_name=$(mdtname_from_index 0)
21447         local low=$(do_facet mds2 $LCTL get_param -n \
21448                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21449         local high=$(do_facet mds2 $LCTL get_param -n \
21450                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21451         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21452         local maxage=$(do_facet mds2 $LCTL get_param -n \
21453                 osp.*$mdt_name-osp-MDT0001.maxage)
21454
21455         stack_trap "do_facet mds2 $LCTL set_param -n \
21456                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21457                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21458         stack_trap "do_facet mds2 $LCTL set_param -n \
21459                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21460
21461         do_facet mds2 $LCTL set_param -n \
21462                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21463         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21464         sleep 4
21465         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21466                 error "migrate $tdir should fail"
21467
21468         do_facet mds2 $LCTL set_param -n \
21469                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21470         do_facet mds2 $LCTL set_param -n \
21471                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21472         sleep 4
21473         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21474                 error "migrate failed"
21475         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21476                 error "$tdir stripe count mismatch"
21477 }
21478 run_test 230x "dir migration check space"
21479
21480 test_231a()
21481 {
21482         # For simplicity this test assumes that max_pages_per_rpc
21483         # is the same across all OSCs
21484         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21485         local bulk_size=$((max_pages * PAGE_SIZE))
21486         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21487                                        head -n 1)
21488
21489         mkdir -p $DIR/$tdir
21490         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21491                 error "failed to set stripe with -S ${brw_size}M option"
21492
21493         # clear the OSC stats
21494         $LCTL set_param osc.*.stats=0 &>/dev/null
21495         stop_writeback
21496
21497         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21499                 oflag=direct &>/dev/null || error "dd failed"
21500
21501         sync; sleep 1; sync # just to be safe
21502         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21503         if [ x$nrpcs != "x1" ]; then
21504                 $LCTL get_param osc.*.stats
21505                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21506         fi
21507
21508         start_writeback
21509         # Drop the OSC cache, otherwise we will read from it
21510         cancel_lru_locks osc
21511
21512         # clear the OSC stats
21513         $LCTL set_param osc.*.stats=0 &>/dev/null
21514
21515         # Client reads $bulk_size.
21516         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21517                 iflag=direct &>/dev/null || error "dd failed"
21518
21519         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21520         if [ x$nrpcs != "x1" ]; then
21521                 $LCTL get_param osc.*.stats
21522                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21523         fi
21524 }
21525 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21526
21527 test_231b() {
21528         mkdir -p $DIR/$tdir
21529         local i
21530         for i in {0..1023}; do
21531                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21532                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21533                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21534         done
21535         sync
21536 }
21537 run_test 231b "must not assert on fully utilized OST request buffer"
21538
21539 test_232a() {
21540         mkdir -p $DIR/$tdir
21541         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21542
21543         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21544         do_facet ost1 $LCTL set_param fail_loc=0x31c
21545
21546         # ignore dd failure
21547         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21548
21549         do_facet ost1 $LCTL set_param fail_loc=0
21550         umount_client $MOUNT || error "umount failed"
21551         mount_client $MOUNT || error "mount failed"
21552         stop ost1 || error "cannot stop ost1"
21553         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21554 }
21555 run_test 232a "failed lock should not block umount"
21556
21557 test_232b() {
21558         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21559                 skip "Need MDS version at least 2.10.58"
21560
21561         mkdir -p $DIR/$tdir
21562         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21563         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21564         sync
21565         cancel_lru_locks osc
21566
21567         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21568         do_facet ost1 $LCTL set_param fail_loc=0x31c
21569
21570         # ignore failure
21571         $LFS data_version $DIR/$tdir/$tfile || true
21572
21573         do_facet ost1 $LCTL set_param fail_loc=0
21574         umount_client $MOUNT || error "umount failed"
21575         mount_client $MOUNT || error "mount failed"
21576         stop ost1 || error "cannot stop ost1"
21577         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21578 }
21579 run_test 232b "failed data version lock should not block umount"
21580
21581 test_233a() {
21582         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21583                 skip "Need MDS version at least 2.3.64"
21584         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21585
21586         local fid=$($LFS path2fid $MOUNT)
21587
21588         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21589                 error "cannot access $MOUNT using its FID '$fid'"
21590 }
21591 run_test 233a "checking that OBF of the FS root succeeds"
21592
21593 test_233b() {
21594         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21595                 skip "Need MDS version at least 2.5.90"
21596         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21597
21598         local fid=$($LFS path2fid $MOUNT/.lustre)
21599
21600         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21601                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21602
21603         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21604         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21605                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21606 }
21607 run_test 233b "checking that OBF of the FS .lustre succeeds"
21608
21609 test_234() {
21610         local p="$TMP/sanityN-$TESTNAME.parameters"
21611         save_lustre_params client "llite.*.xattr_cache" > $p
21612         lctl set_param llite.*.xattr_cache 1 ||
21613                 skip_env "xattr cache is not supported"
21614
21615         mkdir -p $DIR/$tdir || error "mkdir failed"
21616         touch $DIR/$tdir/$tfile || error "touch failed"
21617         # OBD_FAIL_LLITE_XATTR_ENOMEM
21618         $LCTL set_param fail_loc=0x1405
21619         getfattr -n user.attr $DIR/$tdir/$tfile &&
21620                 error "getfattr should have failed with ENOMEM"
21621         $LCTL set_param fail_loc=0x0
21622         rm -rf $DIR/$tdir
21623
21624         restore_lustre_params < $p
21625         rm -f $p
21626 }
21627 run_test 234 "xattr cache should not crash on ENOMEM"
21628
21629 test_235() {
21630         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21631                 skip "Need MDS version at least 2.4.52"
21632
21633         flock_deadlock $DIR/$tfile
21634         local RC=$?
21635         case $RC in
21636                 0)
21637                 ;;
21638                 124) error "process hangs on a deadlock"
21639                 ;;
21640                 *) error "error executing flock_deadlock $DIR/$tfile"
21641                 ;;
21642         esac
21643 }
21644 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21645
21646 #LU-2935
21647 test_236() {
21648         check_swap_layouts_support
21649
21650         local ref1=/etc/passwd
21651         local ref2=/etc/group
21652         local file1=$DIR/$tdir/f1
21653         local file2=$DIR/$tdir/f2
21654
21655         test_mkdir -c1 $DIR/$tdir
21656         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21657         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21658         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21659         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21660         local fd=$(free_fd)
21661         local cmd="exec $fd<>$file2"
21662         eval $cmd
21663         rm $file2
21664         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21665                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21666         cmd="exec $fd>&-"
21667         eval $cmd
21668         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21669
21670         #cleanup
21671         rm -rf $DIR/$tdir
21672 }
21673 run_test 236 "Layout swap on open unlinked file"
21674
21675 # LU-4659 linkea consistency
21676 test_238() {
21677         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21678                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21679                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21680                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21681
21682         touch $DIR/$tfile
21683         ln $DIR/$tfile $DIR/$tfile.lnk
21684         touch $DIR/$tfile.new
21685         mv $DIR/$tfile.new $DIR/$tfile
21686         local fid1=$($LFS path2fid $DIR/$tfile)
21687         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21688         local path1=$($LFS fid2path $FSNAME "$fid1")
21689         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21690         local path2=$($LFS fid2path $FSNAME "$fid2")
21691         [ $tfile.lnk == $path2 ] ||
21692                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21693         rm -f $DIR/$tfile*
21694 }
21695 run_test 238 "Verify linkea consistency"
21696
21697 test_239A() { # was test_239
21698         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21699                 skip "Need MDS version at least 2.5.60"
21700
21701         local list=$(comma_list $(mdts_nodes))
21702
21703         mkdir -p $DIR/$tdir
21704         createmany -o $DIR/$tdir/f- 5000
21705         unlinkmany $DIR/$tdir/f- 5000
21706         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21707                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21708         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21709                         osp.*MDT*.sync_in_flight" | calc_sum)
21710         [ "$changes" -eq 0 ] || error "$changes not synced"
21711 }
21712 run_test 239A "osp_sync test"
21713
21714 test_239a() { #LU-5297
21715         remote_mds_nodsh && skip "remote MDS with nodsh"
21716
21717         touch $DIR/$tfile
21718         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21719         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21720         chgrp $RUNAS_GID $DIR/$tfile
21721         wait_delete_completed
21722 }
21723 run_test 239a "process invalid osp sync record correctly"
21724
21725 test_239b() { #LU-5297
21726         remote_mds_nodsh && skip "remote MDS with nodsh"
21727
21728         touch $DIR/$tfile1
21729         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21730         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21731         chgrp $RUNAS_GID $DIR/$tfile1
21732         wait_delete_completed
21733         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21734         touch $DIR/$tfile2
21735         chgrp $RUNAS_GID $DIR/$tfile2
21736         wait_delete_completed
21737 }
21738 run_test 239b "process osp sync record with ENOMEM error correctly"
21739
21740 test_240() {
21741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21742         remote_mds_nodsh && skip "remote MDS with nodsh"
21743
21744         mkdir -p $DIR/$tdir
21745
21746         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21747                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21748         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21749                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21750
21751         umount_client $MOUNT || error "umount failed"
21752         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21753         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21754         mount_client $MOUNT || error "failed to mount client"
21755
21756         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21757         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21758 }
21759 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21760
21761 test_241_bio() {
21762         local count=$1
21763         local bsize=$2
21764
21765         for LOOP in $(seq $count); do
21766                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21767                 cancel_lru_locks $OSC || true
21768         done
21769 }
21770
21771 test_241_dio() {
21772         local count=$1
21773         local bsize=$2
21774
21775         for LOOP in $(seq $1); do
21776                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21777                         2>/dev/null
21778         done
21779 }
21780
21781 test_241a() { # was test_241
21782         local bsize=$PAGE_SIZE
21783
21784         (( bsize < 40960 )) && bsize=40960
21785         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21786         ls -la $DIR/$tfile
21787         cancel_lru_locks $OSC
21788         test_241_bio 1000 $bsize &
21789         PID=$!
21790         test_241_dio 1000 $bsize
21791         wait $PID
21792 }
21793 run_test 241a "bio vs dio"
21794
21795 test_241b() {
21796         local bsize=$PAGE_SIZE
21797
21798         (( bsize < 40960 )) && bsize=40960
21799         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21800         ls -la $DIR/$tfile
21801         test_241_dio 1000 $bsize &
21802         PID=$!
21803         test_241_dio 1000 $bsize
21804         wait $PID
21805 }
21806 run_test 241b "dio vs dio"
21807
21808 test_242() {
21809         remote_mds_nodsh && skip "remote MDS with nodsh"
21810
21811         mkdir_on_mdt0 $DIR/$tdir
21812         touch $DIR/$tdir/$tfile
21813
21814         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21815         do_facet mds1 lctl set_param fail_loc=0x105
21816         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21817
21818         do_facet mds1 lctl set_param fail_loc=0
21819         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21820 }
21821 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21822
21823 test_243()
21824 {
21825         test_mkdir $DIR/$tdir
21826         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21827 }
21828 run_test 243 "various group lock tests"
21829
21830 test_244a()
21831 {
21832         test_mkdir $DIR/$tdir
21833         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21834         sendfile_grouplock $DIR/$tdir/$tfile || \
21835                 error "sendfile+grouplock failed"
21836         rm -rf $DIR/$tdir
21837 }
21838 run_test 244a "sendfile with group lock tests"
21839
21840 test_244b()
21841 {
21842         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21843
21844         local threads=50
21845         local size=$((1024*1024))
21846
21847         test_mkdir $DIR/$tdir
21848         for i in $(seq 1 $threads); do
21849                 local file=$DIR/$tdir/file_$((i / 10))
21850                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21851                 local pids[$i]=$!
21852         done
21853         for i in $(seq 1 $threads); do
21854                 wait ${pids[$i]}
21855         done
21856 }
21857 run_test 244b "multi-threaded write with group lock"
21858
21859 test_245a() {
21860         local flagname="multi_mod_rpcs"
21861         local connect_data_name="max_mod_rpcs"
21862         local out
21863
21864         # check if multiple modify RPCs flag is set
21865         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21866                 grep "connect_flags:")
21867         echo "$out"
21868
21869         echo "$out" | grep -qw $flagname
21870         if [ $? -ne 0 ]; then
21871                 echo "connect flag $flagname is not set"
21872                 return
21873         fi
21874
21875         # check if multiple modify RPCs data is set
21876         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21877         echo "$out"
21878
21879         echo "$out" | grep -qw $connect_data_name ||
21880                 error "import should have connect data $connect_data_name"
21881 }
21882 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21883
21884 test_245b() {
21885         local flagname="multi_mod_rpcs"
21886         local connect_data_name="max_mod_rpcs"
21887         local out
21888
21889         remote_mds_nodsh && skip "remote MDS with nodsh"
21890         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21891
21892         # check if multiple modify RPCs flag is set
21893         out=$(do_facet mds1 \
21894               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21895               grep "connect_flags:")
21896         echo "$out"
21897
21898         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21899
21900         # check if multiple modify RPCs data is set
21901         out=$(do_facet mds1 \
21902               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21903
21904         [[ "$out" =~ $connect_data_name ]] ||
21905                 {
21906                         echo "$out"
21907                         error "missing connect data $connect_data_name"
21908                 }
21909 }
21910 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21911
21912 cleanup_247() {
21913         local submount=$1
21914
21915         trap 0
21916         umount_client $submount
21917         rmdir $submount
21918 }
21919
21920 test_247a() {
21921         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21922                 grep -q subtree ||
21923                 skip_env "Fileset feature is not supported"
21924
21925         local submount=${MOUNT}_$tdir
21926
21927         mkdir $MOUNT/$tdir
21928         mkdir -p $submount || error "mkdir $submount failed"
21929         FILESET="$FILESET/$tdir" mount_client $submount ||
21930                 error "mount $submount failed"
21931         trap "cleanup_247 $submount" EXIT
21932         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21933         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21934                 error "read $MOUNT/$tdir/$tfile failed"
21935         cleanup_247 $submount
21936 }
21937 run_test 247a "mount subdir as fileset"
21938
21939 test_247b() {
21940         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21941                 skip_env "Fileset feature is not supported"
21942
21943         local submount=${MOUNT}_$tdir
21944
21945         rm -rf $MOUNT/$tdir
21946         mkdir -p $submount || error "mkdir $submount failed"
21947         SKIP_FILESET=1
21948         FILESET="$FILESET/$tdir" mount_client $submount &&
21949                 error "mount $submount should fail"
21950         rmdir $submount
21951 }
21952 run_test 247b "mount subdir that dose not exist"
21953
21954 test_247c() {
21955         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21956                 skip_env "Fileset feature is not supported"
21957
21958         local submount=${MOUNT}_$tdir
21959
21960         mkdir -p $MOUNT/$tdir/dir1
21961         mkdir -p $submount || error "mkdir $submount failed"
21962         trap "cleanup_247 $submount" EXIT
21963         FILESET="$FILESET/$tdir" mount_client $submount ||
21964                 error "mount $submount failed"
21965         local fid=$($LFS path2fid $MOUNT/)
21966         $LFS fid2path $submount $fid && error "fid2path should fail"
21967         cleanup_247 $submount
21968 }
21969 run_test 247c "running fid2path outside subdirectory root"
21970
21971 test_247d() {
21972         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21973                 skip "Fileset feature is not supported"
21974
21975         local submount=${MOUNT}_$tdir
21976
21977         mkdir -p $MOUNT/$tdir/dir1
21978         mkdir -p $submount || error "mkdir $submount failed"
21979         FILESET="$FILESET/$tdir" mount_client $submount ||
21980                 error "mount $submount failed"
21981         trap "cleanup_247 $submount" EXIT
21982
21983         local td=$submount/dir1
21984         local fid=$($LFS path2fid $td)
21985         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21986
21987         # check that we get the same pathname back
21988         local rootpath
21989         local found
21990         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21991                 echo "$rootpath $fid"
21992                 found=$($LFS fid2path $rootpath "$fid")
21993                 [ -n "$found" ] || error "fid2path should succeed"
21994                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21995         done
21996         # check wrong root path format
21997         rootpath=$submount"_wrong"
21998         found=$($LFS fid2path $rootpath "$fid")
21999         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22000
22001         cleanup_247 $submount
22002 }
22003 run_test 247d "running fid2path inside subdirectory root"
22004
22005 # LU-8037
22006 test_247e() {
22007         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22008                 grep -q subtree ||
22009                 skip "Fileset feature is not supported"
22010
22011         local submount=${MOUNT}_$tdir
22012
22013         mkdir $MOUNT/$tdir
22014         mkdir -p $submount || error "mkdir $submount failed"
22015         FILESET="$FILESET/.." mount_client $submount &&
22016                 error "mount $submount should fail"
22017         rmdir $submount
22018 }
22019 run_test 247e "mount .. as fileset"
22020
22021 test_247f() {
22022         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22023         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22024                 skip "Need at least version 2.14.50.162"
22025         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22026                 skip "Fileset feature is not supported"
22027
22028         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22029         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22030                 error "mkdir remote failed"
22031         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22032                 error "mkdir remote/subdir failed"
22033         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22034                 error "mkdir striped failed"
22035         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22036
22037         local submount=${MOUNT}_$tdir
22038
22039         mkdir -p $submount || error "mkdir $submount failed"
22040         stack_trap "rmdir $submount"
22041
22042         local dir
22043         local fileset=$FILESET
22044         local mdts=$(comma_list $(mdts_nodes))
22045
22046         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22047         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22048                 $tdir/striped/subdir $tdir/striped/.; do
22049                 FILESET="$fileset/$dir" mount_client $submount ||
22050                         error "mount $dir failed"
22051                 umount_client $submount
22052         done
22053 }
22054 run_test 247f "mount striped or remote directory as fileset"
22055
22056 test_subdir_mount_lock()
22057 {
22058         local testdir=$1
22059         local submount=${MOUNT}_$(basename $testdir)
22060
22061         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22062
22063         mkdir -p $submount || error "mkdir $submount failed"
22064         stack_trap "rmdir $submount"
22065
22066         FILESET="$fileset/$testdir" mount_client $submount ||
22067                 error "mount $FILESET failed"
22068         stack_trap "umount $submount"
22069
22070         local mdts=$(comma_list $(mdts_nodes))
22071
22072         local nrpcs
22073
22074         stat $submount > /dev/null || error "stat $submount failed"
22075         cancel_lru_locks $MDC
22076         stat $submount > /dev/null || error "stat $submount failed"
22077         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22078         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22079         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22080         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22081                 awk '/getattr/ {sum += $2} END {print sum}')
22082
22083         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22084 }
22085
22086 test_247g() {
22087         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22088
22089         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22090                 error "mkdir $tdir failed"
22091         test_subdir_mount_lock $tdir
22092 }
22093 run_test 247g "striped directory submount revalidate ROOT from cache"
22094
22095 test_247h() {
22096         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22097         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22098                 skip "Need MDS version at least 2.15.51"
22099
22100         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22101         test_subdir_mount_lock $tdir
22102         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22103         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22104                 error "mkdir $tdir.1 failed"
22105         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22106 }
22107 run_test 247h "remote directory submount revalidate ROOT from cache"
22108
22109 test_248a() {
22110         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22111         [ -z "$fast_read_sav" ] && skip "no fast read support"
22112
22113         # create a large file for fast read verification
22114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22115
22116         # make sure the file is created correctly
22117         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22118                 { rm -f $DIR/$tfile; skip "file creation error"; }
22119
22120         echo "Test 1: verify that fast read is 4 times faster on cache read"
22121
22122         # small read with fast read enabled
22123         $LCTL set_param -n llite.*.fast_read=1
22124         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22125                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22126                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22127         # small read with fast read disabled
22128         $LCTL set_param -n llite.*.fast_read=0
22129         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22130                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22131                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22132
22133         # verify that fast read is 4 times faster for cache read
22134         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22135                 error_not_in_vm "fast read was not 4 times faster: " \
22136                            "$t_fast vs $t_slow"
22137
22138         echo "Test 2: verify the performance between big and small read"
22139         $LCTL set_param -n llite.*.fast_read=1
22140
22141         # 1k non-cache read
22142         cancel_lru_locks osc
22143         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22144                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22145                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22146
22147         # 1M non-cache read
22148         cancel_lru_locks osc
22149         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22150                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22151                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22152
22153         # verify that big IO is not 4 times faster than small IO
22154         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22155                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22156
22157         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22158         rm -f $DIR/$tfile
22159 }
22160 run_test 248a "fast read verification"
22161
22162 test_248b() {
22163         # Default short_io_bytes=16384, try both smaller and larger sizes.
22164         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22165         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22166         echo "bs=53248 count=113 normal buffered write"
22167         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22168                 error "dd of initial data file failed"
22169         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22170
22171         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22172         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22173                 error "dd with sync normal writes failed"
22174         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22175
22176         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22177         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22178                 error "dd with sync small writes failed"
22179         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22180
22181         cancel_lru_locks osc
22182
22183         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22184         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22185         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22186         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22187                 iflag=direct || error "dd with O_DIRECT small read failed"
22188         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22189         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22190                 error "compare $TMP/$tfile.1 failed"
22191
22192         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22193         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22194
22195         # just to see what the maximum tunable value is, and test parsing
22196         echo "test invalid parameter 2MB"
22197         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22198                 error "too-large short_io_bytes allowed"
22199         echo "test maximum parameter 512KB"
22200         # if we can set a larger short_io_bytes, run test regardless of version
22201         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22202                 # older clients may not allow setting it this large, that's OK
22203                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22204                         skip "Need at least client version 2.13.50"
22205                 error "medium short_io_bytes failed"
22206         fi
22207         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22208         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22209
22210         echo "test large parameter 64KB"
22211         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22212         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22213
22214         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22215         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22216                 error "dd with sync large writes failed"
22217         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22218
22219         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22220         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22221         num=$((113 * 4096 / PAGE_SIZE))
22222         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22223         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22224                 error "dd with O_DIRECT large writes failed"
22225         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22226                 error "compare $DIR/$tfile.3 failed"
22227
22228         cancel_lru_locks osc
22229
22230         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22231         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22232                 error "dd with O_DIRECT large read failed"
22233         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22234                 error "compare $TMP/$tfile.2 failed"
22235
22236         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22237         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22238                 error "dd with O_DIRECT large read failed"
22239         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22240                 error "compare $TMP/$tfile.3 failed"
22241 }
22242 run_test 248b "test short_io read and write for both small and large sizes"
22243
22244 test_249() { # LU-7890
22245         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22246                 skip "Need at least version 2.8.54"
22247
22248         rm -f $DIR/$tfile
22249         $LFS setstripe -c 1 $DIR/$tfile
22250         # Offset 2T == 4k * 512M
22251         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22252                 error "dd to 2T offset failed"
22253 }
22254 run_test 249 "Write above 2T file size"
22255
22256 test_250() {
22257         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22258          && skip "no 16TB file size limit on ZFS"
22259
22260         $LFS setstripe -c 1 $DIR/$tfile
22261         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22262         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22263         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22264         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22265                 conv=notrunc,fsync && error "append succeeded"
22266         return 0
22267 }
22268 run_test 250 "Write above 16T limit"
22269
22270 test_251() {
22271         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22272
22273         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22274         #Skip once - writing the first stripe will succeed
22275         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22276         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22277                 error "short write happened"
22278
22279         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22280         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22281                 error "short read happened"
22282
22283         rm -f $DIR/$tfile
22284 }
22285 run_test 251 "Handling short read and write correctly"
22286
22287 test_252() {
22288         remote_mds_nodsh && skip "remote MDS with nodsh"
22289         remote_ost_nodsh && skip "remote OST with nodsh"
22290         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22291                 skip_env "ldiskfs only test"
22292         fi
22293
22294         local tgt
22295         local dev
22296         local out
22297         local uuid
22298         local num
22299         local gen
22300
22301         # check lr_reader on OST0000
22302         tgt=ost1
22303         dev=$(facet_device $tgt)
22304         out=$(do_facet $tgt $LR_READER $dev)
22305         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22306         echo "$out"
22307         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22308         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22309                 error "Invalid uuid returned by $LR_READER on target $tgt"
22310         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22311
22312         # check lr_reader -c on MDT0000
22313         tgt=mds1
22314         dev=$(facet_device $tgt)
22315         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22316                 skip "$LR_READER does not support additional options"
22317         fi
22318         out=$(do_facet $tgt $LR_READER -c $dev)
22319         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22320         echo "$out"
22321         num=$(echo "$out" | grep -c "mdtlov")
22322         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22323                 error "Invalid number of mdtlov clients returned by $LR_READER"
22324         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22325
22326         # check lr_reader -cr on MDT0000
22327         out=$(do_facet $tgt $LR_READER -cr $dev)
22328         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22329         echo "$out"
22330         echo "$out" | grep -q "^reply_data:$" ||
22331                 error "$LR_READER should have returned 'reply_data' section"
22332         num=$(echo "$out" | grep -c "client_generation")
22333         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22334 }
22335 run_test 252 "check lr_reader tool"
22336
22337 test_253() {
22338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22339         remote_mds_nodsh && skip "remote MDS with nodsh"
22340         remote_mgs_nodsh && skip "remote MGS with nodsh"
22341
22342         local ostidx=0
22343         local rc=0
22344         local ost_name=$(ostname_from_index $ostidx)
22345
22346         # on the mdt's osc
22347         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22348         do_facet $SINGLEMDS $LCTL get_param -n \
22349                 osp.$mdtosc_proc1.reserved_mb_high ||
22350                 skip  "remote MDS does not support reserved_mb_high"
22351
22352         rm -rf $DIR/$tdir
22353         wait_mds_ost_sync
22354         wait_delete_completed
22355         mkdir $DIR/$tdir
22356
22357         pool_add $TESTNAME || error "Pool creation failed"
22358         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22359
22360         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22361                 error "Setstripe failed"
22362
22363         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22364
22365         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22366                     grep "watermarks")
22367         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22368
22369         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22370                         osp.$mdtosc_proc1.prealloc_status)
22371         echo "prealloc_status $oa_status"
22372
22373         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22374                 error "File creation should fail"
22375
22376         #object allocation was stopped, but we still able to append files
22377         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22378                 oflag=append || error "Append failed"
22379
22380         rm -f $DIR/$tdir/$tfile.0
22381
22382         # For this test, we want to delete the files we created to go out of
22383         # space but leave the watermark, so we remain nearly out of space
22384         ost_watermarks_enospc_delete_files $tfile $ostidx
22385
22386         wait_delete_completed
22387
22388         sleep_maxage
22389
22390         for i in $(seq 10 12); do
22391                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22392                         2>/dev/null || error "File creation failed after rm"
22393         done
22394
22395         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22396                         osp.$mdtosc_proc1.prealloc_status)
22397         echo "prealloc_status $oa_status"
22398
22399         if (( oa_status != 0 )); then
22400                 error "Object allocation still disable after rm"
22401         fi
22402 }
22403 run_test 253 "Check object allocation limit"
22404
22405 test_254() {
22406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22407         remote_mds_nodsh && skip "remote MDS with nodsh"
22408
22409         local mdt=$(facet_svc $SINGLEMDS)
22410
22411         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22412                 skip "MDS does not support changelog_size"
22413
22414         local cl_user
22415
22416         changelog_register || error "changelog_register failed"
22417
22418         changelog_clear 0 || error "changelog_clear failed"
22419
22420         local size1=$(do_facet $SINGLEMDS \
22421                       $LCTL get_param -n mdd.$mdt.changelog_size)
22422         echo "Changelog size $size1"
22423
22424         rm -rf $DIR/$tdir
22425         $LFS mkdir -i 0 $DIR/$tdir
22426         # change something
22427         mkdir -p $DIR/$tdir/pics/2008/zachy
22428         touch $DIR/$tdir/pics/2008/zachy/timestamp
22429         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22430         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22431         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22432         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22433         rm $DIR/$tdir/pics/desktop.jpg
22434
22435         local size2=$(do_facet $SINGLEMDS \
22436                       $LCTL get_param -n mdd.$mdt.changelog_size)
22437         echo "Changelog size after work $size2"
22438
22439         (( $size2 > $size1 )) ||
22440                 error "new Changelog size=$size2 less than old size=$size1"
22441 }
22442 run_test 254 "Check changelog size"
22443
22444 ladvise_no_type()
22445 {
22446         local type=$1
22447         local file=$2
22448
22449         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22450                 awk -F: '{print $2}' | grep $type > /dev/null
22451         if [ $? -ne 0 ]; then
22452                 return 0
22453         fi
22454         return 1
22455 }
22456
22457 ladvise_no_ioctl()
22458 {
22459         local file=$1
22460
22461         lfs ladvise -a willread $file > /dev/null 2>&1
22462         if [ $? -eq 0 ]; then
22463                 return 1
22464         fi
22465
22466         lfs ladvise -a willread $file 2>&1 |
22467                 grep "Inappropriate ioctl for device" > /dev/null
22468         if [ $? -eq 0 ]; then
22469                 return 0
22470         fi
22471         return 1
22472 }
22473
22474 percent() {
22475         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22476 }
22477
22478 # run a random read IO workload
22479 # usage: random_read_iops <filename> <filesize> <iosize>
22480 random_read_iops() {
22481         local file=$1
22482         local fsize=$2
22483         local iosize=${3:-4096}
22484
22485         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22486                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22487 }
22488
22489 drop_file_oss_cache() {
22490         local file="$1"
22491         local nodes="$2"
22492
22493         $LFS ladvise -a dontneed $file 2>/dev/null ||
22494                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22495 }
22496
22497 ladvise_willread_performance()
22498 {
22499         local repeat=10
22500         local average_origin=0
22501         local average_cache=0
22502         local average_ladvise=0
22503
22504         for ((i = 1; i <= $repeat; i++)); do
22505                 echo "Iter $i/$repeat: reading without willread hint"
22506                 cancel_lru_locks osc
22507                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22508                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22509                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22510                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22511
22512                 cancel_lru_locks osc
22513                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22514                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22515                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22516
22517                 cancel_lru_locks osc
22518                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22519                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22520                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22521                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22522                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22523         done
22524         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22525         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22526         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22527
22528         speedup_cache=$(percent $average_cache $average_origin)
22529         speedup_ladvise=$(percent $average_ladvise $average_origin)
22530
22531         echo "Average uncached read: $average_origin"
22532         echo "Average speedup with OSS cached read: " \
22533                 "$average_cache = +$speedup_cache%"
22534         echo "Average speedup with ladvise willread: " \
22535                 "$average_ladvise = +$speedup_ladvise%"
22536
22537         local lowest_speedup=20
22538         if (( ${average_cache%.*} < $lowest_speedup )); then
22539                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22540                      " got $average_cache%. Skipping ladvise willread check."
22541                 return 0
22542         fi
22543
22544         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22545         # it is still good to run until then to exercise 'ladvise willread'
22546         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22547                 [ "$ost1_FSTYPE" = "zfs" ] &&
22548                 echo "osd-zfs does not support dontneed or drop_caches" &&
22549                 return 0
22550
22551         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22552         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22553                 error_not_in_vm "Speedup with willread is less than " \
22554                         "$lowest_speedup%, got $average_ladvise%"
22555 }
22556
22557 test_255a() {
22558         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22559                 skip "lustre < 2.8.54 does not support ladvise "
22560         remote_ost_nodsh && skip "remote OST with nodsh"
22561
22562         stack_trap "rm -f $DIR/$tfile"
22563         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22564
22565         ladvise_no_type willread $DIR/$tfile &&
22566                 skip "willread ladvise is not supported"
22567
22568         ladvise_no_ioctl $DIR/$tfile &&
22569                 skip "ladvise ioctl is not supported"
22570
22571         local size_mb=100
22572         local size=$((size_mb * 1048576))
22573         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22574                 error "dd to $DIR/$tfile failed"
22575
22576         lfs ladvise -a willread $DIR/$tfile ||
22577                 error "Ladvise failed with no range argument"
22578
22579         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22580                 error "Ladvise failed with no -l or -e argument"
22581
22582         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22583                 error "Ladvise failed with only -e argument"
22584
22585         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22586                 error "Ladvise failed with only -l argument"
22587
22588         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22589                 error "End offset should not be smaller than start offset"
22590
22591         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22592                 error "End offset should not be equal to start offset"
22593
22594         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22595                 error "Ladvise failed with overflowing -s argument"
22596
22597         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22598                 error "Ladvise failed with overflowing -e argument"
22599
22600         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22601                 error "Ladvise failed with overflowing -l argument"
22602
22603         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22604                 error "Ladvise succeeded with conflicting -l and -e arguments"
22605
22606         echo "Synchronous ladvise should wait"
22607         local delay=4
22608 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22609         do_nodes $(comma_list $(osts_nodes)) \
22610                 $LCTL set_param fail_val=$delay fail_loc=0x237
22611
22612         local start_ts=$SECONDS
22613         lfs ladvise -a willread $DIR/$tfile ||
22614                 error "Ladvise failed with no range argument"
22615         local end_ts=$SECONDS
22616         local inteval_ts=$((end_ts - start_ts))
22617
22618         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22619                 error "Synchronous advice didn't wait reply"
22620         fi
22621
22622         echo "Asynchronous ladvise shouldn't wait"
22623         local start_ts=$SECONDS
22624         lfs ladvise -a willread -b $DIR/$tfile ||
22625                 error "Ladvise failed with no range argument"
22626         local end_ts=$SECONDS
22627         local inteval_ts=$((end_ts - start_ts))
22628
22629         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22630                 error "Asynchronous advice blocked"
22631         fi
22632
22633         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22634         ladvise_willread_performance
22635 }
22636 run_test 255a "check 'lfs ladvise -a willread'"
22637
22638 facet_meminfo() {
22639         local facet=$1
22640         local info=$2
22641
22642         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22643 }
22644
22645 test_255b() {
22646         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22647                 skip "lustre < 2.8.54 does not support ladvise "
22648         remote_ost_nodsh && skip "remote OST with nodsh"
22649
22650         stack_trap "rm -f $DIR/$tfile"
22651         lfs setstripe -c 1 -i 0 $DIR/$tfile
22652
22653         ladvise_no_type dontneed $DIR/$tfile &&
22654                 skip "dontneed ladvise is not supported"
22655
22656         ladvise_no_ioctl $DIR/$tfile &&
22657                 skip "ladvise ioctl is not supported"
22658
22659         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22660                 [ "$ost1_FSTYPE" = "zfs" ] &&
22661                 skip "zfs-osd does not support 'ladvise dontneed'"
22662
22663         local size_mb=100
22664         local size=$((size_mb * 1048576))
22665         # In order to prevent disturbance of other processes, only check 3/4
22666         # of the memory usage
22667         local kibibytes=$((size_mb * 1024 * 3 / 4))
22668
22669         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22670                 error "dd to $DIR/$tfile failed"
22671
22672         #force write to complete before dropping OST cache & checking memory
22673         sync
22674
22675         local total=$(facet_meminfo ost1 MemTotal)
22676         echo "Total memory: $total KiB"
22677
22678         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22679         local before_read=$(facet_meminfo ost1 Cached)
22680         echo "Cache used before read: $before_read KiB"
22681
22682         lfs ladvise -a willread $DIR/$tfile ||
22683                 error "Ladvise willread failed"
22684         local after_read=$(facet_meminfo ost1 Cached)
22685         echo "Cache used after read: $after_read KiB"
22686
22687         lfs ladvise -a dontneed $DIR/$tfile ||
22688                 error "Ladvise dontneed again failed"
22689         local no_read=$(facet_meminfo ost1 Cached)
22690         echo "Cache used after dontneed ladvise: $no_read KiB"
22691
22692         if [ $total -lt $((before_read + kibibytes)) ]; then
22693                 echo "Memory is too small, abort checking"
22694                 return 0
22695         fi
22696
22697         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22698                 error "Ladvise willread should use more memory" \
22699                         "than $kibibytes KiB"
22700         fi
22701
22702         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22703                 error "Ladvise dontneed should release more memory" \
22704                         "than $kibibytes KiB"
22705         fi
22706 }
22707 run_test 255b "check 'lfs ladvise -a dontneed'"
22708
22709 test_255c() {
22710         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22711                 skip "lustre < 2.10.50 does not support lockahead"
22712
22713         local ost1_imp=$(get_osc_import_name client ost1)
22714         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22715                          cut -d'.' -f2)
22716         local count
22717         local new_count
22718         local difference
22719         local i
22720         local rc
22721
22722         test_mkdir -p $DIR/$tdir
22723         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22724
22725         #test 10 returns only success/failure
22726         i=10
22727         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22728         rc=$?
22729         if [ $rc -eq 255 ]; then
22730                 error "Ladvise test${i} failed, ${rc}"
22731         fi
22732
22733         #test 11 counts lock enqueue requests, all others count new locks
22734         i=11
22735         count=$(do_facet ost1 \
22736                 $LCTL get_param -n ost.OSS.ost.stats)
22737         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22738
22739         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22740         rc=$?
22741         if [ $rc -eq 255 ]; then
22742                 error "Ladvise test${i} failed, ${rc}"
22743         fi
22744
22745         new_count=$(do_facet ost1 \
22746                 $LCTL get_param -n ost.OSS.ost.stats)
22747         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22748                    awk '{ print $2 }')
22749
22750         difference="$((new_count - count))"
22751         if [ $difference -ne $rc ]; then
22752                 error "Ladvise test${i}, bad enqueue count, returned " \
22753                       "${rc}, actual ${difference}"
22754         fi
22755
22756         for i in $(seq 12 21); do
22757                 # If we do not do this, we run the risk of having too many
22758                 # locks and starting lock cancellation while we are checking
22759                 # lock counts.
22760                 cancel_lru_locks osc
22761
22762                 count=$($LCTL get_param -n \
22763                        ldlm.namespaces.$imp_name.lock_unused_count)
22764
22765                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22766                 rc=$?
22767                 if [ $rc -eq 255 ]; then
22768                         error "Ladvise test ${i} failed, ${rc}"
22769                 fi
22770
22771                 new_count=$($LCTL get_param -n \
22772                        ldlm.namespaces.$imp_name.lock_unused_count)
22773                 difference="$((new_count - count))"
22774
22775                 # Test 15 output is divided by 100 to map down to valid return
22776                 if [ $i -eq 15 ]; then
22777                         rc="$((rc * 100))"
22778                 fi
22779
22780                 if [ $difference -ne $rc ]; then
22781                         error "Ladvise test ${i}, bad lock count, returned " \
22782                               "${rc}, actual ${difference}"
22783                 fi
22784         done
22785
22786         #test 22 returns only success/failure
22787         i=22
22788         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22789         rc=$?
22790         if [ $rc -eq 255 ]; then
22791                 error "Ladvise test${i} failed, ${rc}"
22792         fi
22793 }
22794 run_test 255c "suite of ladvise lockahead tests"
22795
22796 test_256() {
22797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22798         remote_mds_nodsh && skip "remote MDS with nodsh"
22799         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22800         changelog_users $SINGLEMDS | grep "^cl" &&
22801                 skip "active changelog user"
22802
22803         local cl_user
22804         local cat_sl
22805         local mdt_dev
22806
22807         mdt_dev=$(facet_device $SINGLEMDS)
22808         echo $mdt_dev
22809
22810         changelog_register || error "changelog_register failed"
22811
22812         rm -rf $DIR/$tdir
22813         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22814
22815         changelog_clear 0 || error "changelog_clear failed"
22816
22817         # change something
22818         touch $DIR/$tdir/{1..10}
22819
22820         # stop the MDT
22821         stop $SINGLEMDS || error "Fail to stop MDT"
22822
22823         # remount the MDT
22824         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22825                 error "Fail to start MDT"
22826
22827         #after mount new plainllog is used
22828         touch $DIR/$tdir/{11..19}
22829         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22830         stack_trap "rm -f $tmpfile"
22831         cat_sl=$(do_facet $SINGLEMDS "sync; \
22832                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22833                  llog_reader $tmpfile | grep -c type=1064553b")
22834         do_facet $SINGLEMDS llog_reader $tmpfile
22835
22836         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22837
22838         changelog_clear 0 || error "changelog_clear failed"
22839
22840         cat_sl=$(do_facet $SINGLEMDS "sync; \
22841                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22842                  llog_reader $tmpfile | grep -c type=1064553b")
22843
22844         if (( cat_sl == 2 )); then
22845                 error "Empty plain llog was not deleted from changelog catalog"
22846         elif (( cat_sl != 1 )); then
22847                 error "Active plain llog shouldn't be deleted from catalog"
22848         fi
22849 }
22850 run_test 256 "Check llog delete for empty and not full state"
22851
22852 test_257() {
22853         remote_mds_nodsh && skip "remote MDS with nodsh"
22854         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22855                 skip "Need MDS version at least 2.8.55"
22856
22857         test_mkdir $DIR/$tdir
22858
22859         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22860                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22861         stat $DIR/$tdir
22862
22863 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22864         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22865         local facet=mds$((mdtidx + 1))
22866         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22867         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22868
22869         stop $facet || error "stop MDS failed"
22870         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22871                 error "start MDS fail"
22872         wait_recovery_complete $facet
22873 }
22874 run_test 257 "xattr locks are not lost"
22875
22876 # Verify we take the i_mutex when security requires it
22877 test_258a() {
22878 #define OBD_FAIL_IMUTEX_SEC 0x141c
22879         $LCTL set_param fail_loc=0x141c
22880         touch $DIR/$tfile
22881         chmod u+s $DIR/$tfile
22882         chmod a+rwx $DIR/$tfile
22883         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22884         RC=$?
22885         if [ $RC -ne 0 ]; then
22886                 error "error, failed to take i_mutex, rc=$?"
22887         fi
22888         rm -f $DIR/$tfile
22889 }
22890 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22891
22892 # Verify we do NOT take the i_mutex in the normal case
22893 test_258b() {
22894 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22895         $LCTL set_param fail_loc=0x141d
22896         touch $DIR/$tfile
22897         chmod a+rwx $DIR
22898         chmod a+rw $DIR/$tfile
22899         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22900         RC=$?
22901         if [ $RC -ne 0 ]; then
22902                 error "error, took i_mutex unnecessarily, rc=$?"
22903         fi
22904         rm -f $DIR/$tfile
22905
22906 }
22907 run_test 258b "verify i_mutex security behavior"
22908
22909 test_259() {
22910         local file=$DIR/$tfile
22911         local before
22912         local after
22913
22914         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22915
22916         stack_trap "rm -f $file" EXIT
22917
22918         wait_delete_completed
22919         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22920         echo "before: $before"
22921
22922         $LFS setstripe -i 0 -c 1 $file
22923         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22924         sync_all_data
22925         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22926         echo "after write: $after"
22927
22928 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22929         do_facet ost1 $LCTL set_param fail_loc=0x2301
22930         $TRUNCATE $file 0
22931         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22932         echo "after truncate: $after"
22933
22934         stop ost1
22935         do_facet ost1 $LCTL set_param fail_loc=0
22936         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22937         sleep 2
22938         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22939         echo "after restart: $after"
22940         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22941                 error "missing truncate?"
22942
22943         return 0
22944 }
22945 run_test 259 "crash at delayed truncate"
22946
22947 test_260() {
22948 #define OBD_FAIL_MDC_CLOSE               0x806
22949         $LCTL set_param fail_loc=0x80000806
22950         touch $DIR/$tfile
22951
22952 }
22953 run_test 260 "Check mdc_close fail"
22954
22955 ### Data-on-MDT sanity tests ###
22956 test_270a() {
22957         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22958                 skip "Need MDS version at least 2.10.55 for DoM"
22959
22960         # create DoM file
22961         local dom=$DIR/$tdir/dom_file
22962         local tmp=$DIR/$tdir/tmp_file
22963
22964         mkdir_on_mdt0 $DIR/$tdir
22965
22966         # basic checks for DoM component creation
22967         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22968                 error "Can set MDT layout to non-first entry"
22969
22970         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22971                 error "Can define multiple entries as MDT layout"
22972
22973         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22974
22975         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22976         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22977         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22978
22979         local mdtidx=$($LFS getstripe -m $dom)
22980         local mdtname=MDT$(printf %04x $mdtidx)
22981         local facet=mds$((mdtidx + 1))
22982         local space_check=1
22983
22984         # Skip free space checks with ZFS
22985         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22986
22987         # write
22988         sync
22989         local size_tmp=$((65536 * 3))
22990         local mdtfree1=$(do_facet $facet \
22991                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22992
22993         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22994         # check also direct IO along write
22995         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22996         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22997         sync
22998         cmp $tmp $dom || error "file data is different"
22999         [ $(stat -c%s $dom) == $size_tmp ] ||
23000                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23001         if [ $space_check == 1 ]; then
23002                 local mdtfree2=$(do_facet $facet \
23003                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23004
23005                 # increase in usage from by $size_tmp
23006                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23007                         error "MDT free space wrong after write: " \
23008                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23009         fi
23010
23011         # truncate
23012         local size_dom=10000
23013
23014         $TRUNCATE $dom $size_dom
23015         [ $(stat -c%s $dom) == $size_dom ] ||
23016                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23017         if [ $space_check == 1 ]; then
23018                 mdtfree1=$(do_facet $facet \
23019                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23020                 # decrease in usage from $size_tmp to new $size_dom
23021                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23022                   $(((size_tmp - size_dom) / 1024)) ] ||
23023                         error "MDT free space is wrong after truncate: " \
23024                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23025         fi
23026
23027         # append
23028         cat $tmp >> $dom
23029         sync
23030         size_dom=$((size_dom + size_tmp))
23031         [ $(stat -c%s $dom) == $size_dom ] ||
23032                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23033         if [ $space_check == 1 ]; then
23034                 mdtfree2=$(do_facet $facet \
23035                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23036                 # increase in usage by $size_tmp from previous
23037                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23038                         error "MDT free space is wrong after append: " \
23039                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23040         fi
23041
23042         # delete
23043         rm $dom
23044         if [ $space_check == 1 ]; then
23045                 mdtfree1=$(do_facet $facet \
23046                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23047                 # decrease in usage by $size_dom from previous
23048                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23049                         error "MDT free space is wrong after removal: " \
23050                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23051         fi
23052
23053         # combined striping
23054         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23055                 error "Can't create DoM + OST striping"
23056
23057         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23058         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23059         # check also direct IO along write
23060         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23061         sync
23062         cmp $tmp $dom || error "file data is different"
23063         [ $(stat -c%s $dom) == $size_tmp ] ||
23064                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23065         rm $dom $tmp
23066
23067         return 0
23068 }
23069 run_test 270a "DoM: basic functionality tests"
23070
23071 test_270b() {
23072         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23073                 skip "Need MDS version at least 2.10.55"
23074
23075         local dom=$DIR/$tdir/dom_file
23076         local max_size=1048576
23077
23078         mkdir -p $DIR/$tdir
23079         $LFS setstripe -E $max_size -L mdt $dom
23080
23081         # truncate over the limit
23082         $TRUNCATE $dom $(($max_size + 1)) &&
23083                 error "successful truncate over the maximum size"
23084         # write over the limit
23085         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23086                 error "successful write over the maximum size"
23087         # append over the limit
23088         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23089         echo "12345" >> $dom && error "successful append over the maximum size"
23090         rm $dom
23091
23092         return 0
23093 }
23094 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23095
23096 test_270c() {
23097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23098                 skip "Need MDS version at least 2.10.55"
23099
23100         mkdir -p $DIR/$tdir
23101         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23102
23103         # check files inherit DoM EA
23104         touch $DIR/$tdir/first
23105         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23106                 error "bad pattern"
23107         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23108                 error "bad stripe count"
23109         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23110                 error "bad stripe size"
23111
23112         # check directory inherits DoM EA and uses it as default
23113         mkdir $DIR/$tdir/subdir
23114         touch $DIR/$tdir/subdir/second
23115         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23116                 error "bad pattern in sub-directory"
23117         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23118                 error "bad stripe count in sub-directory"
23119         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23120                 error "bad stripe size in sub-directory"
23121         return 0
23122 }
23123 run_test 270c "DoM: DoM EA inheritance tests"
23124
23125 test_270d() {
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         # inherit default DoM striping
23133         mkdir $DIR/$tdir/subdir
23134         touch $DIR/$tdir/subdir/f1
23135
23136         # change default directory striping
23137         $LFS setstripe -c 1 $DIR/$tdir/subdir
23138         touch $DIR/$tdir/subdir/f2
23139         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23140                 error "wrong default striping in file 2"
23141         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23142                 error "bad pattern in file 2"
23143         return 0
23144 }
23145 run_test 270d "DoM: change striping from DoM to RAID0"
23146
23147 test_270e() {
23148         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23149                 skip "Need MDS version at least 2.10.55"
23150
23151         mkdir -p $DIR/$tdir/dom
23152         mkdir -p $DIR/$tdir/norm
23153         DOMFILES=20
23154         NORMFILES=10
23155         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23156         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23157
23158         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23159         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23160
23161         # find DoM files by layout
23162         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23163         [ $NUM -eq  $DOMFILES ] ||
23164                 error "lfs find -L: found $NUM, expected $DOMFILES"
23165         echo "Test 1: lfs find 20 DOM files by layout: OK"
23166
23167         # there should be 1 dir with default DOM striping
23168         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23169         [ $NUM -eq  1 ] ||
23170                 error "lfs find -L: found $NUM, expected 1 dir"
23171         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23172
23173         # find DoM files by stripe size
23174         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23175         [ $NUM -eq  $DOMFILES ] ||
23176                 error "lfs find -S: found $NUM, expected $DOMFILES"
23177         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23178
23179         # find files by stripe offset except DoM files
23180         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23181         [ $NUM -eq  $NORMFILES ] ||
23182                 error "lfs find -i: found $NUM, expected $NORMFILES"
23183         echo "Test 5: lfs find no DOM files by stripe index: OK"
23184         return 0
23185 }
23186 run_test 270e "DoM: lfs find with DoM files test"
23187
23188 test_270f() {
23189         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23190                 skip "Need MDS version at least 2.10.55"
23191
23192         local mdtname=${FSNAME}-MDT0000-mdtlov
23193         local dom=$DIR/$tdir/dom_file
23194         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23195                                                 lod.$mdtname.dom_stripesize)
23196         local dom_limit=131072
23197
23198         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23199         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23200                                                 lod.$mdtname.dom_stripesize)
23201         [ ${dom_limit} -eq ${dom_current} ] ||
23202                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23203
23204         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23205         $LFS setstripe -d $DIR/$tdir
23206         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23207                 error "Can't set directory default striping"
23208
23209         # exceed maximum stripe size
23210         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23211                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23212         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23213                 error "Able to create DoM component size more than LOD limit"
23214
23215         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23216         dom_current=$(do_facet mds1 $LCTL get_param -n \
23217                                                 lod.$mdtname.dom_stripesize)
23218         [ 0 -eq ${dom_current} ] ||
23219                 error "Can't set zero DoM stripe limit"
23220         rm $dom
23221
23222         # attempt to create DoM file on server with disabled DoM should
23223         # remove DoM entry from layout and be succeed
23224         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23225                 error "Can't create DoM file (DoM is disabled)"
23226         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23227                 error "File has DoM component while DoM is disabled"
23228         rm $dom
23229
23230         # attempt to create DoM file with only DoM stripe should return error
23231         $LFS setstripe -E $dom_limit -L mdt $dom &&
23232                 error "Able to create DoM-only file while DoM is disabled"
23233
23234         # too low values to be aligned with smallest stripe size 64K
23235         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23236         dom_current=$(do_facet mds1 $LCTL get_param -n \
23237                                                 lod.$mdtname.dom_stripesize)
23238         [ 30000 -eq ${dom_current} ] &&
23239                 error "Can set too small DoM stripe limit"
23240
23241         # 64K is a minimal stripe size in Lustre, expect limit of that size
23242         [ 65536 -eq ${dom_current} ] ||
23243                 error "Limit is not set to 64K but ${dom_current}"
23244
23245         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23246         dom_current=$(do_facet mds1 $LCTL get_param -n \
23247                                                 lod.$mdtname.dom_stripesize)
23248         echo $dom_current
23249         [ 2147483648 -eq ${dom_current} ] &&
23250                 error "Can set too large DoM stripe limit"
23251
23252         do_facet mds1 $LCTL set_param -n \
23253                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23254         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23255                 error "Can't create DoM component size after limit change"
23256         do_facet mds1 $LCTL set_param -n \
23257                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23258         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23259                 error "Can't create DoM file after limit decrease"
23260         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23261                 error "Can create big DoM component after limit decrease"
23262         touch ${dom}_def ||
23263                 error "Can't create file with old default layout"
23264
23265         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23266         return 0
23267 }
23268 run_test 270f "DoM: maximum DoM stripe size checks"
23269
23270 test_270g() {
23271         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23272                 skip "Need MDS version at least 2.13.52"
23273         local dom=$DIR/$tdir/$tfile
23274
23275         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23276         local lodname=${FSNAME}-MDT0000-mdtlov
23277
23278         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23279         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23280         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23281         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23282
23283         local dom_limit=1024
23284         local dom_threshold="50%"
23285
23286         $LFS setstripe -d $DIR/$tdir
23287         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23288                 error "Can't set directory default striping"
23289
23290         do_facet mds1 $LCTL set_param -n \
23291                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23292         # set 0 threshold and create DOM file to change tunable stripesize
23293         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23294         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23295                 error "Failed to create $dom file"
23296         # now tunable dom_cur_stripesize should reach maximum
23297         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23298                                         lod.${lodname}.dom_stripesize_cur_kb)
23299         [[ $dom_current == $dom_limit ]] ||
23300                 error "Current DOM stripesize is not maximum"
23301         rm $dom
23302
23303         # set threshold for further tests
23304         do_facet mds1 $LCTL set_param -n \
23305                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23306         echo "DOM threshold is $dom_threshold free space"
23307         local dom_def
23308         local dom_set
23309         # Spoof bfree to exceed threshold
23310         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23311         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23312         for spfree in 40 20 0 15 30 55; do
23313                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23314                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23315                         error "Failed to create $dom file"
23316                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23317                                         lod.${lodname}.dom_stripesize_cur_kb)
23318                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23319                 [[ $dom_def != $dom_current ]] ||
23320                         error "Default stripe size was not changed"
23321                 if (( spfree > 0 )) ; then
23322                         dom_set=$($LFS getstripe -S $dom)
23323                         (( dom_set == dom_def * 1024 )) ||
23324                                 error "DOM component size is still old"
23325                 else
23326                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23327                                 error "DoM component is set with no free space"
23328                 fi
23329                 rm $dom
23330                 dom_current=$dom_def
23331         done
23332 }
23333 run_test 270g "DoM: default DoM stripe size depends on free space"
23334
23335 test_270h() {
23336         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23337                 skip "Need MDS version at least 2.13.53"
23338
23339         local mdtname=${FSNAME}-MDT0000-mdtlov
23340         local dom=$DIR/$tdir/$tfile
23341         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23342
23343         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23344         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23345
23346         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23347         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23348                 error "can't create OST file"
23349         # mirrored file with DOM entry in the second mirror
23350         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23351                 error "can't create mirror with DoM component"
23352
23353         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23354
23355         # DOM component in the middle and has other enries in the same mirror,
23356         # should succeed but lost DoM component
23357         $LFS setstripe --copy=${dom}_1 $dom ||
23358                 error "Can't create file from OST|DOM mirror layout"
23359         # check new file has no DoM layout after all
23360         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23361                 error "File has DoM component while DoM is disabled"
23362 }
23363 run_test 270h "DoM: DoM stripe removal when disabled on server"
23364
23365 test_270i() {
23366         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23367                 skip "Need MDS version at least 2.14.54"
23368
23369         mkdir $DIR/$tdir
23370         # DoM with plain layout
23371         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23372                 error "default plain layout with DoM must fail"
23373         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23374                 error "setstripe plain file layout with DoM must fail"
23375         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23376                 error "default DoM layout with bad striping must fail"
23377         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23378                 error "setstripe to DoM layout with bad striping must fail"
23379         return 0
23380 }
23381 run_test 270i "DoM: setting invalid DoM striping should fail"
23382
23383 test_271a() {
23384         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23385                 skip "Need MDS version at least 2.10.55"
23386
23387         local dom=$DIR/$tdir/dom
23388
23389         mkdir -p $DIR/$tdir
23390
23391         $LFS setstripe -E 1024K -L mdt $dom
23392
23393         lctl set_param -n mdc.*.stats=clear
23394         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23395         cat $dom > /dev/null
23396         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23397         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23398         ls $dom
23399         rm -f $dom
23400 }
23401 run_test 271a "DoM: data is cached for read after write"
23402
23403 test_271b() {
23404         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23405                 skip "Need MDS version at least 2.10.55"
23406
23407         local dom=$DIR/$tdir/dom
23408
23409         mkdir -p $DIR/$tdir
23410
23411         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23412
23413         lctl set_param -n mdc.*.stats=clear
23414         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23415         cancel_lru_locks mdc
23416         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23417         # second stat to check size is cached on client
23418         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23419         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23420         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23421         rm -f $dom
23422 }
23423 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23424
23425 test_271ba() {
23426         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23427                 skip "Need MDS version at least 2.10.55"
23428
23429         local dom=$DIR/$tdir/dom
23430
23431         mkdir -p $DIR/$tdir
23432
23433         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23434
23435         lctl set_param -n mdc.*.stats=clear
23436         lctl set_param -n osc.*.stats=clear
23437         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23438         cancel_lru_locks mdc
23439         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23440         # second stat to check size is cached on client
23441         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23442         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23443         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23444         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23445         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23446         rm -f $dom
23447 }
23448 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23449
23450
23451 get_mdc_stats() {
23452         local mdtidx=$1
23453         local param=$2
23454         local mdt=MDT$(printf %04x $mdtidx)
23455
23456         if [ -z $param ]; then
23457                 lctl get_param -n mdc.*$mdt*.stats
23458         else
23459                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23460         fi
23461 }
23462
23463 test_271c() {
23464         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23465                 skip "Need MDS version at least 2.10.55"
23466
23467         local dom=$DIR/$tdir/dom
23468
23469         mkdir -p $DIR/$tdir
23470
23471         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23472
23473         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23474         local facet=mds$((mdtidx + 1))
23475
23476         cancel_lru_locks mdc
23477         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23478         createmany -o $dom 1000
23479         lctl set_param -n mdc.*.stats=clear
23480         smalliomany -w $dom 1000 200
23481         get_mdc_stats $mdtidx
23482         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23483         # Each file has 1 open, 1 IO enqueues, total 2000
23484         # but now we have also +1 getxattr for security.capability, total 3000
23485         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23486         unlinkmany $dom 1000
23487
23488         cancel_lru_locks mdc
23489         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23490         createmany -o $dom 1000
23491         lctl set_param -n mdc.*.stats=clear
23492         smalliomany -w $dom 1000 200
23493         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23494         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23495         # for OPEN and IO lock.
23496         [ $((enq - enq_2)) -ge 1000 ] ||
23497                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23498         unlinkmany $dom 1000
23499         return 0
23500 }
23501 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23502
23503 cleanup_271def_tests() {
23504         trap 0
23505         rm -f $1
23506 }
23507
23508 test_271d() {
23509         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23510                 skip "Need MDS version at least 2.10.57"
23511
23512         local dom=$DIR/$tdir/dom
23513         local tmp=$TMP/$tfile
23514         trap "cleanup_271def_tests $tmp" EXIT
23515
23516         mkdir -p $DIR/$tdir
23517
23518         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23519
23520         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23521
23522         cancel_lru_locks mdc
23523         dd if=/dev/urandom of=$tmp bs=1000 count=1
23524         dd if=$tmp of=$dom bs=1000 count=1
23525         cancel_lru_locks mdc
23526
23527         cat /etc/hosts >> $tmp
23528         lctl set_param -n mdc.*.stats=clear
23529
23530         # append data to the same file it should update local page
23531         echo "Append to the same page"
23532         cat /etc/hosts >> $dom
23533         local num=$(get_mdc_stats $mdtidx ost_read)
23534         local ra=$(get_mdc_stats $mdtidx req_active)
23535         local rw=$(get_mdc_stats $mdtidx req_waittime)
23536
23537         [ -z $num ] || error "$num READ RPC occured"
23538         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23539         echo "... DONE"
23540
23541         # compare content
23542         cmp $tmp $dom || error "file miscompare"
23543
23544         cancel_lru_locks mdc
23545         lctl set_param -n mdc.*.stats=clear
23546
23547         echo "Open and read file"
23548         cat $dom > /dev/null
23549         local num=$(get_mdc_stats $mdtidx ost_read)
23550         local ra=$(get_mdc_stats $mdtidx req_active)
23551         local rw=$(get_mdc_stats $mdtidx req_waittime)
23552
23553         [ -z $num ] || error "$num READ RPC occured"
23554         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23555         echo "... DONE"
23556
23557         # compare content
23558         cmp $tmp $dom || error "file miscompare"
23559
23560         return 0
23561 }
23562 run_test 271d "DoM: read on open (1K file in reply buffer)"
23563
23564 test_271f() {
23565         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23566                 skip "Need MDS version at least 2.10.57"
23567
23568         local dom=$DIR/$tdir/dom
23569         local tmp=$TMP/$tfile
23570         trap "cleanup_271def_tests $tmp" EXIT
23571
23572         mkdir -p $DIR/$tdir
23573
23574         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23575
23576         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23577
23578         cancel_lru_locks mdc
23579         dd if=/dev/urandom of=$tmp bs=265000 count=1
23580         dd if=$tmp of=$dom bs=265000 count=1
23581         cancel_lru_locks mdc
23582         cat /etc/hosts >> $tmp
23583         lctl set_param -n mdc.*.stats=clear
23584
23585         echo "Append to the same page"
23586         cat /etc/hosts >> $dom
23587         local num=$(get_mdc_stats $mdtidx ost_read)
23588         local ra=$(get_mdc_stats $mdtidx req_active)
23589         local rw=$(get_mdc_stats $mdtidx req_waittime)
23590
23591         [ -z $num ] || error "$num READ RPC occured"
23592         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23593         echo "... DONE"
23594
23595         # compare content
23596         cmp $tmp $dom || error "file miscompare"
23597
23598         cancel_lru_locks mdc
23599         lctl set_param -n mdc.*.stats=clear
23600
23601         echo "Open and read file"
23602         cat $dom > /dev/null
23603         local num=$(get_mdc_stats $mdtidx ost_read)
23604         local ra=$(get_mdc_stats $mdtidx req_active)
23605         local rw=$(get_mdc_stats $mdtidx req_waittime)
23606
23607         [ -z $num ] && num=0
23608         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23609         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23610         echo "... DONE"
23611
23612         # compare content
23613         cmp $tmp $dom || error "file miscompare"
23614
23615         return 0
23616 }
23617 run_test 271f "DoM: read on open (200K file and read tail)"
23618
23619 test_271g() {
23620         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23621                 skip "Skipping due to old client or server version"
23622
23623         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23624         # to get layout
23625         $CHECKSTAT -t file $DIR1/$tfile
23626
23627         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23628         MULTIOP_PID=$!
23629         sleep 1
23630         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23631         $LCTL set_param fail_loc=0x80000314
23632         rm $DIR1/$tfile || error "Unlink fails"
23633         RC=$?
23634         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23635         [ $RC -eq 0 ] || error "Failed write to stale object"
23636 }
23637 run_test 271g "Discard DoM data vs client flush race"
23638
23639 test_272a() {
23640         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23641                 skip "Need MDS version at least 2.11.50"
23642
23643         local dom=$DIR/$tdir/dom
23644         mkdir -p $DIR/$tdir
23645
23646         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23647         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23648                 error "failed to write data into $dom"
23649         local old_md5=$(md5sum $dom)
23650
23651         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23652                 error "failed to migrate to the same DoM component"
23653
23654         local new_md5=$(md5sum $dom)
23655
23656         [ "$old_md5" == "$new_md5" ] ||
23657                 error "md5sum differ: $old_md5, $new_md5"
23658
23659         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23660                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23661 }
23662 run_test 272a "DoM migration: new layout with the same DOM component"
23663
23664 test_272b() {
23665         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23666                 skip "Need MDS version at least 2.11.50"
23667
23668         local dom=$DIR/$tdir/dom
23669         mkdir -p $DIR/$tdir
23670         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23671
23672         local mdtidx=$($LFS getstripe -m $dom)
23673         local mdtname=MDT$(printf %04x $mdtidx)
23674         local facet=mds$((mdtidx + 1))
23675
23676         local mdtfree1=$(do_facet $facet \
23677                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23678         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23679                 error "failed to write data into $dom"
23680         local old_md5=$(md5sum $dom)
23681         cancel_lru_locks mdc
23682         local mdtfree1=$(do_facet $facet \
23683                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23684
23685         $LFS migrate -c2 $dom ||
23686                 error "failed to migrate to the new composite layout"
23687         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23688                 error "MDT stripe was not removed"
23689
23690         cancel_lru_locks mdc
23691         local new_md5=$(md5sum $dom)
23692         [ "$old_md5" == "$new_md5" ] ||
23693                 error "$old_md5 != $new_md5"
23694
23695         # Skip free space checks with ZFS
23696         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23697                 local mdtfree2=$(do_facet $facet \
23698                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23699                 [ $mdtfree2 -gt $mdtfree1 ] ||
23700                         error "MDT space is not freed after migration"
23701         fi
23702         return 0
23703 }
23704 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23705
23706 test_272c() {
23707         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23708                 skip "Need MDS version at least 2.11.50"
23709
23710         local dom=$DIR/$tdir/$tfile
23711         mkdir -p $DIR/$tdir
23712         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23713
23714         local mdtidx=$($LFS getstripe -m $dom)
23715         local mdtname=MDT$(printf %04x $mdtidx)
23716         local facet=mds$((mdtidx + 1))
23717
23718         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23719                 error "failed to write data into $dom"
23720         local old_md5=$(md5sum $dom)
23721         cancel_lru_locks mdc
23722         local mdtfree1=$(do_facet $facet \
23723                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23724
23725         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23726                 error "failed to migrate to the new composite layout"
23727         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23728                 error "MDT stripe was not removed"
23729
23730         cancel_lru_locks mdc
23731         local new_md5=$(md5sum $dom)
23732         [ "$old_md5" == "$new_md5" ] ||
23733                 error "$old_md5 != $new_md5"
23734
23735         # Skip free space checks with ZFS
23736         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23737                 local mdtfree2=$(do_facet $facet \
23738                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23739                 [ $mdtfree2 -gt $mdtfree1 ] ||
23740                         error "MDS space is not freed after migration"
23741         fi
23742         return 0
23743 }
23744 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23745
23746 test_272d() {
23747         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23748                 skip "Need MDS version at least 2.12.55"
23749
23750         local dom=$DIR/$tdir/$tfile
23751         mkdir -p $DIR/$tdir
23752         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23753
23754         local mdtidx=$($LFS getstripe -m $dom)
23755         local mdtname=MDT$(printf %04x $mdtidx)
23756         local facet=mds$((mdtidx + 1))
23757
23758         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23759                 error "failed to write data into $dom"
23760         local old_md5=$(md5sum $dom)
23761         cancel_lru_locks mdc
23762         local mdtfree1=$(do_facet $facet \
23763                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23764
23765         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23766                 error "failed mirroring to the new composite layout"
23767         $LFS mirror resync $dom ||
23768                 error "failed mirror resync"
23769         $LFS mirror split --mirror-id 1 -d $dom ||
23770                 error "failed mirror split"
23771
23772         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23773                 error "MDT stripe was not removed"
23774
23775         cancel_lru_locks mdc
23776         local new_md5=$(md5sum $dom)
23777         [ "$old_md5" == "$new_md5" ] ||
23778                 error "$old_md5 != $new_md5"
23779
23780         # Skip free space checks with ZFS
23781         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23782                 local mdtfree2=$(do_facet $facet \
23783                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23784                 [ $mdtfree2 -gt $mdtfree1 ] ||
23785                         error "MDS space is not freed after DOM mirror deletion"
23786         fi
23787         return 0
23788 }
23789 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23790
23791 test_272e() {
23792         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23793                 skip "Need MDS version at least 2.12.55"
23794
23795         local dom=$DIR/$tdir/$tfile
23796         mkdir -p $DIR/$tdir
23797         $LFS setstripe -c 2 $dom
23798
23799         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23800                 error "failed to write data into $dom"
23801         local old_md5=$(md5sum $dom)
23802         cancel_lru_locks
23803
23804         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23805                 error "failed mirroring to the DOM layout"
23806         $LFS mirror resync $dom ||
23807                 error "failed mirror resync"
23808         $LFS mirror split --mirror-id 1 -d $dom ||
23809                 error "failed mirror split"
23810
23811         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23812                 error "MDT stripe wasn't set"
23813
23814         cancel_lru_locks
23815         local new_md5=$(md5sum $dom)
23816         [ "$old_md5" == "$new_md5" ] ||
23817                 error "$old_md5 != $new_md5"
23818
23819         return 0
23820 }
23821 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23822
23823 test_272f() {
23824         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23825                 skip "Need MDS version at least 2.12.55"
23826
23827         local dom=$DIR/$tdir/$tfile
23828         mkdir -p $DIR/$tdir
23829         $LFS setstripe -c 2 $dom
23830
23831         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23832                 error "failed to write data into $dom"
23833         local old_md5=$(md5sum $dom)
23834         cancel_lru_locks
23835
23836         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23837                 error "failed migrating to the DOM file"
23838
23839         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23840                 error "MDT stripe wasn't set"
23841
23842         cancel_lru_locks
23843         local new_md5=$(md5sum $dom)
23844         [ "$old_md5" != "$new_md5" ] &&
23845                 error "$old_md5 != $new_md5"
23846
23847         return 0
23848 }
23849 run_test 272f "DoM migration: OST-striped file to DOM file"
23850
23851 test_273a() {
23852         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23853                 skip "Need MDS version at least 2.11.50"
23854
23855         # Layout swap cannot be done if either file has DOM component,
23856         # this will never be supported, migration should be used instead
23857
23858         local dom=$DIR/$tdir/$tfile
23859         mkdir -p $DIR/$tdir
23860
23861         $LFS setstripe -c2 ${dom}_plain
23862         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23863         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23864                 error "can swap layout with DoM component"
23865         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23866                 error "can swap layout with DoM component"
23867
23868         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23869         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23870                 error "can swap layout with DoM component"
23871         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23872                 error "can swap layout with DoM component"
23873         return 0
23874 }
23875 run_test 273a "DoM: layout swapping should fail with DOM"
23876
23877 test_273b() {
23878         mkdir -p $DIR/$tdir
23879         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23880
23881 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23882         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23883
23884         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23885 }
23886 run_test 273b "DoM: race writeback and object destroy"
23887
23888 test_275() {
23889         remote_ost_nodsh && skip "remote OST with nodsh"
23890         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23891                 skip "Need OST version >= 2.10.57"
23892
23893         local file=$DIR/$tfile
23894         local oss
23895
23896         oss=$(comma_list $(osts_nodes))
23897
23898         dd if=/dev/urandom of=$file bs=1M count=2 ||
23899                 error "failed to create a file"
23900         cancel_lru_locks osc
23901
23902         #lock 1
23903         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23904                 error "failed to read a file"
23905
23906 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23907         $LCTL set_param fail_loc=0x8000031f
23908
23909         cancel_lru_locks osc &
23910         sleep 1
23911
23912 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23913         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23914         #IO takes another lock, but matches the PENDING one
23915         #and places it to the IO RPC
23916         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23917                 error "failed to read a file with PENDING lock"
23918 }
23919 run_test 275 "Read on a canceled duplicate lock"
23920
23921 test_276() {
23922         remote_ost_nodsh && skip "remote OST with nodsh"
23923         local pid
23924
23925         do_facet ost1 "(while true; do \
23926                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23927                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23928         pid=$!
23929
23930         for LOOP in $(seq 20); do
23931                 stop ost1
23932                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23933         done
23934         kill -9 $pid
23935         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23936                 rm $TMP/sanity_276_pid"
23937 }
23938 run_test 276 "Race between mount and obd_statfs"
23939
23940 test_277() {
23941         $LCTL set_param ldlm.namespaces.*.lru_size=0
23942         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23943         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23944                         grep ^used_mb | awk '{print $2}')
23945         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23946         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23947                 oflag=direct conv=notrunc
23948         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23949                         grep ^used_mb | awk '{print $2}')
23950         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23951 }
23952 run_test 277 "Direct IO shall drop page cache"
23953
23954 test_278() {
23955         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23956         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23957         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23958                 skip "needs the same host for mdt1 mdt2" && return
23959
23960         local pid1
23961         local pid2
23962
23963 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23964         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23965         stop mds2 &
23966         pid2=$!
23967
23968         stop mds1
23969
23970         echo "Starting MDTs"
23971         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23972         wait $pid2
23973 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23974 #will return NULL
23975         do_facet mds2 $LCTL set_param fail_loc=0
23976
23977         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23978         wait_recovery_complete mds2
23979 }
23980 run_test 278 "Race starting MDS between MDTs stop/start"
23981
23982 test_280() {
23983         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23984                 skip "Need MGS version at least 2.13.52"
23985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23986         combined_mgs_mds || skip "needs combined MGS/MDT"
23987
23988         umount_client $MOUNT
23989 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23990         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23991
23992         mount_client $MOUNT &
23993         sleep 1
23994         stop mgs || error "stop mgs failed"
23995         #for a race mgs would crash
23996         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23997         # make sure we unmount client before remounting
23998         wait
23999         umount_client $MOUNT
24000         mount_client $MOUNT || error "mount client failed"
24001 }
24002 run_test 280 "Race between MGS umount and client llog processing"
24003
24004 cleanup_test_300() {
24005         trap 0
24006         umask $SAVE_UMASK
24007 }
24008 test_striped_dir() {
24009         local mdt_index=$1
24010         local stripe_count
24011         local stripe_index
24012
24013         mkdir -p $DIR/$tdir
24014
24015         SAVE_UMASK=$(umask)
24016         trap cleanup_test_300 RETURN EXIT
24017
24018         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24019                                                 $DIR/$tdir/striped_dir ||
24020                 error "set striped dir error"
24021
24022         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24023         [ "$mode" = "755" ] || error "expect 755 got $mode"
24024
24025         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24026                 error "getdirstripe failed"
24027         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24028         if [ "$stripe_count" != "2" ]; then
24029                 error "1:stripe_count is $stripe_count, expect 2"
24030         fi
24031         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24032         if [ "$stripe_count" != "2" ]; then
24033                 error "2:stripe_count is $stripe_count, expect 2"
24034         fi
24035
24036         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24037         if [ "$stripe_index" != "$mdt_index" ]; then
24038                 error "stripe_index is $stripe_index, expect $mdt_index"
24039         fi
24040
24041         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24042                 error "nlink error after create striped dir"
24043
24044         mkdir $DIR/$tdir/striped_dir/a
24045         mkdir $DIR/$tdir/striped_dir/b
24046
24047         stat $DIR/$tdir/striped_dir/a ||
24048                 error "create dir under striped dir failed"
24049         stat $DIR/$tdir/striped_dir/b ||
24050                 error "create dir under striped dir failed"
24051
24052         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24053                 error "nlink error after mkdir"
24054
24055         rmdir $DIR/$tdir/striped_dir/a
24056         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24057                 error "nlink error after rmdir"
24058
24059         rmdir $DIR/$tdir/striped_dir/b
24060         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24061                 error "nlink error after rmdir"
24062
24063         chattr +i $DIR/$tdir/striped_dir
24064         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24065                 error "immutable flags not working under striped dir!"
24066         chattr -i $DIR/$tdir/striped_dir
24067
24068         rmdir $DIR/$tdir/striped_dir ||
24069                 error "rmdir striped dir error"
24070
24071         cleanup_test_300
24072
24073         true
24074 }
24075
24076 test_300a() {
24077         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24078                 skip "skipped for lustre < 2.7.0"
24079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24080         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24081
24082         test_striped_dir 0 || error "failed on striped dir on MDT0"
24083         test_striped_dir 1 || error "failed on striped dir on MDT0"
24084 }
24085 run_test 300a "basic striped dir sanity test"
24086
24087 test_300b() {
24088         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24089                 skip "skipped for lustre < 2.7.0"
24090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24092
24093         local i
24094         local mtime1
24095         local mtime2
24096         local mtime3
24097
24098         test_mkdir $DIR/$tdir || error "mkdir fail"
24099         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24100                 error "set striped dir error"
24101         for i in {0..9}; do
24102                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24103                 sleep 1
24104                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24105                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24106                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24107                 sleep 1
24108                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24109                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24110                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24111         done
24112         true
24113 }
24114 run_test 300b "check ctime/mtime for striped dir"
24115
24116 test_300c() {
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         local file_count
24123
24124         mkdir_on_mdt0 $DIR/$tdir
24125         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24126                 error "set striped dir error"
24127
24128         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24129                 error "chown striped dir failed"
24130
24131         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24132                 error "create 5k files failed"
24133
24134         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24135
24136         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24137
24138         rm -rf $DIR/$tdir
24139 }
24140 run_test 300c "chown && check ls under striped directory"
24141
24142 test_300d() {
24143         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24144                 skip "skipped for lustre < 2.7.0"
24145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24147
24148         local stripe_count
24149         local file
24150
24151         mkdir -p $DIR/$tdir
24152         $LFS setstripe -c 2 $DIR/$tdir
24153
24154         #local striped directory
24155         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24156                 error "set striped dir error"
24157         #look at the directories for debug purposes
24158         ls -l $DIR/$tdir
24159         $LFS getdirstripe $DIR/$tdir
24160         ls -l $DIR/$tdir/striped_dir
24161         $LFS getdirstripe $DIR/$tdir/striped_dir
24162         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24163                 error "create 10 files failed"
24164
24165         #remote striped directory
24166         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24167                 error "set striped dir error"
24168         #look at the directories for debug purposes
24169         ls -l $DIR/$tdir
24170         $LFS getdirstripe $DIR/$tdir
24171         ls -l $DIR/$tdir/remote_striped_dir
24172         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24173         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24174                 error "create 10 files failed"
24175
24176         for file in $(find $DIR/$tdir); do
24177                 stripe_count=$($LFS getstripe -c $file)
24178                 [ $stripe_count -eq 2 ] ||
24179                         error "wrong stripe $stripe_count for $file"
24180         done
24181
24182         rm -rf $DIR/$tdir
24183 }
24184 run_test 300d "check default stripe under striped directory"
24185
24186 test_300e() {
24187         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24188                 skip "Need MDS version at least 2.7.55"
24189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24190         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24191
24192         local stripe_count
24193         local file
24194
24195         mkdir -p $DIR/$tdir
24196
24197         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24198                 error "set striped dir error"
24199
24200         touch $DIR/$tdir/striped_dir/a
24201         touch $DIR/$tdir/striped_dir/b
24202         touch $DIR/$tdir/striped_dir/c
24203
24204         mkdir $DIR/$tdir/striped_dir/dir_a
24205         mkdir $DIR/$tdir/striped_dir/dir_b
24206         mkdir $DIR/$tdir/striped_dir/dir_c
24207
24208         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24209                 error "set striped adir under striped dir error"
24210
24211         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24212                 error "set striped bdir under striped dir error"
24213
24214         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24215                 error "set striped cdir under striped dir error"
24216
24217         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24218                 error "rename dir under striped dir fails"
24219
24220         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24221                 error "rename dir under different stripes fails"
24222
24223         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24224                 error "rename file under striped dir should succeed"
24225
24226         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24227                 error "rename dir under striped dir should succeed"
24228
24229         rm -rf $DIR/$tdir
24230 }
24231 run_test 300e "check rename under striped directory"
24232
24233 test_300f() {
24234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24235         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24236         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24237                 skip "Need MDS version at least 2.7.55"
24238
24239         local stripe_count
24240         local file
24241
24242         rm -rf $DIR/$tdir
24243         mkdir -p $DIR/$tdir
24244
24245         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24246                 error "set striped dir error"
24247
24248         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24249                 error "set striped dir error"
24250
24251         touch $DIR/$tdir/striped_dir/a
24252         mkdir $DIR/$tdir/striped_dir/dir_a
24253         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24254                 error "create striped dir under striped dir fails"
24255
24256         touch $DIR/$tdir/striped_dir1/b
24257         mkdir $DIR/$tdir/striped_dir1/dir_b
24258         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24259                 error "create striped dir under striped dir fails"
24260
24261         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24262                 error "rename dir under different striped dir should fail"
24263
24264         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24265                 error "rename striped dir under diff striped dir should fail"
24266
24267         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24268                 error "rename file under diff striped dirs fails"
24269
24270         rm -rf $DIR/$tdir
24271 }
24272 run_test 300f "check rename cross striped directory"
24273
24274 test_300_check_default_striped_dir()
24275 {
24276         local dirname=$1
24277         local default_count=$2
24278         local default_index=$3
24279         local stripe_count
24280         local stripe_index
24281         local dir_stripe_index
24282         local dir
24283
24284         echo "checking $dirname $default_count $default_index"
24285         $LFS setdirstripe -D -c $default_count -i $default_index \
24286                                 -H all_char $DIR/$tdir/$dirname ||
24287                 error "set default stripe on striped dir error"
24288         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24289         [ $stripe_count -eq $default_count ] ||
24290                 error "expect $default_count get $stripe_count for $dirname"
24291
24292         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24293         [ $stripe_index -eq $default_index ] ||
24294                 error "expect $default_index get $stripe_index for $dirname"
24295
24296         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24297                                                 error "create dirs failed"
24298
24299         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24300         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24301         for dir in $(find $DIR/$tdir/$dirname/*); do
24302                 stripe_count=$($LFS getdirstripe -c $dir)
24303                 (( $stripe_count == $default_count )) ||
24304                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24305                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24306                 error "stripe count $default_count != $stripe_count for $dir"
24307
24308                 stripe_index=$($LFS getdirstripe -i $dir)
24309                 [ $default_index -eq -1 ] ||
24310                         [ $stripe_index -eq $default_index ] ||
24311                         error "$stripe_index != $default_index for $dir"
24312
24313                 #check default stripe
24314                 stripe_count=$($LFS getdirstripe -D -c $dir)
24315                 [ $stripe_count -eq $default_count ] ||
24316                 error "default count $default_count != $stripe_count for $dir"
24317
24318                 stripe_index=$($LFS getdirstripe -D -i $dir)
24319                 [ $stripe_index -eq $default_index ] ||
24320                 error "default index $default_index != $stripe_index for $dir"
24321         done
24322         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24323 }
24324
24325 test_300g() {
24326         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24327         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24328                 skip "Need MDS version at least 2.7.55"
24329
24330         local dir
24331         local stripe_count
24332         local stripe_index
24333
24334         mkdir_on_mdt0 $DIR/$tdir
24335         mkdir $DIR/$tdir/normal_dir
24336
24337         #Checking when client cache stripe index
24338         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24339         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24340                 error "create striped_dir failed"
24341
24342         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24343                 error "create dir0 fails"
24344         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24345         [ $stripe_index -eq 0 ] ||
24346                 error "dir0 expect index 0 got $stripe_index"
24347
24348         mkdir $DIR/$tdir/striped_dir/dir1 ||
24349                 error "create dir1 fails"
24350         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24351         [ $stripe_index -eq 1 ] ||
24352                 error "dir1 expect index 1 got $stripe_index"
24353
24354         #check default stripe count/stripe index
24355         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24356         test_300_check_default_striped_dir normal_dir 1 0
24357         test_300_check_default_striped_dir normal_dir -1 1
24358         test_300_check_default_striped_dir normal_dir 2 -1
24359
24360         #delete default stripe information
24361         echo "delete default stripeEA"
24362         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24363                 error "set default stripe on striped dir error"
24364
24365         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24366         for dir in $(find $DIR/$tdir/normal_dir/*); do
24367                 stripe_count=$($LFS getdirstripe -c $dir)
24368                 [ $stripe_count -eq 0 ] ||
24369                         error "expect 1 get $stripe_count for $dir"
24370         done
24371 }
24372 run_test 300g "check default striped directory for normal directory"
24373
24374 test_300h() {
24375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24376         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24377                 skip "Need MDS version at least 2.7.55"
24378
24379         local dir
24380         local stripe_count
24381
24382         mkdir $DIR/$tdir
24383         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24384                 error "set striped dir error"
24385
24386         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24387         test_300_check_default_striped_dir striped_dir 1 0
24388         test_300_check_default_striped_dir striped_dir -1 1
24389         test_300_check_default_striped_dir striped_dir 2 -1
24390
24391         #delete default stripe information
24392         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24393                 error "set default stripe on striped dir error"
24394
24395         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24396         for dir in $(find $DIR/$tdir/striped_dir/*); do
24397                 stripe_count=$($LFS getdirstripe -c $dir)
24398                 [ $stripe_count -eq 0 ] ||
24399                         error "expect 1 get $stripe_count for $dir"
24400         done
24401 }
24402 run_test 300h "check default striped directory for striped directory"
24403
24404 test_300i() {
24405         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24406         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24407         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24408                 skip "Need MDS version at least 2.7.55"
24409
24410         local stripe_count
24411         local file
24412
24413         mkdir $DIR/$tdir
24414
24415         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24416                 error "set striped dir error"
24417
24418         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24419                 error "create files under striped dir failed"
24420
24421         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24422                 error "set striped hashdir error"
24423
24424         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24425                 error "create dir0 under hash dir failed"
24426         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24427                 error "create dir1 under hash dir failed"
24428         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24429                 error "create dir2 under hash dir failed"
24430
24431         # unfortunately, we need to umount to clear dir layout cache for now
24432         # once we fully implement dir layout, we can drop this
24433         umount_client $MOUNT || error "umount failed"
24434         mount_client $MOUNT || error "mount failed"
24435
24436         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24437         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24438         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24439
24440         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24441                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24442                         error "create crush2 dir $tdir/hashdir/d3 failed"
24443                 $LFS find -H crush2 $DIR/$tdir/hashdir
24444                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24445                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24446
24447                 # mkdir with an invalid hash type (hash=fail_val) from client
24448                 # should be replaced on MDS with a valid (default) hash type
24449                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24450                 $LCTL set_param fail_loc=0x1901 fail_val=99
24451                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24452
24453                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24454                 local expect=$(do_facet mds1 \
24455                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24456                 [[ $hash == $expect ]] ||
24457                         error "d99 hash '$hash' != expected hash '$expect'"
24458         fi
24459
24460         #set the stripe to be unknown hash type on read
24461         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24462         $LCTL set_param fail_loc=0x1901 fail_val=99
24463         for ((i = 0; i < 10; i++)); do
24464                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24465                         error "stat f-$i failed"
24466                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24467         done
24468
24469         touch $DIR/$tdir/striped_dir/f0 &&
24470                 error "create under striped dir with unknown hash should fail"
24471
24472         $LCTL set_param fail_loc=0
24473
24474         umount_client $MOUNT || error "umount failed"
24475         mount_client $MOUNT || error "mount failed"
24476
24477         return 0
24478 }
24479 run_test 300i "client handle unknown hash type striped directory"
24480
24481 test_300j() {
24482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24484         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24485                 skip "Need MDS version at least 2.7.55"
24486
24487         local stripe_count
24488         local file
24489
24490         mkdir $DIR/$tdir
24491
24492         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24493         $LCTL set_param fail_loc=0x1702
24494         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24495                 error "set striped dir error"
24496
24497         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24498                 error "create files under striped dir failed"
24499
24500         $LCTL set_param fail_loc=0
24501
24502         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24503
24504         return 0
24505 }
24506 run_test 300j "test large update record"
24507
24508 test_300k() {
24509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24512                 skip "Need MDS version at least 2.7.55"
24513
24514         # this test needs a huge transaction
24515         local kb
24516         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24517              osd*.$FSNAME-MDT0000.kbytestotal")
24518         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24519
24520         local stripe_count
24521         local file
24522
24523         mkdir $DIR/$tdir
24524
24525         #define OBD_FAIL_LARGE_STRIPE   0x1703
24526         $LCTL set_param fail_loc=0x1703
24527         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24528                 error "set striped dir error"
24529         $LCTL set_param fail_loc=0
24530
24531         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24532                 error "getstripeddir fails"
24533         rm -rf $DIR/$tdir/striped_dir ||
24534                 error "unlink striped dir fails"
24535
24536         return 0
24537 }
24538 run_test 300k "test large striped directory"
24539
24540 test_300l() {
24541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24542         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24543         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24544                 skip "Need MDS version at least 2.7.55"
24545
24546         local stripe_index
24547
24548         test_mkdir -p $DIR/$tdir/striped_dir
24549         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24550                         error "chown $RUNAS_ID failed"
24551         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24552                 error "set default striped dir failed"
24553
24554         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24555         $LCTL set_param fail_loc=0x80000158
24556         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24557
24558         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24559         [ $stripe_index -eq 1 ] ||
24560                 error "expect 1 get $stripe_index for $dir"
24561 }
24562 run_test 300l "non-root user to create dir under striped dir with stale layout"
24563
24564 test_300m() {
24565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24566         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24567         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24568                 skip "Need MDS version at least 2.7.55"
24569
24570         mkdir -p $DIR/$tdir/striped_dir
24571         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24572                 error "set default stripes dir error"
24573
24574         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24575
24576         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24577         [ $stripe_count -eq 0 ] ||
24578                         error "expect 0 get $stripe_count for a"
24579
24580         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24581                 error "set default stripes dir error"
24582
24583         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24584
24585         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24586         [ $stripe_count -eq 0 ] ||
24587                         error "expect 0 get $stripe_count for b"
24588
24589         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24590                 error "set default stripes dir error"
24591
24592         mkdir $DIR/$tdir/striped_dir/c &&
24593                 error "default stripe_index is invalid, mkdir c should fails"
24594
24595         rm -rf $DIR/$tdir || error "rmdir fails"
24596 }
24597 run_test 300m "setstriped directory on single MDT FS"
24598
24599 cleanup_300n() {
24600         local list=$(comma_list $(mdts_nodes))
24601
24602         trap 0
24603         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24604 }
24605
24606 test_300n() {
24607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24609         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24610                 skip "Need MDS version at least 2.7.55"
24611         remote_mds_nodsh && skip "remote MDS with nodsh"
24612
24613         local stripe_index
24614         local list=$(comma_list $(mdts_nodes))
24615
24616         trap cleanup_300n RETURN EXIT
24617         mkdir -p $DIR/$tdir
24618         chmod 777 $DIR/$tdir
24619         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24620                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24621                 error "create striped dir succeeds with gid=0"
24622
24623         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24624         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24625                 error "create striped dir fails with gid=-1"
24626
24627         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24628         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24629                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24630                 error "set default striped dir succeeds with gid=0"
24631
24632
24633         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24634         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24635                 error "set default striped dir fails with gid=-1"
24636
24637
24638         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24639         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24640                                         error "create test_dir fails"
24641         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24642                                         error "create test_dir1 fails"
24643         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24644                                         error "create test_dir2 fails"
24645         cleanup_300n
24646 }
24647 run_test 300n "non-root user to create dir under striped dir with default EA"
24648
24649 test_300o() {
24650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24652         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24653                 skip "Need MDS version at least 2.7.55"
24654
24655         local numfree1
24656         local numfree2
24657
24658         mkdir -p $DIR/$tdir
24659
24660         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24661         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24662         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24663                 skip "not enough free inodes $numfree1 $numfree2"
24664         fi
24665
24666         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24667         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24668         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24669                 skip "not enough free space $numfree1 $numfree2"
24670         fi
24671
24672         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24673                 error "setdirstripe fails"
24674
24675         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24676                 error "create dirs fails"
24677
24678         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24679         ls $DIR/$tdir/striped_dir > /dev/null ||
24680                 error "ls striped dir fails"
24681         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24682                 error "unlink big striped dir fails"
24683 }
24684 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24685
24686 test_300p() {
24687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24688         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24689         remote_mds_nodsh && skip "remote MDS with nodsh"
24690
24691         mkdir_on_mdt0 $DIR/$tdir
24692
24693         #define OBD_FAIL_OUT_ENOSPC     0x1704
24694         do_facet mds2 lctl set_param fail_loc=0x80001704
24695         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24696                  && error "create striped directory should fail"
24697
24698         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24699
24700         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24701         true
24702 }
24703 run_test 300p "create striped directory without space"
24704
24705 test_300q() {
24706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24708
24709         local fd=$(free_fd)
24710         local cmd="exec $fd<$tdir"
24711         cd $DIR
24712         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24713         eval $cmd
24714         cmd="exec $fd<&-"
24715         trap "eval $cmd" EXIT
24716         cd $tdir || error "cd $tdir fails"
24717         rmdir  ../$tdir || error "rmdir $tdir fails"
24718         mkdir local_dir && error "create dir succeeds"
24719         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24720         eval $cmd
24721         return 0
24722 }
24723 run_test 300q "create remote directory under orphan directory"
24724
24725 test_300r() {
24726         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24727                 skip "Need MDS version at least 2.7.55" && return
24728         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24729
24730         mkdir $DIR/$tdir
24731
24732         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24733                 error "set striped dir error"
24734
24735         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24736                 error "getstripeddir fails"
24737
24738         local stripe_count
24739         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24740                       awk '/lmv_stripe_count:/ { print $2 }')
24741
24742         [ $MDSCOUNT -ne $stripe_count ] &&
24743                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24744
24745         rm -rf $DIR/$tdir/striped_dir ||
24746                 error "unlink striped dir fails"
24747 }
24748 run_test 300r "test -1 striped directory"
24749
24750 test_300s_helper() {
24751         local count=$1
24752
24753         local stripe_dir=$DIR/$tdir/striped_dir.$count
24754
24755         $LFS mkdir -c $count $stripe_dir ||
24756                 error "lfs mkdir -c error"
24757
24758         $LFS getdirstripe $stripe_dir ||
24759                 error "lfs getdirstripe fails"
24760
24761         local stripe_count
24762         stripe_count=$($LFS getdirstripe $stripe_dir |
24763                       awk '/lmv_stripe_count:/ { print $2 }')
24764
24765         [ $count -ne $stripe_count ] &&
24766                 error_noexit "bad stripe count $stripe_count expected $count"
24767
24768         local dupe_stripes
24769         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24770                 awk '/0x/ {count[$1] += 1}; END {
24771                         for (idx in count) {
24772                                 if (count[idx]>1) {
24773                                         print "index " idx " count " count[idx]
24774                                 }
24775                         }
24776                 }')
24777
24778         if [[ -n "$dupe_stripes" ]] ; then
24779                 lfs getdirstripe $stripe_dir
24780                 error_noexit "Dupe MDT above: $dupe_stripes "
24781         fi
24782
24783         rm -rf $stripe_dir ||
24784                 error_noexit "unlink $stripe_dir fails"
24785 }
24786
24787 test_300s() {
24788         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24789                 skip "Need MDS version at least 2.7.55" && return
24790         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24791
24792         mkdir $DIR/$tdir
24793         for count in $(seq 2 $MDSCOUNT); do
24794                 test_300s_helper $count
24795         done
24796 }
24797 run_test 300s "test lfs mkdir -c without -i"
24798
24799 test_300t() {
24800         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24801                 skip "need MDS 2.14.55 or later"
24802         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24803
24804         local testdir="$DIR/$tdir/striped_dir"
24805         local dir1=$testdir/dir1
24806         local dir2=$testdir/dir2
24807
24808         mkdir -p $testdir
24809
24810         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24811                 error "failed to set default stripe count for $testdir"
24812
24813         mkdir $dir1
24814         local stripe_count=$($LFS getdirstripe -c $dir1)
24815
24816         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24817
24818         local max_count=$((MDSCOUNT - 1))
24819         local mdts=$(comma_list $(mdts_nodes))
24820
24821         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24822         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24823
24824         mkdir $dir2
24825         stripe_count=$($LFS getdirstripe -c $dir2)
24826
24827         (( $stripe_count == $max_count )) || error "wrong stripe count"
24828 }
24829 run_test 300t "test max_mdt_stripecount"
24830
24831 prepare_remote_file() {
24832         mkdir $DIR/$tdir/src_dir ||
24833                 error "create remote source failed"
24834
24835         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24836                  error "cp to remote source failed"
24837         touch $DIR/$tdir/src_dir/a
24838
24839         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24840                 error "create remote target dir failed"
24841
24842         touch $DIR/$tdir/tgt_dir/b
24843
24844         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24845                 error "rename dir cross MDT failed!"
24846
24847         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24848                 error "src_child still exists after rename"
24849
24850         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24851                 error "missing file(a) after rename"
24852
24853         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24854                 error "diff after rename"
24855 }
24856
24857 test_310a() {
24858         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24860
24861         local remote_file=$DIR/$tdir/tgt_dir/b
24862
24863         mkdir -p $DIR/$tdir
24864
24865         prepare_remote_file || error "prepare remote file failed"
24866
24867         #open-unlink file
24868         $OPENUNLINK $remote_file $remote_file ||
24869                 error "openunlink $remote_file failed"
24870         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24871 }
24872 run_test 310a "open unlink remote file"
24873
24874 test_310b() {
24875         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24877
24878         local remote_file=$DIR/$tdir/tgt_dir/b
24879
24880         mkdir -p $DIR/$tdir
24881
24882         prepare_remote_file || error "prepare remote file failed"
24883
24884         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24885         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24886         $CHECKSTAT -t file $remote_file || error "check file failed"
24887 }
24888 run_test 310b "unlink remote file with multiple links while open"
24889
24890 test_310c() {
24891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24892         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24893
24894         local remote_file=$DIR/$tdir/tgt_dir/b
24895
24896         mkdir -p $DIR/$tdir
24897
24898         prepare_remote_file || error "prepare remote file failed"
24899
24900         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24901         multiop_bg_pause $remote_file O_uc ||
24902                         error "mulitop failed for remote file"
24903         MULTIPID=$!
24904         $MULTIOP $DIR/$tfile Ouc
24905         kill -USR1 $MULTIPID
24906         wait $MULTIPID
24907 }
24908 run_test 310c "open-unlink remote file with multiple links"
24909
24910 #LU-4825
24911 test_311() {
24912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24913         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24914         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24915                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24916         remote_mds_nodsh && skip "remote MDS with nodsh"
24917
24918         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24919         local mdts=$(comma_list $(mdts_nodes))
24920
24921         mkdir -p $DIR/$tdir
24922         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24923         createmany -o $DIR/$tdir/$tfile. 1000
24924
24925         # statfs data is not real time, let's just calculate it
24926         old_iused=$((old_iused + 1000))
24927
24928         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24929                         osp.*OST0000*MDT0000.create_count")
24930         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24931                                 osp.*OST0000*MDT0000.max_create_count")
24932         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24933
24934         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24935         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24936         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24937
24938         unlinkmany $DIR/$tdir/$tfile. 1000
24939
24940         do_nodes $mdts "$LCTL set_param -n \
24941                         osp.*OST0000*.max_create_count=$max_count"
24942         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24943                 do_nodes $mdts "$LCTL set_param -n \
24944                                 osp.*OST0000*.create_count=$count"
24945         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24946                         grep "=0" && error "create_count is zero"
24947
24948         local new_iused
24949         for i in $(seq 120); do
24950                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24951                 # system may be too busy to destroy all objs in time, use
24952                 # a somewhat small value to not fail autotest
24953                 [ $((old_iused - new_iused)) -gt 400 ] && break
24954                 sleep 1
24955         done
24956
24957         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24958         [ $((old_iused - new_iused)) -gt 400 ] ||
24959                 error "objs not destroyed after unlink"
24960 }
24961 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24962
24963 zfs_get_objid()
24964 {
24965         local ost=$1
24966         local tf=$2
24967         local fid=($($LFS getstripe $tf | grep 0x))
24968         local seq=${fid[3]#0x}
24969         local objid=${fid[1]}
24970
24971         local vdevdir=$(dirname $(facet_vdevice $ost))
24972         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24973         local zfs_zapid=$(do_facet $ost $cmd |
24974                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24975                           awk '/Object/{getline; print $1}')
24976         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24977                           awk "/$objid = /"'{printf $3}')
24978
24979         echo $zfs_objid
24980 }
24981
24982 zfs_object_blksz() {
24983         local ost=$1
24984         local objid=$2
24985
24986         local vdevdir=$(dirname $(facet_vdevice $ost))
24987         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24988         local blksz=$(do_facet $ost $cmd $objid |
24989                       awk '/dblk/{getline; printf $4}')
24990
24991         case "${blksz: -1}" in
24992                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24993                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24994                 *) ;;
24995         esac
24996
24997         echo $blksz
24998 }
24999
25000 test_312() { # LU-4856
25001         remote_ost_nodsh && skip "remote OST with nodsh"
25002         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25003
25004         local max_blksz=$(do_facet ost1 \
25005                           $ZFS get -p recordsize $(facet_device ost1) |
25006                           awk '!/VALUE/{print $3}')
25007         local tf=$DIR/$tfile
25008
25009         $LFS setstripe -c1 $tf
25010         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25011
25012         # Get ZFS object id
25013         local zfs_objid=$(zfs_get_objid $facet $tf)
25014         # block size change by sequential overwrite
25015         local bs
25016
25017         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25018                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25019
25020                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25021                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25022         done
25023         rm -f $tf
25024
25025         $LFS setstripe -c1 $tf
25026         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25027
25028         # block size change by sequential append write
25029         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25030         zfs_objid=$(zfs_get_objid $facet $tf)
25031         local count
25032
25033         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25034                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25035                         oflag=sync conv=notrunc
25036
25037                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25038                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25039                         error "blksz error, actual $blksz, " \
25040                                 "expected: 2 * $count * $PAGE_SIZE"
25041         done
25042         rm -f $tf
25043
25044         # random write
25045         $LFS setstripe -c1 $tf
25046         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25047         zfs_objid=$(zfs_get_objid $facet $tf)
25048
25049         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25050         blksz=$(zfs_object_blksz $facet $zfs_objid)
25051         (( blksz == PAGE_SIZE )) ||
25052                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25053
25054         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25055         blksz=$(zfs_object_blksz $facet $zfs_objid)
25056         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25057
25058         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25059         blksz=$(zfs_object_blksz $facet $zfs_objid)
25060         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25061 }
25062 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25063
25064 test_313() {
25065         remote_ost_nodsh && skip "remote OST with nodsh"
25066
25067         local file=$DIR/$tfile
25068
25069         rm -f $file
25070         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25071
25072         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25073         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25074         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25075                 error "write should failed"
25076         do_facet ost1 "$LCTL set_param fail_loc=0"
25077         rm -f $file
25078 }
25079 run_test 313 "io should fail after last_rcvd update fail"
25080
25081 test_314() {
25082         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25083
25084         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25085         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25086         rm -f $DIR/$tfile
25087         wait_delete_completed
25088         do_facet ost1 "$LCTL set_param fail_loc=0"
25089 }
25090 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25091
25092 test_315() { # LU-618
25093         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25094
25095         local file=$DIR/$tfile
25096         rm -f $file
25097
25098         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25099                 error "multiop file write failed"
25100         $MULTIOP $file oO_RDONLY:r4063232_c &
25101         PID=$!
25102
25103         sleep 2
25104
25105         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25106         kill -USR1 $PID
25107
25108         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25109         rm -f $file
25110 }
25111 run_test 315 "read should be accounted"
25112
25113 test_316() {
25114         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25115         large_xattr_enabled || skip "ea_inode feature disabled"
25116
25117         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25118         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25119         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25120         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25121
25122         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25123 }
25124 run_test 316 "lfs migrate of file with large_xattr enabled"
25125
25126 test_317() {
25127         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25128                 skip "Need MDS version at least 2.11.53"
25129         if [ "$ost1_FSTYPE" == "zfs" ]; then
25130                 skip "LU-10370: no implementation for ZFS"
25131         fi
25132
25133         local trunc_sz
25134         local grant_blk_size
25135
25136         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25137                         awk '/grant_block_size:/ { print $2; exit; }')
25138         #
25139         # Create File of size 5M. Truncate it to below size's and verify
25140         # blocks count.
25141         #
25142         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25143                 error "Create file $DIR/$tfile failed"
25144         stack_trap "rm -f $DIR/$tfile" EXIT
25145
25146         for trunc_sz in 2097152 4097 4000 509 0; do
25147                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25148                         error "truncate $tfile to $trunc_sz failed"
25149                 local sz=$(stat --format=%s $DIR/$tfile)
25150                 local blk=$(stat --format=%b $DIR/$tfile)
25151                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25152                                      grant_blk_size) * 8))
25153
25154                 if [[ $blk -ne $trunc_blk ]]; then
25155                         $(which stat) $DIR/$tfile
25156                         error "Expected Block $trunc_blk got $blk for $tfile"
25157                 fi
25158
25159                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25160                         error "Expected Size $trunc_sz got $sz for $tfile"
25161         done
25162
25163         #
25164         # sparse file test
25165         # Create file with a hole and write actual 65536 bytes which aligned
25166         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25167         #
25168         local bs=65536
25169         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25170                 error "Create file : $DIR/$tfile"
25171
25172         #
25173         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25174         # blocks. The block count must drop to 8.
25175         #
25176         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25177                 ((bs - grant_blk_size) + 1)))
25178         $TRUNCATE $DIR/$tfile $trunc_sz ||
25179                 error "truncate $tfile to $trunc_sz failed"
25180
25181         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25182         sz=$(stat --format=%s $DIR/$tfile)
25183         blk=$(stat --format=%b $DIR/$tfile)
25184
25185         if [[ $blk -ne $trunc_bsz ]]; then
25186                 $(which stat) $DIR/$tfile
25187                 error "Expected Block $trunc_bsz got $blk for $tfile"
25188         fi
25189
25190         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25191                 error "Expected Size $trunc_sz got $sz for $tfile"
25192 }
25193 run_test 317 "Verify blocks get correctly update after truncate"
25194
25195 test_318() {
25196         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25197         local old_max_active=$($LCTL get_param -n \
25198                             ${llite_name}.max_read_ahead_async_active \
25199                             2>/dev/null)
25200
25201         $LCTL set_param llite.*.max_read_ahead_async_active=256
25202         local max_active=$($LCTL get_param -n \
25203                            ${llite_name}.max_read_ahead_async_active \
25204                            2>/dev/null)
25205         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25206
25207         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25208                 error "set max_read_ahead_async_active should succeed"
25209
25210         $LCTL set_param llite.*.max_read_ahead_async_active=512
25211         max_active=$($LCTL get_param -n \
25212                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25213         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25214
25215         # restore @max_active
25216         [ $old_max_active -ne 0 ] && $LCTL set_param \
25217                 llite.*.max_read_ahead_async_active=$old_max_active
25218
25219         local old_threshold=$($LCTL get_param -n \
25220                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25221         local max_per_file_mb=$($LCTL get_param -n \
25222                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25223
25224         local invalid=$(($max_per_file_mb + 1))
25225         $LCTL set_param \
25226                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25227                         && error "set $invalid should fail"
25228
25229         local valid=$(($invalid - 1))
25230         $LCTL set_param \
25231                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25232                         error "set $valid should succeed"
25233         local threshold=$($LCTL get_param -n \
25234                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25235         [ $threshold -eq $valid ] || error \
25236                 "expect threshold $valid got $threshold"
25237         $LCTL set_param \
25238                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25239 }
25240 run_test 318 "Verify async readahead tunables"
25241
25242 test_319() {
25243         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25244
25245         local before=$(date +%s)
25246         local evict
25247         local mdir=$DIR/$tdir
25248         local file=$mdir/xxx
25249
25250         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25251         touch $file
25252
25253 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25254         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25255         $LFS migrate -m1 $mdir &
25256
25257         sleep 1
25258         dd if=$file of=/dev/null
25259         wait
25260         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25261           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25262
25263         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25264 }
25265 run_test 319 "lost lease lock on migrate error"
25266
25267 test_398a() { # LU-4198
25268         local ost1_imp=$(get_osc_import_name client ost1)
25269         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25270                          cut -d'.' -f2)
25271
25272         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25273         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25274
25275         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25276         # request a new lock on client
25277         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25278
25279         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25280         #local lock_count=$($LCTL get_param -n \
25281         #                  ldlm.namespaces.$imp_name.lru_size)
25282         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25283
25284         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25285
25286         # no lock cached, should use lockless DIO and not enqueue new lock
25287         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25288                 conv=notrunc ||
25289                 error "dio write failed"
25290         lock_count=$($LCTL get_param -n \
25291                      ldlm.namespaces.$imp_name.lru_size)
25292         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25293
25294         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25295
25296         # no lock cached, should use locked DIO append
25297         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25298                 conv=notrunc || error "DIO append failed"
25299         lock_count=$($LCTL get_param -n \
25300                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25301         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25302 }
25303 run_test 398a "direct IO should cancel lock otherwise lockless"
25304
25305 test_398b() { # LU-4198
25306         local before=$(date +%s)
25307         local njobs=4
25308         local size=48
25309
25310         which fio || skip_env "no fio installed"
25311         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25312         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25313
25314         # Single page, multiple pages, stripe size, 4*stripe size
25315         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25316                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25317                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25318                         --numjobs=$njobs --fallocate=none \
25319                         --iodepth=16 --allow_file_create=0 \
25320                         --size=$((size/njobs))M \
25321                         --filename=$DIR/$tfile &
25322                 bg_pid=$!
25323
25324                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25325                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25326                         --numjobs=$njobs --fallocate=none \
25327                         --iodepth=16 --allow_file_create=0 \
25328                         --size=$((size/njobs))M \
25329                         --filename=$DIR/$tfile || true
25330                 wait $bg_pid
25331         done
25332
25333         evict=$(do_facet client $LCTL get_param \
25334                 osc.$FSNAME-OST*-osc-*/state |
25335             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25336
25337         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25338                 (do_facet client $LCTL get_param \
25339                         osc.$FSNAME-OST*-osc-*/state;
25340                     error "eviction happened: $evict before:$before")
25341
25342         rm -f $DIR/$tfile
25343 }
25344 run_test 398b "DIO and buffer IO race"
25345
25346 test_398c() { # LU-4198
25347         local ost1_imp=$(get_osc_import_name client ost1)
25348         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25349                          cut -d'.' -f2)
25350
25351         which fio || skip_env "no fio installed"
25352
25353         saved_debug=$($LCTL get_param -n debug)
25354         $LCTL set_param debug=0
25355
25356         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25357         ((size /= 1024)) # by megabytes
25358         ((size /= 2)) # write half of the OST at most
25359         [ $size -gt 40 ] && size=40 #reduce test time anyway
25360
25361         $LFS setstripe -c 1 $DIR/$tfile
25362
25363         # it seems like ldiskfs reserves more space than necessary if the
25364         # writing blocks are not mapped, so it extends the file firstly
25365         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25366         cancel_lru_locks osc
25367
25368         # clear and verify rpc_stats later
25369         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25370
25371         local njobs=4
25372         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25373         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25374                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25375                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25376                 --filename=$DIR/$tfile
25377         [ $? -eq 0 ] || error "fio write error"
25378
25379         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25380                 error "Locks were requested while doing AIO"
25381
25382         # get the percentage of 1-page I/O
25383         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25384                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25385                 awk '{print $7}')
25386         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25387
25388         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25389         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25390                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25391                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25392                 --filename=$DIR/$tfile
25393         [ $? -eq 0 ] || error "fio mixed read write error"
25394
25395         echo "AIO with large block size ${size}M"
25396         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25397                 --numjobs=1 --fallocate=none --ioengine=libaio \
25398                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25399                 --filename=$DIR/$tfile
25400         [ $? -eq 0 ] || error "fio large block size failed"
25401
25402         rm -f $DIR/$tfile
25403         $LCTL set_param debug="$saved_debug"
25404 }
25405 run_test 398c "run fio to test AIO"
25406
25407 test_398d() { #  LU-13846
25408         which aiocp || skip_env "no aiocp installed"
25409         local aio_file=$DIR/$tfile.aio
25410
25411         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25412
25413         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25414         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25415         stack_trap "rm -f $DIR/$tfile $aio_file"
25416
25417         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25418
25419         # make sure we don't crash and fail properly
25420         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25421                 error "aio not aligned with PAGE SIZE should fail"
25422
25423         rm -f $DIR/$tfile $aio_file
25424 }
25425 run_test 398d "run aiocp to verify block size > stripe size"
25426
25427 test_398e() {
25428         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25429         touch $DIR/$tfile.new
25430         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25431 }
25432 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25433
25434 test_398f() { #  LU-14687
25435         which aiocp || skip_env "no aiocp installed"
25436         local aio_file=$DIR/$tfile.aio
25437
25438         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25439
25440         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25441         stack_trap "rm -f $DIR/$tfile $aio_file"
25442
25443         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25444         $LCTL set_param fail_loc=0x1418
25445         # make sure we don't crash and fail properly
25446         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25447                 error "aio with page allocation failure succeeded"
25448         $LCTL set_param fail_loc=0
25449         diff $DIR/$tfile $aio_file
25450         [[ $? != 0 ]] || error "no diff after failed aiocp"
25451 }
25452 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25453
25454 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25455 # stripe and i/o size must be > stripe size
25456 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25457 # single RPC in flight.  This test shows async DIO submission is working by
25458 # showing multiple RPCs in flight.
25459 test_398g() { #  LU-13798
25460         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25461
25462         # We need to do some i/o first to acquire enough grant to put our RPCs
25463         # in flight; otherwise a new connection may not have enough grant
25464         # available
25465         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25466                 error "parallel dio failed"
25467         stack_trap "rm -f $DIR/$tfile"
25468
25469         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25470         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25471         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25472         stack_trap "$LCTL set_param -n $pages_per_rpc"
25473
25474         # Recreate file so it's empty
25475         rm -f $DIR/$tfile
25476         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25477         #Pause rpc completion to guarantee we see multiple rpcs in flight
25478         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25479         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25480         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25481
25482         # Clear rpc stats
25483         $LCTL set_param osc.*.rpc_stats=c
25484
25485         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25486                 error "parallel dio failed"
25487         stack_trap "rm -f $DIR/$tfile"
25488
25489         $LCTL get_param osc.*-OST0000-*.rpc_stats
25490         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25491                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25492                 grep "8:" | awk '{print $8}')
25493         # We look at the "8 rpcs in flight" field, and verify A) it is present
25494         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25495         # as expected for an 8M DIO to a file with 1M stripes.
25496         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25497
25498         # Verify turning off parallel dio works as expected
25499         # Clear rpc stats
25500         $LCTL set_param osc.*.rpc_stats=c
25501         $LCTL set_param llite.*.parallel_dio=0
25502         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25503
25504         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25505                 error "dio with parallel dio disabled failed"
25506
25507         # Ideally, we would see only one RPC in flight here, but there is an
25508         # unavoidable race between i/o completion and RPC in flight counting,
25509         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25510         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25511         # So instead we just verify it's always < 8.
25512         $LCTL get_param osc.*-OST0000-*.rpc_stats
25513         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25514                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25515                 grep '^$' -B1 | grep . | awk '{print $1}')
25516         [ $ret != "8:" ] ||
25517                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25518 }
25519 run_test 398g "verify parallel dio async RPC submission"
25520
25521 test_398h() { #  LU-13798
25522         local dio_file=$DIR/$tfile.dio
25523
25524         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25525
25526         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25527         stack_trap "rm -f $DIR/$tfile $dio_file"
25528
25529         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25530                 error "parallel dio failed"
25531         diff $DIR/$tfile $dio_file
25532         [[ $? == 0 ]] || error "file diff after aiocp"
25533 }
25534 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25535
25536 test_398i() { #  LU-13798
25537         local dio_file=$DIR/$tfile.dio
25538
25539         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25540
25541         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25542         stack_trap "rm -f $DIR/$tfile $dio_file"
25543
25544         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25545         $LCTL set_param fail_loc=0x1418
25546         # make sure we don't crash and fail properly
25547         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25548                 error "parallel dio page allocation failure succeeded"
25549         diff $DIR/$tfile $dio_file
25550         [[ $? != 0 ]] || error "no diff after failed aiocp"
25551 }
25552 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25553
25554 test_398j() { #  LU-13798
25555         # Stripe size > RPC size but less than i/o size tests split across
25556         # stripes and RPCs for individual i/o op
25557         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25558
25559         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25560         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25561         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25562         stack_trap "$LCTL set_param -n $pages_per_rpc"
25563
25564         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25565                 error "parallel dio write failed"
25566         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25567
25568         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25569                 error "parallel dio read failed"
25570         diff $DIR/$tfile $DIR/$tfile.2
25571         [[ $? == 0 ]] || error "file diff after parallel dio read"
25572 }
25573 run_test 398j "test parallel dio where stripe size > rpc_size"
25574
25575 test_398k() { #  LU-13798
25576         wait_delete_completed
25577         wait_mds_ost_sync
25578
25579         # 4 stripe file; we will cause out of space on OST0
25580         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25581
25582         # Fill OST0 (if it's not too large)
25583         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25584                    head -n1)
25585         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25586                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25587         fi
25588         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25589         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25590                 error "dd should fill OST0"
25591         stack_trap "rm -f $DIR/$tfile.1"
25592
25593         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25594         err=$?
25595
25596         ls -la $DIR/$tfile
25597         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25598                 error "file is not 0 bytes in size"
25599
25600         # dd above should not succeed, but don't error until here so we can
25601         # get debug info above
25602         [[ $err != 0 ]] ||
25603                 error "parallel dio write with enospc succeeded"
25604         stack_trap "rm -f $DIR/$tfile"
25605 }
25606 run_test 398k "test enospc on first stripe"
25607
25608 test_398l() { #  LU-13798
25609         wait_delete_completed
25610         wait_mds_ost_sync
25611
25612         # 4 stripe file; we will cause out of space on OST0
25613         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25614         # happens on the second i/o chunk we issue
25615         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25616
25617         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25618         stack_trap "rm -f $DIR/$tfile"
25619
25620         # Fill OST0 (if it's not too large)
25621         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25622                    head -n1)
25623         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25624                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25625         fi
25626         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25627         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25628                 error "dd should fill OST0"
25629         stack_trap "rm -f $DIR/$tfile.1"
25630
25631         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25632         err=$?
25633         stack_trap "rm -f $DIR/$tfile.2"
25634
25635         # Check that short write completed as expected
25636         ls -la $DIR/$tfile.2
25637         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25638                 error "file is not 1M 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
25645         # Truncate source file to same length as output file and diff them
25646         $TRUNCATE $DIR/$tfile 1048576
25647         diff $DIR/$tfile $DIR/$tfile.2
25648         [[ $? == 0 ]] || error "data incorrect after short write"
25649 }
25650 run_test 398l "test enospc on intermediate stripe/RPC"
25651
25652 test_398m() { #  LU-13798
25653         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25654
25655         # Set up failure on OST0, the first stripe:
25656         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25657         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25658         # OST0 is on ost1, OST1 is on ost2.
25659         # So this fail_val specifies OST0
25660         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25661         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25662
25663         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25664                 error "parallel dio write with failure on first stripe succeeded"
25665         stack_trap "rm -f $DIR/$tfile"
25666         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25667
25668         # Place data in file for read
25669         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25670                 error "parallel dio write failed"
25671
25672         # Fail read on OST0, first stripe
25673         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25674         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25675         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25676                 error "parallel dio read with error on first stripe succeeded"
25677         rm -f $DIR/$tfile.2
25678         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25679
25680         # Switch to testing on OST1, second stripe
25681         # Clear file contents, maintain striping
25682         echo > $DIR/$tfile
25683         # Set up failure on OST1, second stripe:
25684         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25685         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25686
25687         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25688                 error "parallel dio write with failure on second stripe succeeded"
25689         stack_trap "rm -f $DIR/$tfile"
25690         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25691
25692         # Place data in file for read
25693         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25694                 error "parallel dio write failed"
25695
25696         # Fail read on OST1, second stripe
25697         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25698         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25699         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25700                 error "parallel dio read with error on second stripe succeeded"
25701         rm -f $DIR/$tfile.2
25702         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25703 }
25704 run_test 398m "test RPC failures with parallel dio"
25705
25706 # Parallel submission of DIO should not cause problems for append, but it's
25707 # important to verify.
25708 test_398n() { #  LU-13798
25709         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25710
25711         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25712                 error "dd to create source file failed"
25713         stack_trap "rm -f $DIR/$tfile"
25714
25715         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25716                 error "parallel dio write with failure on second stripe succeeded"
25717         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25718         diff $DIR/$tfile $DIR/$tfile.1
25719         [[ $? == 0 ]] || error "data incorrect after append"
25720
25721 }
25722 run_test 398n "test append with parallel DIO"
25723
25724 test_398o() {
25725         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25726 }
25727 run_test 398o "right kms with DIO"
25728
25729 test_fake_rw() {
25730         local read_write=$1
25731         if [ "$read_write" = "write" ]; then
25732                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25733         elif [ "$read_write" = "read" ]; then
25734                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25735         else
25736                 error "argument error"
25737         fi
25738
25739         # turn off debug for performance testing
25740         local saved_debug=$($LCTL get_param -n debug)
25741         $LCTL set_param debug=0
25742
25743         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25744
25745         # get ost1 size - $FSNAME-OST0000
25746         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25747         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25748         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25749
25750         if [ "$read_write" = "read" ]; then
25751                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25752         fi
25753
25754         local start_time=$(date +%s.%N)
25755         $dd_cmd bs=1M count=$blocks oflag=sync ||
25756                 error "real dd $read_write error"
25757         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25758
25759         if [ "$read_write" = "write" ]; then
25760                 rm -f $DIR/$tfile
25761         fi
25762
25763         # define OBD_FAIL_OST_FAKE_RW           0x238
25764         do_facet ost1 $LCTL set_param fail_loc=0x238
25765
25766         local start_time=$(date +%s.%N)
25767         $dd_cmd bs=1M count=$blocks oflag=sync ||
25768                 error "fake dd $read_write error"
25769         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25770
25771         if [ "$read_write" = "write" ]; then
25772                 # verify file size
25773                 cancel_lru_locks osc
25774                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25775                         error "$tfile size not $blocks MB"
25776         fi
25777         do_facet ost1 $LCTL set_param fail_loc=0
25778
25779         echo "fake $read_write $duration_fake vs. normal $read_write" \
25780                 "$duration in seconds"
25781         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25782                 error_not_in_vm "fake write is slower"
25783
25784         $LCTL set_param -n debug="$saved_debug"
25785         rm -f $DIR/$tfile
25786 }
25787 test_399a() { # LU-7655 for OST fake write
25788         remote_ost_nodsh && skip "remote OST with nodsh"
25789
25790         test_fake_rw write
25791 }
25792 run_test 399a "fake write should not be slower than normal write"
25793
25794 test_399b() { # LU-8726 for OST fake read
25795         remote_ost_nodsh && skip "remote OST with nodsh"
25796         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25797                 skip_env "ldiskfs only test"
25798         fi
25799
25800         test_fake_rw read
25801 }
25802 run_test 399b "fake read should not be slower than normal read"
25803
25804 test_400a() { # LU-1606, was conf-sanity test_74
25805         if ! which $CC > /dev/null 2>&1; then
25806                 skip_env "$CC is not installed"
25807         fi
25808
25809         local extra_flags=''
25810         local out=$TMP/$tfile
25811         local prefix=/usr/include/lustre
25812         local prog
25813
25814         # Oleg removes .c files in his test rig so test if any c files exist
25815         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25816                 skip_env "Needed .c test files are missing"
25817
25818         if ! [[ -d $prefix ]]; then
25819                 # Assume we're running in tree and fixup the include path.
25820                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25821                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25822                 extra_flags+=" -L$LUSTRE/utils/.libs"
25823         fi
25824
25825         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25826                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25827                         error "client api broken"
25828         done
25829         rm -f $out
25830 }
25831 run_test 400a "Lustre client api program can compile and link"
25832
25833 test_400b() { # LU-1606, LU-5011
25834         local header
25835         local out=$TMP/$tfile
25836         local prefix=/usr/include/linux/lustre
25837
25838         # We use a hard coded prefix so that this test will not fail
25839         # when run in tree. There are headers in lustre/include/lustre/
25840         # that are not packaged (like lustre_idl.h) and have more
25841         # complicated include dependencies (like config.h and lnet/types.h).
25842         # Since this test about correct packaging we just skip them when
25843         # they don't exist (see below) rather than try to fixup cppflags.
25844
25845         if ! which $CC > /dev/null 2>&1; then
25846                 skip_env "$CC is not installed"
25847         fi
25848
25849         for header in $prefix/*.h; do
25850                 if ! [[ -f "$header" ]]; then
25851                         continue
25852                 fi
25853
25854                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25855                         continue # lustre_ioctl.h is internal header
25856                 fi
25857
25858                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25859                         error "cannot compile '$header'"
25860         done
25861         rm -f $out
25862 }
25863 run_test 400b "packaged headers can be compiled"
25864
25865 test_401a() { #LU-7437
25866         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25867         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25868
25869         #count the number of parameters by "list_param -R"
25870         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25871         #count the number of parameters by listing proc files
25872         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25873         echo "proc_dirs='$proc_dirs'"
25874         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25875         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25876                       sort -u | wc -l)
25877
25878         [ $params -eq $procs ] ||
25879                 error "found $params parameters vs. $procs proc files"
25880
25881         # test the list_param -D option only returns directories
25882         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25883         #count the number of parameters by listing proc directories
25884         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25885                 sort -u | wc -l)
25886
25887         [ $params -eq $procs ] ||
25888                 error "found $params parameters vs. $procs proc files"
25889 }
25890 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25891
25892 test_401b() {
25893         # jobid_var may not allow arbitrary values, so use jobid_name
25894         # if available
25895         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25896                 local testname=jobid_name tmp='testing%p'
25897         else
25898                 local testname=jobid_var tmp=testing
25899         fi
25900
25901         local save=$($LCTL get_param -n $testname)
25902
25903         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25904                 error "no error returned when setting bad parameters"
25905
25906         local jobid_new=$($LCTL get_param -n foe $testname baz)
25907         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25908
25909         $LCTL set_param -n fog=bam $testname=$save bat=fog
25910         local jobid_old=$($LCTL get_param -n foe $testname bag)
25911         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25912 }
25913 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25914
25915 test_401c() {
25916         # jobid_var may not allow arbitrary values, so use jobid_name
25917         # if available
25918         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25919                 local testname=jobid_name
25920         else
25921                 local testname=jobid_var
25922         fi
25923
25924         local jobid_var_old=$($LCTL get_param -n $testname)
25925         local jobid_var_new
25926
25927         $LCTL set_param $testname= &&
25928                 error "no error returned for 'set_param a='"
25929
25930         jobid_var_new=$($LCTL get_param -n $testname)
25931         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25932                 error "$testname was changed by setting without value"
25933
25934         $LCTL set_param $testname &&
25935                 error "no error returned for 'set_param a'"
25936
25937         jobid_var_new=$($LCTL get_param -n $testname)
25938         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25939                 error "$testname was changed by setting without value"
25940 }
25941 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25942
25943 test_401d() {
25944         # jobid_var may not allow arbitrary values, so use jobid_name
25945         # if available
25946         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25947                 local testname=jobid_name new_value='foo=bar%p'
25948         else
25949                 local testname=jobid_var new_valuie=foo=bar
25950         fi
25951
25952         local jobid_var_old=$($LCTL get_param -n $testname)
25953         local jobid_var_new
25954
25955         $LCTL set_param $testname=$new_value ||
25956                 error "'set_param a=b' did not accept a value containing '='"
25957
25958         jobid_var_new=$($LCTL get_param -n $testname)
25959         [[ "$jobid_var_new" == "$new_value" ]] ||
25960                 error "'set_param a=b' failed on a value containing '='"
25961
25962         # Reset the $testname to test the other format
25963         $LCTL set_param $testname=$jobid_var_old
25964         jobid_var_new=$($LCTL get_param -n $testname)
25965         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25966                 error "failed to reset $testname"
25967
25968         $LCTL set_param $testname $new_value ||
25969                 error "'set_param a b' did not accept a value containing '='"
25970
25971         jobid_var_new=$($LCTL get_param -n $testname)
25972         [[ "$jobid_var_new" == "$new_value" ]] ||
25973                 error "'set_param a b' failed on a value containing '='"
25974
25975         $LCTL set_param $testname $jobid_var_old
25976         jobid_var_new=$($LCTL get_param -n $testname)
25977         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25978                 error "failed to reset $testname"
25979 }
25980 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25981
25982 test_401e() { # LU-14779
25983         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25984                 error "lctl list_param MGC* failed"
25985         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25986         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25987                 error "lctl get_param lru_size failed"
25988 }
25989 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25990
25991 test_402() {
25992         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25993         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25994                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25995         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25996                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25997                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25998         remote_mds_nodsh && skip "remote MDS with nodsh"
25999
26000         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26001 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26002         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26003         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26004                 echo "Touch failed - OK"
26005 }
26006 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26007
26008 test_403() {
26009         local file1=$DIR/$tfile.1
26010         local file2=$DIR/$tfile.2
26011         local tfile=$TMP/$tfile
26012
26013         rm -f $file1 $file2 $tfile
26014
26015         touch $file1
26016         ln $file1 $file2
26017
26018         # 30 sec OBD_TIMEOUT in ll_getattr()
26019         # right before populating st_nlink
26020         $LCTL set_param fail_loc=0x80001409
26021         stat -c %h $file1 > $tfile &
26022
26023         # create an alias, drop all locks and reclaim the dentry
26024         < $file2
26025         cancel_lru_locks mdc
26026         cancel_lru_locks osc
26027         sysctl -w vm.drop_caches=2
26028
26029         wait
26030
26031         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26032
26033         rm -f $tfile $file1 $file2
26034 }
26035 run_test 403 "i_nlink should not drop to zero due to aliasing"
26036
26037 test_404() { # LU-6601
26038         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26039                 skip "Need server version newer than 2.8.52"
26040         remote_mds_nodsh && skip "remote MDS with nodsh"
26041
26042         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26043                 awk '/osp .*-osc-MDT/ { print $4}')
26044
26045         local osp
26046         for osp in $mosps; do
26047                 echo "Deactivate: " $osp
26048                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26049                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26050                         awk -vp=$osp '$4 == p { print $2 }')
26051                 [ $stat = IN ] || {
26052                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26053                         error "deactivate error"
26054                 }
26055                 echo "Activate: " $osp
26056                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26057                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26058                         awk -vp=$osp '$4 == p { print $2 }')
26059                 [ $stat = UP ] || {
26060                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26061                         error "activate error"
26062                 }
26063         done
26064 }
26065 run_test 404 "validate manual {de}activated works properly for OSPs"
26066
26067 test_405() {
26068         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26069         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26070                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26071                         skip "Layout swap lock is not supported"
26072
26073         check_swap_layouts_support
26074         check_swap_layout_no_dom $DIR
26075
26076         test_mkdir $DIR/$tdir
26077         swap_lock_test -d $DIR/$tdir ||
26078                 error "One layout swap locked test failed"
26079 }
26080 run_test 405 "Various layout swap lock tests"
26081
26082 test_406() {
26083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26084         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26085         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26087         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26088                 skip "Need MDS version at least 2.8.50"
26089
26090         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26091         local test_pool=$TESTNAME
26092
26093         pool_add $test_pool || error "pool_add failed"
26094         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26095                 error "pool_add_targets failed"
26096
26097         save_layout_restore_at_exit $MOUNT
26098
26099         # parent set default stripe count only, child will stripe from both
26100         # parent and fs default
26101         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26102                 error "setstripe $MOUNT failed"
26103         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26104         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26105         for i in $(seq 10); do
26106                 local f=$DIR/$tdir/$tfile.$i
26107                 touch $f || error "touch failed"
26108                 local count=$($LFS getstripe -c $f)
26109                 [ $count -eq $OSTCOUNT ] ||
26110                         error "$f stripe count $count != $OSTCOUNT"
26111                 local offset=$($LFS getstripe -i $f)
26112                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26113                 local size=$($LFS getstripe -S $f)
26114                 [ $size -eq $((def_stripe_size * 2)) ] ||
26115                         error "$f stripe size $size != $((def_stripe_size * 2))"
26116                 local pool=$($LFS getstripe -p $f)
26117                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26118         done
26119
26120         # change fs default striping, delete parent default striping, now child
26121         # will stripe from new fs default striping only
26122         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26123                 error "change $MOUNT default stripe failed"
26124         $LFS setstripe -c 0 $DIR/$tdir ||
26125                 error "delete $tdir default stripe failed"
26126         for i in $(seq 11 20); do
26127                 local f=$DIR/$tdir/$tfile.$i
26128                 touch $f || error "touch $f failed"
26129                 local count=$($LFS getstripe -c $f)
26130                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26131                 local offset=$($LFS getstripe -i $f)
26132                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26133                 local size=$($LFS getstripe -S $f)
26134                 [ $size -eq $def_stripe_size ] ||
26135                         error "$f stripe size $size != $def_stripe_size"
26136                 local pool=$($LFS getstripe -p $f)
26137                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26138         done
26139
26140         unlinkmany $DIR/$tdir/$tfile. 1 20
26141
26142         local f=$DIR/$tdir/$tfile
26143         pool_remove_all_targets $test_pool $f
26144         pool_remove $test_pool $f
26145 }
26146 run_test 406 "DNE support fs default striping"
26147
26148 test_407() {
26149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26150         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26151                 skip "Need MDS version at least 2.8.55"
26152         remote_mds_nodsh && skip "remote MDS with nodsh"
26153
26154         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26155                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26156         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26157                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26158         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26159
26160         #define OBD_FAIL_DT_TXN_STOP    0x2019
26161         for idx in $(seq $MDSCOUNT); do
26162                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26163         done
26164         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26165         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26166                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26167         true
26168 }
26169 run_test 407 "transaction fail should cause operation fail"
26170
26171 test_408() {
26172         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26173
26174         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26175         lctl set_param fail_loc=0x8000040a
26176         # let ll_prepare_partial_page() fail
26177         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26178
26179         rm -f $DIR/$tfile
26180
26181         # create at least 100 unused inodes so that
26182         # shrink_icache_memory(0) should not return 0
26183         touch $DIR/$tfile-{0..100}
26184         rm -f $DIR/$tfile-{0..100}
26185         sync
26186
26187         echo 2 > /proc/sys/vm/drop_caches
26188 }
26189 run_test 408 "drop_caches should not hang due to page leaks"
26190
26191 test_409()
26192 {
26193         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26194
26195         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26196         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26197         touch $DIR/$tdir/guard || error "(2) Fail to create"
26198
26199         local PREFIX=$(str_repeat 'A' 128)
26200         echo "Create 1K hard links start at $(date)"
26201         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26202                 error "(3) Fail to hard link"
26203
26204         echo "Links count should be right although linkEA overflow"
26205         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26206         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26207         [ $linkcount -eq 1001 ] ||
26208                 error "(5) Unexpected hard links count: $linkcount"
26209
26210         echo "List all links start at $(date)"
26211         ls -l $DIR/$tdir/foo > /dev/null ||
26212                 error "(6) Fail to list $DIR/$tdir/foo"
26213
26214         echo "Unlink hard links start at $(date)"
26215         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26216                 error "(7) Fail to unlink"
26217         echo "Unlink hard links finished at $(date)"
26218 }
26219 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26220
26221 test_410()
26222 {
26223         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26224                 skip "Need client version at least 2.9.59"
26225         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26226                 skip "Need MODULES build"
26227
26228         # Create a file, and stat it from the kernel
26229         local testfile=$DIR/$tfile
26230         touch $testfile
26231
26232         local run_id=$RANDOM
26233         local my_ino=$(stat --format "%i" $testfile)
26234
26235         # Try to insert the module. This will always fail as the
26236         # module is designed to not be inserted.
26237         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26238             &> /dev/null
26239
26240         # Anything but success is a test failure
26241         dmesg | grep -q \
26242             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26243             error "no inode match"
26244 }
26245 run_test 410 "Test inode number returned from kernel thread"
26246
26247 cleanup_test411_cgroup() {
26248         trap 0
26249         rmdir "$1"
26250 }
26251
26252 test_411() {
26253         local cg_basedir=/sys/fs/cgroup/memory
26254         # LU-9966
26255         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26256                 skip "no setup for cgroup"
26257
26258         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26259                 error "test file creation failed"
26260         cancel_lru_locks osc
26261
26262         # Create a very small memory cgroup to force a slab allocation error
26263         local cgdir=$cg_basedir/osc_slab_alloc
26264         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26265         trap "cleanup_test411_cgroup $cgdir" EXIT
26266         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26267         echo 1M > $cgdir/memory.limit_in_bytes
26268
26269         # Should not LBUG, just be killed by oom-killer
26270         # dd will return 0 even allocation failure in some environment.
26271         # So don't check return value
26272         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26273         cleanup_test411_cgroup $cgdir
26274
26275         return 0
26276 }
26277 run_test 411 "Slab allocation error with cgroup does not LBUG"
26278
26279 test_412() {
26280         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26281         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26282                 skip "Need server version at least 2.10.55"
26283
26284         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26285                 error "mkdir failed"
26286         $LFS getdirstripe $DIR/$tdir
26287         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26288         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26289                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26290         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26291         [ $stripe_count -eq 2 ] ||
26292                 error "expect 2 get $stripe_count"
26293
26294         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26295
26296         local index
26297         local index2
26298
26299         # subdirs should be on the same MDT as parent
26300         for i in $(seq 0 $((MDSCOUNT - 1))); do
26301                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26302                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26303                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26304                 (( index == i )) || error "mdt$i/sub on MDT$index"
26305         done
26306
26307         # stripe offset -1, ditto
26308         for i in {1..10}; do
26309                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26310                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26311                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26312                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26313                 (( index == index2 )) ||
26314                         error "qos$i on MDT$index, sub on MDT$index2"
26315         done
26316
26317         local testdir=$DIR/$tdir/inherit
26318
26319         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26320         # inherit 2 levels
26321         for i in 1 2; do
26322                 testdir=$testdir/s$i
26323                 mkdir $testdir || error "mkdir $testdir failed"
26324                 index=$($LFS getstripe -m $testdir)
26325                 (( index == 1 )) ||
26326                         error "$testdir on MDT$index"
26327         done
26328
26329         # not inherit any more
26330         testdir=$testdir/s3
26331         mkdir $testdir || error "mkdir $testdir failed"
26332         getfattr -d -m dmv $testdir | grep dmv &&
26333                 error "default LMV set on $testdir" || true
26334 }
26335 run_test 412 "mkdir on specific MDTs"
26336
26337 TEST413_COUNT=${TEST413_COUNT:-200}
26338
26339 #
26340 # set_maxage() is used by test_413 only.
26341 # This is a helper function to set maxage. Does not return any value.
26342 # Input: maxage to set
26343 #
26344 set_maxage() {
26345         local lmv_qos_maxage
26346         local lod_qos_maxage
26347         local new_maxage=$1
26348
26349         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26350         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26351         stack_trap "$LCTL set_param \
26352                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26353         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26354                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26355         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26356                 lod.*.mdt_qos_maxage=$new_maxage
26357         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26358                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26359 }
26360
26361 generate_uneven_mdts() {
26362         local threshold=$1
26363         local ffree
26364         local bavail
26365         local max
26366         local min
26367         local max_index
26368         local min_index
26369         local tmp
26370         local i
26371
26372         echo
26373         echo "Check for uneven MDTs: "
26374
26375         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26376         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26377         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26378
26379         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26380         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26381         max_index=0
26382         min_index=0
26383         for ((i = 1; i < ${#ffree[@]}; i++)); do
26384                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26385                 if [ $tmp -gt $max ]; then
26386                         max=$tmp
26387                         max_index=$i
26388                 fi
26389                 if [ $tmp -lt $min ]; then
26390                         min=$tmp
26391                         min_index=$i
26392                 fi
26393         done
26394
26395         (( min > 0 )) || skip "low space on MDT$min_index"
26396         (( ${ffree[min_index]} > 0 )) ||
26397                 skip "no free files on MDT$min_index"
26398         (( ${ffree[min_index]} < 10000000 )) ||
26399                 skip "too many free files on MDT$min_index"
26400
26401         # Check if we need to generate uneven MDTs
26402         local diff=$(((max - min) * 100 / min))
26403         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26404         local testdir # individual folder within $testdirp
26405         local start
26406         local cmd
26407
26408         # fallocate is faster to consume space on MDT, if available
26409         if check_fallocate_supported mds$((min_index + 1)); then
26410                 cmd="fallocate -l 128K "
26411         else
26412                 cmd="dd if=/dev/zero bs=128K count=1 of="
26413         fi
26414
26415         echo "using cmd $cmd"
26416         for (( i = 0; diff < threshold; i++ )); do
26417                 testdir=${testdirp}/$i
26418                 [ -d $testdir ] && continue
26419
26420                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26421
26422                 mkdir -p $testdirp
26423                 # generate uneven MDTs, create till $threshold% diff
26424                 echo -n "weight diff=$diff% must be > $threshold% ..."
26425                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26426                 $LFS mkdir -i $min_index $testdir ||
26427                         error "mkdir $testdir failed"
26428                 $LFS setstripe -E 1M -L mdt $testdir ||
26429                         error "setstripe $testdir failed"
26430                 start=$SECONDS
26431                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26432                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26433                 done
26434                 sync; sleep 1; sync
26435
26436                 # wait for QOS to update
26437                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26438
26439                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26440                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26441                 max=$(((${ffree[max_index]} >> 8) *
26442                         (${bavail[max_index]} * bsize >> 16)))
26443                 min=$(((${ffree[min_index]} >> 8) *
26444                         (${bavail[min_index]} * bsize >> 16)))
26445                 (( min > 0 )) || skip "low space on MDT$min_index"
26446                 diff=$(((max - min) * 100 / min))
26447         done
26448
26449         echo "MDT filesfree available: ${ffree[*]}"
26450         echo "MDT blocks available: ${bavail[*]}"
26451         echo "weight diff=$diff%"
26452 }
26453
26454 test_qos_mkdir() {
26455         local mkdir_cmd=$1
26456         local stripe_count=$2
26457         local mdts=$(comma_list $(mdts_nodes))
26458
26459         local testdir
26460         local lmv_qos_prio_free
26461         local lmv_qos_threshold_rr
26462         local lod_qos_prio_free
26463         local lod_qos_threshold_rr
26464         local total
26465         local count
26466         local i
26467
26468         # @total is total directories created if it's testing plain
26469         # directories, otherwise it's total stripe object count for
26470         # striped directories test.
26471         # remote/striped directory unlinking is slow on zfs and may
26472         # timeout, test with fewer directories
26473         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26474
26475         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26476         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26477         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26478                 head -n1)
26479         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26480         stack_trap "$LCTL set_param \
26481                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26482         stack_trap "$LCTL set_param \
26483                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26484
26485         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26486                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26487         lod_qos_prio_free=${lod_qos_prio_free%%%}
26488         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26489                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26490         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26491         stack_trap "do_nodes $mdts $LCTL set_param \
26492                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26493         stack_trap "do_nodes $mdts $LCTL set_param \
26494                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26495
26496         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26497         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26498
26499         testdir=$DIR/$tdir-s$stripe_count/rr
26500
26501         local stripe_index=$($LFS getstripe -m $testdir)
26502         local test_mkdir_rr=true
26503
26504         getfattr -d -m dmv -e hex $testdir | grep dmv
26505         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26506                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26507                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26508                         test_mkdir_rr=false
26509         fi
26510
26511         echo
26512         $test_mkdir_rr &&
26513                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26514                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26515
26516         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26517         for (( i = 0; i < total / stripe_count; i++ )); do
26518                 eval $mkdir_cmd $testdir/subdir$i ||
26519                         error "$mkdir_cmd subdir$i failed"
26520         done
26521
26522         for (( i = 0; i < $MDSCOUNT; i++ )); do
26523                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26524                 echo "$count directories created on MDT$i"
26525                 if $test_mkdir_rr; then
26526                         (( count == total / stripe_count / MDSCOUNT )) ||
26527                                 error "subdirs are not evenly distributed"
26528                 elif (( i == stripe_index )); then
26529                         (( count == total / stripe_count )) ||
26530                                 error "$count subdirs created on MDT$i"
26531                 else
26532                         (( count == 0 )) ||
26533                                 error "$count subdirs created on MDT$i"
26534                 fi
26535
26536                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26537                         count=$($LFS getdirstripe $testdir/* |
26538                                 grep -c -P "^\s+$i\t")
26539                         echo "$count stripes created on MDT$i"
26540                         # deviation should < 5% of average
26541                         delta=$((count - total / MDSCOUNT))
26542                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26543                                 error "stripes are not evenly distributed"
26544                 fi
26545         done
26546
26547         echo
26548         echo "Check for uneven MDTs: "
26549
26550         local ffree
26551         local bavail
26552         local max
26553         local min
26554         local max_index
26555         local min_index
26556         local tmp
26557
26558         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26559         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26560         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26561
26562         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26563         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26564         max_index=0
26565         min_index=0
26566         for ((i = 1; i < ${#ffree[@]}; i++)); do
26567                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26568                 if [ $tmp -gt $max ]; then
26569                         max=$tmp
26570                         max_index=$i
26571                 fi
26572                 if [ $tmp -lt $min ]; then
26573                         min=$tmp
26574                         min_index=$i
26575                 fi
26576         done
26577         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26578
26579         (( min > 0 )) || skip "low space on MDT$min_index"
26580         (( ${ffree[min_index]} < 10000000 )) ||
26581                 skip "too many free files on MDT$min_index"
26582
26583         generate_uneven_mdts 120
26584
26585         echo "MDT filesfree available: ${ffree[*]}"
26586         echo "MDT blocks available: ${bavail[*]}"
26587         echo "weight diff=$(((max - min) * 100 / min))%"
26588         echo
26589         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26590
26591         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26592         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26593         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26594         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26595         # decrease statfs age, so that it can be updated in time
26596         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26597         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26598
26599         sleep 1
26600
26601         testdir=$DIR/$tdir-s$stripe_count/qos
26602
26603         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26604         for (( i = 0; i < total / stripe_count; i++ )); do
26605                 eval $mkdir_cmd $testdir/subdir$i ||
26606                         error "$mkdir_cmd subdir$i failed"
26607         done
26608
26609         max=0
26610         for (( i = 0; i < $MDSCOUNT; i++ )); do
26611                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26612                 (( count > max )) && max=$count
26613                 echo "$count directories created on MDT$i : curmax=$max"
26614         done
26615
26616         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26617
26618         # D-value should > 10% of average
26619         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26620                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26621
26622         # ditto for stripes
26623         if (( stripe_count > 1 )); then
26624                 max=0
26625                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26626                         count=$($LFS getdirstripe $testdir/* |
26627                                 grep -c -P "^\s+$i\t")
26628                         (( count > max )) && max=$count
26629                         echo "$count stripes created on MDT$i"
26630                 done
26631
26632                 min=$($LFS getdirstripe $testdir/* |
26633                         grep -c -P "^\s+$min_index\t")
26634                 (( max - min > total / MDSCOUNT / 10 )) ||
26635                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26636         fi
26637 }
26638
26639 most_full_mdt() {
26640         local ffree
26641         local bavail
26642         local bsize
26643         local min
26644         local min_index
26645         local tmp
26646
26647         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26648         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26649         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26650
26651         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26652         min_index=0
26653         for ((i = 1; i < ${#ffree[@]}; i++)); do
26654                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26655                 (( tmp < min )) && min=$tmp && min_index=$i
26656         done
26657
26658         echo -n $min_index
26659 }
26660
26661 test_413a() {
26662         [ $MDSCOUNT -lt 2 ] &&
26663                 skip "We need at least 2 MDTs for this test"
26664
26665         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26666                 skip "Need server version at least 2.12.52"
26667
26668         local stripe_max=$((MDSCOUNT - 1))
26669         local stripe_count
26670
26671         # let caller set maxage for latest result
26672         set_maxage 1
26673
26674         # fill MDT unevenly
26675         generate_uneven_mdts 120
26676
26677         # test 4-stripe directory at most, otherwise it's too slow
26678         # We are being very defensive. Although Autotest uses 4 MDTs.
26679         # We make sure stripe_max does not go over 4.
26680         (( stripe_max > 4 )) && stripe_max=4
26681         # unlinking striped directory is slow on zfs, and may timeout, only test
26682         # plain directory
26683         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26684         for stripe_count in $(seq 1 $stripe_max); do
26685                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26686                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26687                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26688                         error "mkdir failed"
26689                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26690         done
26691 }
26692 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26693
26694 test_413b() {
26695         [ $MDSCOUNT -lt 2 ] &&
26696                 skip "We need at least 2 MDTs for this test"
26697
26698         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26699                 skip "Need server version at least 2.12.52"
26700
26701         local stripe_max=$((MDSCOUNT - 1))
26702         local testdir
26703         local stripe_count
26704
26705         # let caller set maxage for latest result
26706         set_maxage 1
26707
26708         # fill MDT unevenly
26709         generate_uneven_mdts 120
26710
26711         # test 4-stripe directory at most, otherwise it's too slow
26712         # We are being very defensive. Although Autotest uses 4 MDTs.
26713         # We make sure stripe_max does not go over 4.
26714         (( stripe_max > 4 )) && stripe_max=4
26715         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26716         for stripe_count in $(seq 1 $stripe_max); do
26717                 testdir=$DIR/$tdir-s$stripe_count
26718                 mkdir $testdir || error "mkdir $testdir failed"
26719                 mkdir $testdir/rr || error "mkdir rr failed"
26720                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26721                         error "mkdir qos failed"
26722                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26723                         $testdir/rr || error "setdirstripe rr failed"
26724                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26725                         error "setdirstripe failed"
26726                 test_qos_mkdir "mkdir" $stripe_count
26727         done
26728 }
26729 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26730
26731 test_413c() {
26732         (( $MDSCOUNT >= 2 )) ||
26733                 skip "We need at least 2 MDTs for this test"
26734
26735         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26736                 skip "Need server version at least 2.14.51"
26737
26738         local testdir
26739         local inherit
26740         local inherit_rr
26741         local lmv_qos_maxage
26742         local lod_qos_maxage
26743
26744         # let caller set maxage for latest result
26745         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26746         $LCTL set_param lmv.*.qos_maxage=1
26747         stack_trap "$LCTL set_param \
26748                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26749         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26750                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26751         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26752                 lod.*.mdt_qos_maxage=1
26753         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26754                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26755
26756         # fill MDT unevenly
26757         generate_uneven_mdts 120
26758
26759         testdir=$DIR/${tdir}-s1
26760         mkdir $testdir || error "mkdir $testdir failed"
26761         mkdir $testdir/rr || error "mkdir rr failed"
26762         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26763         # default max_inherit is -1, default max_inherit_rr is 0
26764         $LFS setdirstripe -D -c 1 $testdir/rr ||
26765                 error "setdirstripe rr failed"
26766         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26767                 error "setdirstripe qos failed"
26768         test_qos_mkdir "mkdir" 1
26769
26770         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26771         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26772         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26773         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26774         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26775
26776         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26777         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26778         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26779         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26780         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26781         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26782         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26783                 error "level2 shouldn't have default LMV" || true
26784 }
26785 run_test 413c "mkdir with default LMV max inherit rr"
26786
26787 test_413d() {
26788         (( MDSCOUNT >= 2 )) ||
26789                 skip "We need at least 2 MDTs for this test"
26790
26791         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26792                 skip "Need server version at least 2.14.51"
26793
26794         local lmv_qos_threshold_rr
26795
26796         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26797                 head -n1)
26798         stack_trap "$LCTL set_param \
26799                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26800
26801         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26802         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26803         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26804                 error "$tdir shouldn't have default LMV"
26805         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26806                 error "mkdir sub failed"
26807
26808         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26809
26810         (( count == 100 )) || error "$count subdirs on MDT0"
26811 }
26812 run_test 413d "inherit ROOT default LMV"
26813
26814 test_413e() {
26815         (( MDSCOUNT >= 2 )) ||
26816                 skip "We need at least 2 MDTs for this test"
26817         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26818                 skip "Need server version at least 2.14.55"
26819
26820         local testdir=$DIR/$tdir
26821         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26822         local max_inherit
26823         local sub_max_inherit
26824
26825         mkdir -p $testdir || error "failed to create $testdir"
26826
26827         # set default max-inherit to -1 if stripe count is 0 or 1
26828         $LFS setdirstripe -D -c 1 $testdir ||
26829                 error "failed to set default LMV"
26830         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26831         (( max_inherit == -1 )) ||
26832                 error "wrong max_inherit value $max_inherit"
26833
26834         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26835         $LFS setdirstripe -D -c -1 $testdir ||
26836                 error "failed to set default LMV"
26837         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26838         (( max_inherit > 0 )) ||
26839                 error "wrong max_inherit value $max_inherit"
26840
26841         # and the subdir will decrease the max_inherit by 1
26842         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26843         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26844         (( sub_max_inherit == max_inherit - 1)) ||
26845                 error "wrong max-inherit of subdir $sub_max_inherit"
26846
26847         # check specified --max-inherit and warning message
26848         stack_trap "rm -f $tmpfile"
26849         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26850                 error "failed to set default LMV"
26851         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26852         (( max_inherit == -1 )) ||
26853                 error "wrong max_inherit value $max_inherit"
26854
26855         # check the warning messages
26856         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26857                 error "failed to detect warning string"
26858         fi
26859 }
26860 run_test 413e "check default max-inherit value"
26861
26862 test_fs_dmv_inherit()
26863 {
26864         local testdir=$DIR/$tdir
26865
26866         local count
26867         local inherit
26868         local inherit_rr
26869
26870         for i in 1 2 3; do
26871                 mkdir $testdir || error "mkdir $testdir failed"
26872                 count=$($LFS getdirstripe -D -c $testdir)
26873                 (( count == 1 )) ||
26874                         error "$testdir default LMV count mismatch $count != 1"
26875                 inherit=$($LFS getdirstripe -D -X $testdir)
26876                 (( inherit == 3 - i )) ||
26877                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26878                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26879                 (( inherit_rr == 3 - i )) ||
26880                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26881                 testdir=$testdir/sub
26882         done
26883
26884         mkdir $testdir || error "mkdir $testdir failed"
26885         count=$($LFS getdirstripe -D -c $testdir)
26886         (( count == 0 )) ||
26887                 error "$testdir default LMV count not zero: $count"
26888 }
26889
26890 test_413f() {
26891         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26892
26893         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26894                 skip "Need server version at least 2.14.55"
26895
26896         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26897                 error "dump $DIR default LMV failed"
26898         stack_trap "setfattr --restore=$TMP/dmv.ea"
26899
26900         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26901                 error "set $DIR default LMV failed"
26902
26903         test_fs_dmv_inherit
26904 }
26905 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26906
26907 test_413g() {
26908         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26909
26910         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26911         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26912                 error "dump $DIR default LMV failed"
26913         stack_trap "setfattr --restore=$TMP/dmv.ea"
26914
26915         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26916                 error "set $DIR default LMV failed"
26917
26918         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26919                 error "mount $MOUNT2 failed"
26920         stack_trap "umount_client $MOUNT2"
26921
26922         local saved_DIR=$DIR
26923
26924         export DIR=$MOUNT2
26925
26926         stack_trap "export DIR=$saved_DIR"
26927
26928         # first check filesystem-wide default LMV inheritance
26929         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26930
26931         # then check subdirs are spread to all MDTs
26932         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26933
26934         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26935
26936         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26937 }
26938 run_test 413g "enforce ROOT default LMV on subdir mount"
26939
26940 test_413h() {
26941         (( MDSCOUNT >= 2 )) ||
26942                 skip "We need at least 2 MDTs for this test"
26943
26944         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26945                 skip "Need server version at least 2.15.50.6"
26946
26947         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26948
26949         stack_trap "$LCTL set_param \
26950                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26951         $LCTL set_param lmv.*.qos_maxage=1
26952
26953         local depth=5
26954         local rr_depth=4
26955         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26956         local count=$((MDSCOUNT * 20))
26957
26958         generate_uneven_mdts 50
26959
26960         mkdir -p $dir || error "mkdir $dir failed"
26961         stack_trap "rm -rf $dir"
26962         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26963                 --max-inherit-rr=$rr_depth $dir
26964
26965         for ((d=0; d < depth + 2; d++)); do
26966                 log "dir=$dir:"
26967                 for ((sub=0; sub < count; sub++)); do
26968                         mkdir $dir/d$sub
26969                 done
26970                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26971                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26972                 # subdirs within $rr_depth should be created round-robin
26973                 if (( d < rr_depth )); then
26974                         (( ${num[0]} != count )) ||
26975                                 error "all objects created on MDT ${num[1]}"
26976                 fi
26977
26978                 dir=$dir/d0
26979         done
26980 }
26981 run_test 413h "don't stick to parent for round-robin dirs"
26982
26983 test_413z() {
26984         local pids=""
26985         local subdir
26986         local pid
26987
26988         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26989                 unlinkmany $subdir/f. $TEST413_COUNT &
26990                 pids="$pids $!"
26991         done
26992
26993         for pid in $pids; do
26994                 wait $pid
26995         done
26996
26997         true
26998 }
26999 run_test 413z "413 test cleanup"
27000
27001 test_414() {
27002 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27003         $LCTL set_param fail_loc=0x80000521
27004         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27005         rm -f $DIR/$tfile
27006 }
27007 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27008
27009 test_415() {
27010         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27011         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27012                 skip "Need server version at least 2.11.52"
27013
27014         # LU-11102
27015         local total=500
27016         local max=120
27017
27018         # this test may be slow on ZFS
27019         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27020
27021         # though this test is designed for striped directory, let's test normal
27022         # directory too since lock is always saved as CoS lock.
27023         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27024         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27025         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27026         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27027         wait_delete_completed_mds
27028
27029         # run a loop without concurrent touch to measure rename duration.
27030         # only for test debug/robustness, NOT part of COS functional test.
27031         local start_time=$SECONDS
27032         for ((i = 0; i < total; i++)); do
27033                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27034                         > /dev/null
27035         done
27036         local baseline=$((SECONDS - start_time))
27037         echo "rename $total files without 'touch' took $baseline sec"
27038
27039         (
27040                 while true; do
27041                         touch $DIR/$tdir
27042                 done
27043         ) &
27044         local setattr_pid=$!
27045
27046         # rename files back to original name so unlinkmany works
27047         start_time=$SECONDS
27048         for ((i = 0; i < total; i++)); do
27049                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27050                         > /dev/null
27051         done
27052         local duration=$((SECONDS - start_time))
27053
27054         kill -9 $setattr_pid
27055
27056         echo "rename $total files with 'touch' took $duration sec"
27057         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27058         (( duration <= max )) || error "rename took $duration > $max sec"
27059 }
27060 run_test 415 "lock revoke is not missing"
27061
27062 test_416() {
27063         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27064                 skip "Need server version at least 2.11.55"
27065
27066         # define OBD_FAIL_OSD_TXN_START    0x19a
27067         do_facet mds1 lctl set_param fail_loc=0x19a
27068
27069         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27070
27071         true
27072 }
27073 run_test 416 "transaction start failure won't cause system hung"
27074
27075 cleanup_417() {
27076         trap 0
27077         do_nodes $(comma_list $(mdts_nodes)) \
27078                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27079         do_nodes $(comma_list $(mdts_nodes)) \
27080                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27081         do_nodes $(comma_list $(mdts_nodes)) \
27082                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27083 }
27084
27085 test_417() {
27086         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27087         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27088                 skip "Need MDS version at least 2.11.56"
27089
27090         trap cleanup_417 RETURN EXIT
27091
27092         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27093         do_nodes $(comma_list $(mdts_nodes)) \
27094                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27095         $LFS migrate -m 0 $DIR/$tdir.1 &&
27096                 error "migrate dir $tdir.1 should fail"
27097
27098         do_nodes $(comma_list $(mdts_nodes)) \
27099                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27100         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27101                 error "create remote dir $tdir.2 should fail"
27102
27103         do_nodes $(comma_list $(mdts_nodes)) \
27104                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27105         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27106                 error "create striped dir $tdir.3 should fail"
27107         true
27108 }
27109 run_test 417 "disable remote dir, striped dir and dir migration"
27110
27111 # Checks that the outputs of df [-i] and lfs df [-i] match
27112 #
27113 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27114 check_lfs_df() {
27115         local dir=$2
27116         local inodes
27117         local df_out
27118         local lfs_df_out
27119         local count
27120         local passed=false
27121
27122         # blocks or inodes
27123         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27124
27125         for count in {1..100}; do
27126                 do_nodes "$CLIENTS" \
27127                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27128                 sync; sleep 0.2
27129
27130                 # read the lines of interest
27131                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27132                         error "df $inodes $dir | tail -n +2 failed"
27133                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27134                         error "lfs df $inodes $dir | grep summary: failed"
27135
27136                 # skip first substrings of each output as they are different
27137                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27138                 # compare the two outputs
27139                 passed=true
27140                 #  skip "available" on MDT until LU-13997 is fixed.
27141                 #for i in {1..5}; do
27142                 for i in 1 2 4 5; do
27143                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27144                 done
27145                 $passed && break
27146         done
27147
27148         if ! $passed; then
27149                 df -P $inodes $dir
27150                 echo
27151                 lfs df $inodes $dir
27152                 error "df and lfs df $1 output mismatch: "      \
27153                       "df ${inodes}: ${df_out[*]}, "            \
27154                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27155         fi
27156 }
27157
27158 test_418() {
27159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27160
27161         local dir=$DIR/$tdir
27162         local numfiles=$((RANDOM % 4096 + 2))
27163         local numblocks=$((RANDOM % 256 + 1))
27164
27165         wait_delete_completed
27166         test_mkdir $dir
27167
27168         # check block output
27169         check_lfs_df blocks $dir
27170         # check inode output
27171         check_lfs_df inodes $dir
27172
27173         # create a single file and retest
27174         echo "Creating a single file and testing"
27175         createmany -o $dir/$tfile- 1 &>/dev/null ||
27176                 error "creating 1 file in $dir failed"
27177         check_lfs_df blocks $dir
27178         check_lfs_df inodes $dir
27179
27180         # create a random number of files
27181         echo "Creating $((numfiles - 1)) files and testing"
27182         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27183                 error "creating $((numfiles - 1)) files in $dir failed"
27184
27185         # write a random number of blocks to the first test file
27186         echo "Writing $numblocks 4K blocks and testing"
27187         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27188                 count=$numblocks &>/dev/null ||
27189                 error "dd to $dir/${tfile}-0 failed"
27190
27191         # retest
27192         check_lfs_df blocks $dir
27193         check_lfs_df inodes $dir
27194
27195         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27196                 error "unlinking $numfiles files in $dir failed"
27197 }
27198 run_test 418 "df and lfs df outputs match"
27199
27200 test_419()
27201 {
27202         local dir=$DIR/$tdir
27203
27204         mkdir -p $dir
27205         touch $dir/file
27206
27207         cancel_lru_locks mdc
27208
27209         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27210         $LCTL set_param fail_loc=0x1410
27211         cat $dir/file
27212         $LCTL set_param fail_loc=0
27213         rm -rf $dir
27214 }
27215 run_test 419 "Verify open file by name doesn't crash kernel"
27216
27217 test_420()
27218 {
27219         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27220                 skip "Need MDS version at least 2.12.53"
27221
27222         local SAVE_UMASK=$(umask)
27223         local dir=$DIR/$tdir
27224         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27225
27226         mkdir -p $dir
27227         umask 0000
27228         mkdir -m03777 $dir/testdir
27229         ls -dn $dir/testdir
27230         # Need to remove trailing '.' when SELinux is enabled
27231         local dirperms=$(ls -dn $dir/testdir |
27232                          awk '{ sub(/\.$/, "", $1); print $1}')
27233         [ $dirperms == "drwxrwsrwt" ] ||
27234                 error "incorrect perms on $dir/testdir"
27235
27236         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27237                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27238         ls -n $dir/testdir/testfile
27239         local fileperms=$(ls -n $dir/testdir/testfile |
27240                           awk '{ sub(/\.$/, "", $1); print $1}')
27241         [ $fileperms == "-rwxr-xr-x" ] ||
27242                 error "incorrect perms on $dir/testdir/testfile"
27243
27244         umask $SAVE_UMASK
27245 }
27246 run_test 420 "clear SGID bit on non-directories for non-members"
27247
27248 test_421a() {
27249         local cnt
27250         local fid1
27251         local fid2
27252
27253         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27254                 skip "Need MDS version at least 2.12.54"
27255
27256         test_mkdir $DIR/$tdir
27257         createmany -o $DIR/$tdir/f 3
27258         cnt=$(ls -1 $DIR/$tdir | wc -l)
27259         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27260
27261         fid1=$(lfs path2fid $DIR/$tdir/f1)
27262         fid2=$(lfs path2fid $DIR/$tdir/f2)
27263         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27264
27265         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27266         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27267
27268         cnt=$(ls -1 $DIR/$tdir | wc -l)
27269         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27270
27271         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27272         createmany -o $DIR/$tdir/f 3
27273         cnt=$(ls -1 $DIR/$tdir | wc -l)
27274         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27275
27276         fid1=$(lfs path2fid $DIR/$tdir/f1)
27277         fid2=$(lfs path2fid $DIR/$tdir/f2)
27278         echo "remove using fsname $FSNAME"
27279         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27280
27281         cnt=$(ls -1 $DIR/$tdir | wc -l)
27282         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27283 }
27284 run_test 421a "simple rm by fid"
27285
27286 test_421b() {
27287         local cnt
27288         local FID1
27289         local FID2
27290
27291         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27292                 skip "Need MDS version at least 2.12.54"
27293
27294         test_mkdir $DIR/$tdir
27295         createmany -o $DIR/$tdir/f 3
27296         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27297         MULTIPID=$!
27298
27299         FID1=$(lfs path2fid $DIR/$tdir/f1)
27300         FID2=$(lfs path2fid $DIR/$tdir/f2)
27301         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27302
27303         kill -USR1 $MULTIPID
27304         wait
27305
27306         cnt=$(ls $DIR/$tdir | wc -l)
27307         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27308 }
27309 run_test 421b "rm by fid on open file"
27310
27311 test_421c() {
27312         local cnt
27313         local FIDS
27314
27315         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27316                 skip "Need MDS version at least 2.12.54"
27317
27318         test_mkdir $DIR/$tdir
27319         createmany -o $DIR/$tdir/f 3
27320         touch $DIR/$tdir/$tfile
27321         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27322         cnt=$(ls -1 $DIR/$tdir | wc -l)
27323         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27324
27325         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27326         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27327
27328         cnt=$(ls $DIR/$tdir | wc -l)
27329         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27330 }
27331 run_test 421c "rm by fid against hardlinked files"
27332
27333 test_421d() {
27334         local cnt
27335         local FIDS
27336
27337         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27338                 skip "Need MDS version at least 2.12.54"
27339
27340         test_mkdir $DIR/$tdir
27341         createmany -o $DIR/$tdir/f 4097
27342         cnt=$(ls -1 $DIR/$tdir | wc -l)
27343         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27344
27345         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27346         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27347
27348         cnt=$(ls $DIR/$tdir | wc -l)
27349         rm -rf $DIR/$tdir
27350         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27351 }
27352 run_test 421d "rmfid en masse"
27353
27354 test_421e() {
27355         local cnt
27356         local FID
27357
27358         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27359         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27360                 skip "Need MDS version at least 2.12.54"
27361
27362         mkdir -p $DIR/$tdir
27363         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27364         createmany -o $DIR/$tdir/striped_dir/f 512
27365         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27366         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27367
27368         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27369                 sed "s/[/][^:]*://g")
27370         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27371
27372         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27373         rm -rf $DIR/$tdir
27374         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27375 }
27376 run_test 421e "rmfid in DNE"
27377
27378 test_421f() {
27379         local cnt
27380         local FID
27381
27382         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27383                 skip "Need MDS version at least 2.12.54"
27384
27385         test_mkdir $DIR/$tdir
27386         touch $DIR/$tdir/f
27387         cnt=$(ls -1 $DIR/$tdir | wc -l)
27388         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27389
27390         FID=$(lfs path2fid $DIR/$tdir/f)
27391         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27392         # rmfid should fail
27393         cnt=$(ls -1 $DIR/$tdir | wc -l)
27394         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27395
27396         chmod a+rw $DIR/$tdir
27397         ls -la $DIR/$tdir
27398         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27399         # rmfid should fail
27400         cnt=$(ls -1 $DIR/$tdir | wc -l)
27401         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27402
27403         rm -f $DIR/$tdir/f
27404         $RUNAS touch $DIR/$tdir/f
27405         FID=$(lfs path2fid $DIR/$tdir/f)
27406         echo "rmfid as root"
27407         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27408         cnt=$(ls -1 $DIR/$tdir | wc -l)
27409         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27410
27411         rm -f $DIR/$tdir/f
27412         $RUNAS touch $DIR/$tdir/f
27413         cnt=$(ls -1 $DIR/$tdir | wc -l)
27414         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27415         FID=$(lfs path2fid $DIR/$tdir/f)
27416         # rmfid w/o user_fid2path mount option should fail
27417         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27418         cnt=$(ls -1 $DIR/$tdir | wc -l)
27419         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27420
27421         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27422         stack_trap "rmdir $tmpdir"
27423         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27424                 error "failed to mount client'"
27425         stack_trap "umount_client $tmpdir"
27426
27427         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27428         # rmfid should succeed
27429         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27430         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27431
27432         # rmfid shouldn't allow to remove files due to dir's permission
27433         chmod a+rwx $tmpdir/$tdir
27434         touch $tmpdir/$tdir/f
27435         ls -la $tmpdir/$tdir
27436         FID=$(lfs path2fid $tmpdir/$tdir/f)
27437         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27438         return 0
27439 }
27440 run_test 421f "rmfid checks permissions"
27441
27442 test_421g() {
27443         local cnt
27444         local FIDS
27445
27446         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27447         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27448                 skip "Need MDS version at least 2.12.54"
27449
27450         mkdir -p $DIR/$tdir
27451         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27452         createmany -o $DIR/$tdir/striped_dir/f 512
27453         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27454         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27455
27456         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27457                 sed "s/[/][^:]*://g")
27458
27459         rm -f $DIR/$tdir/striped_dir/f1*
27460         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27461         removed=$((512 - cnt))
27462
27463         # few files have been just removed, so we expect
27464         # rmfid to fail on their fids
27465         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27466         [ $removed != $errors ] && error "$errors != $removed"
27467
27468         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27469         rm -rf $DIR/$tdir
27470         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27471 }
27472 run_test 421g "rmfid to return errors properly"
27473
27474 test_421h() {
27475         local mount_other
27476         local mount_ret
27477         local rmfid_ret
27478         local old_fid
27479         local fidA
27480         local fidB
27481         local fidC
27482         local fidD
27483
27484         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27485                 skip "Need MDS version at least 2.15.53"
27486
27487         test_mkdir $DIR/$tdir
27488         test_mkdir $DIR/$tdir/subdir
27489         touch $DIR/$tdir/subdir/file0
27490         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27491         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27492         rm -f $DIR/$tdir/subdir/file0
27493         touch $DIR/$tdir/subdir/fileA
27494         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27495         echo File $DIR/$tdir/subdir/fileA FID $fidA
27496         touch $DIR/$tdir/subdir/fileB
27497         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27498         echo File $DIR/$tdir/subdir/fileB FID $fidB
27499         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27500         touch $DIR/$tdir/subdir/fileC
27501         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27502         echo File $DIR/$tdir/subdir/fileC FID $fidC
27503         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27504         touch $DIR/$tdir/fileD
27505         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27506         echo File $DIR/$tdir/fileD FID $fidD
27507
27508         # mount another client mount point with subdirectory mount
27509         export FILESET=/$tdir/subdir
27510         mount_other=${MOUNT}_other
27511         mount_client $mount_other ${MOUNT_OPTS}
27512         mount_ret=$?
27513         export FILESET=""
27514         (( mount_ret == 0 )) || error "mount $mount_other failed"
27515
27516         echo Removing FIDs:
27517         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27518         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27519         rmfid_ret=$?
27520
27521         umount_client $mount_other || error "umount $mount_other failed"
27522
27523         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27524
27525         # fileA should have been deleted
27526         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27527
27528         # fileB should have been deleted
27529         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27530
27531         # fileC should not have been deleted, fid also exists outside of fileset
27532         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27533
27534         # fileD should not have been deleted, it exists outside of fileset
27535         stat $DIR/$tdir/fileD || error "fileD deleted"
27536 }
27537 run_test 421h "rmfid with fileset mount"
27538
27539 test_422() {
27540         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27541         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27542         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27543         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27544         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27545
27546         local amc=$(at_max_get client)
27547         local amo=$(at_max_get mds1)
27548         local timeout=`lctl get_param -n timeout`
27549
27550         at_max_set 0 client
27551         at_max_set 0 mds1
27552
27553 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27554         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27555                         fail_val=$(((2*timeout + 10)*1000))
27556         touch $DIR/$tdir/d3/file &
27557         sleep 2
27558 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27559         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27560                         fail_val=$((2*timeout + 5))
27561         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27562         local pid=$!
27563         sleep 1
27564         kill -9 $pid
27565         sleep $((2 * timeout))
27566         echo kill $pid
27567         kill -9 $pid
27568         lctl mark touch
27569         touch $DIR/$tdir/d2/file3
27570         touch $DIR/$tdir/d2/file4
27571         touch $DIR/$tdir/d2/file5
27572
27573         wait
27574         at_max_set $amc client
27575         at_max_set $amo mds1
27576
27577         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27578         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27579                 error "Watchdog is always throttled"
27580 }
27581 run_test 422 "kill a process with RPC in progress"
27582
27583 stat_test() {
27584     df -h $MOUNT &
27585     df -h $MOUNT &
27586     df -h $MOUNT &
27587     df -h $MOUNT &
27588     df -h $MOUNT &
27589     df -h $MOUNT &
27590 }
27591
27592 test_423() {
27593     local _stats
27594     # ensure statfs cache is expired
27595     sleep 2;
27596
27597     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27598     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27599
27600     return 0
27601 }
27602 run_test 423 "statfs should return a right data"
27603
27604 test_424() {
27605 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27606         $LCTL set_param fail_loc=0x80000522
27607         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27608         rm -f $DIR/$tfile
27609 }
27610 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27611
27612 test_425() {
27613         test_mkdir -c -1 $DIR/$tdir
27614         $LFS setstripe -c -1 $DIR/$tdir
27615
27616         lru_resize_disable "" 100
27617         stack_trap "lru_resize_enable" EXIT
27618
27619         sleep 5
27620
27621         for i in $(seq $((MDSCOUNT * 125))); do
27622                 local t=$DIR/$tdir/$tfile_$i
27623
27624                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27625                         error_noexit "Create file $t"
27626         done
27627         stack_trap "rm -rf $DIR/$tdir" EXIT
27628
27629         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27630                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27631                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27632
27633                 [ $lock_count -le $lru_size ] ||
27634                         error "osc lock count $lock_count > lru size $lru_size"
27635         done
27636
27637         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27638                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27639                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27640
27641                 [ $lock_count -le $lru_size ] ||
27642                         error "mdc lock count $lock_count > lru size $lru_size"
27643         done
27644 }
27645 run_test 425 "lock count should not exceed lru size"
27646
27647 test_426() {
27648         splice-test -r $DIR/$tfile
27649         splice-test -rd $DIR/$tfile
27650         splice-test $DIR/$tfile
27651         splice-test -d $DIR/$tfile
27652 }
27653 run_test 426 "splice test on Lustre"
27654
27655 test_427() {
27656         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27657         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27658                 skip "Need MDS version at least 2.12.4"
27659         local log
27660
27661         mkdir $DIR/$tdir
27662         mkdir $DIR/$tdir/1
27663         mkdir $DIR/$tdir/2
27664         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27665         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27666
27667         $LFS getdirstripe $DIR/$tdir/1/dir
27668
27669         #first setfattr for creating updatelog
27670         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27671
27672 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27673         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27674         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27675         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27676
27677         sleep 2
27678         fail mds2
27679         wait_recovery_complete mds2 $((2*TIMEOUT))
27680
27681         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27682         echo $log | grep "get update log failed" &&
27683                 error "update log corruption is detected" || true
27684 }
27685 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27686
27687 test_428() {
27688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27689         local cache_limit=$CACHE_MAX
27690
27691         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27692         $LCTL set_param -n llite.*.max_cached_mb=64
27693
27694         mkdir $DIR/$tdir
27695         $LFS setstripe -c 1 $DIR/$tdir
27696         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27697         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27698         #test write
27699         for f in $(seq 4); do
27700                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27701         done
27702         wait
27703
27704         cancel_lru_locks osc
27705         # Test read
27706         for f in $(seq 4); do
27707                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27708         done
27709         wait
27710 }
27711 run_test 428 "large block size IO should not hang"
27712
27713 test_429() { # LU-7915 / LU-10948
27714         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27715         local testfile=$DIR/$tfile
27716         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27717         local new_flag=1
27718         local first_rpc
27719         local second_rpc
27720         local third_rpc
27721
27722         $LCTL get_param $ll_opencache_threshold_count ||
27723                 skip "client does not have opencache parameter"
27724
27725         set_opencache $new_flag
27726         stack_trap "restore_opencache"
27727         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27728                 error "enable opencache failed"
27729         touch $testfile
27730         # drop MDC DLM locks
27731         cancel_lru_locks mdc
27732         # clear MDC RPC stats counters
27733         $LCTL set_param $mdc_rpcstats=clear
27734
27735         # According to the current implementation, we need to run 3 times
27736         # open & close file to verify if opencache is enabled correctly.
27737         # 1st, RPCs are sent for lookup/open and open handle is released on
27738         #      close finally.
27739         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27740         #      so open handle won't be released thereafter.
27741         # 3rd, No RPC is sent out.
27742         $MULTIOP $testfile oc || error "multiop failed"
27743         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27744         echo "1st: $first_rpc RPCs in flight"
27745
27746         $MULTIOP $testfile oc || error "multiop failed"
27747         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27748         echo "2nd: $second_rpc RPCs in flight"
27749
27750         $MULTIOP $testfile oc || error "multiop failed"
27751         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27752         echo "3rd: $third_rpc RPCs in flight"
27753
27754         #verify no MDC RPC is sent
27755         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27756 }
27757 run_test 429 "verify if opencache flag on client side does work"
27758
27759 lseek_test_430() {
27760         local offset
27761         local file=$1
27762
27763         # data at [200K, 400K)
27764         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27765                 error "256K->512K dd fails"
27766         # data at [2M, 3M)
27767         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27768                 error "2M->3M dd fails"
27769         # data at [4M, 5M)
27770         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27771                 error "4M->5M dd fails"
27772         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27773         # start at first component hole #1
27774         printf "Seeking hole from 1000 ... "
27775         offset=$(lseek_test -l 1000 $file)
27776         echo $offset
27777         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27778         printf "Seeking data from 1000 ... "
27779         offset=$(lseek_test -d 1000 $file)
27780         echo $offset
27781         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27782
27783         # start at first component data block
27784         printf "Seeking hole from 300000 ... "
27785         offset=$(lseek_test -l 300000 $file)
27786         echo $offset
27787         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27788         printf "Seeking data from 300000 ... "
27789         offset=$(lseek_test -d 300000 $file)
27790         echo $offset
27791         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27792
27793         # start at the first component but beyond end of object size
27794         printf "Seeking hole from 1000000 ... "
27795         offset=$(lseek_test -l 1000000 $file)
27796         echo $offset
27797         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27798         printf "Seeking data from 1000000 ... "
27799         offset=$(lseek_test -d 1000000 $file)
27800         echo $offset
27801         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27802
27803         # start at second component stripe 2 (empty file)
27804         printf "Seeking hole from 1500000 ... "
27805         offset=$(lseek_test -l 1500000 $file)
27806         echo $offset
27807         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27808         printf "Seeking data from 1500000 ... "
27809         offset=$(lseek_test -d 1500000 $file)
27810         echo $offset
27811         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27812
27813         # start at second component stripe 1 (all data)
27814         printf "Seeking hole from 3000000 ... "
27815         offset=$(lseek_test -l 3000000 $file)
27816         echo $offset
27817         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27818         printf "Seeking data from 3000000 ... "
27819         offset=$(lseek_test -d 3000000 $file)
27820         echo $offset
27821         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27822
27823         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27824                 error "2nd dd fails"
27825         echo "Add data block at 640K...1280K"
27826
27827         # start at before new data block, in hole
27828         printf "Seeking hole from 600000 ... "
27829         offset=$(lseek_test -l 600000 $file)
27830         echo $offset
27831         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27832         printf "Seeking data from 600000 ... "
27833         offset=$(lseek_test -d 600000 $file)
27834         echo $offset
27835         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27836
27837         # start at the first component new data block
27838         printf "Seeking hole from 1000000 ... "
27839         offset=$(lseek_test -l 1000000 $file)
27840         echo $offset
27841         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27842         printf "Seeking data from 1000000 ... "
27843         offset=$(lseek_test -d 1000000 $file)
27844         echo $offset
27845         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27846
27847         # start at second component stripe 2, new data
27848         printf "Seeking hole from 1200000 ... "
27849         offset=$(lseek_test -l 1200000 $file)
27850         echo $offset
27851         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27852         printf "Seeking data from 1200000 ... "
27853         offset=$(lseek_test -d 1200000 $file)
27854         echo $offset
27855         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27856
27857         # start beyond file end
27858         printf "Using offset > filesize ... "
27859         lseek_test -l 4000000 $file && error "lseek should fail"
27860         printf "Using offset > filesize ... "
27861         lseek_test -d 4000000 $file && error "lseek should fail"
27862
27863         printf "Done\n\n"
27864 }
27865
27866 test_430a() {
27867         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27868                 skip "MDT does not support SEEK_HOLE"
27869
27870         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27871                 skip "OST does not support SEEK_HOLE"
27872
27873         local file=$DIR/$tdir/$tfile
27874
27875         mkdir -p $DIR/$tdir
27876
27877         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27878         # OST stripe #1 will have continuous data at [1M, 3M)
27879         # OST stripe #2 is empty
27880         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27881         lseek_test_430 $file
27882         rm $file
27883         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27884         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27885         lseek_test_430 $file
27886         rm $file
27887         $LFS setstripe -c2 -S 512K $file
27888         echo "Two stripes, stripe size 512K"
27889         lseek_test_430 $file
27890         rm $file
27891         # FLR with stale mirror
27892         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27893                        -N -c2 -S 1M $file
27894         echo "Mirrored file:"
27895         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27896         echo "Plain 2 stripes 1M"
27897         lseek_test_430 $file
27898         rm $file
27899 }
27900 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27901
27902 test_430b() {
27903         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27904                 skip "OST does not support SEEK_HOLE"
27905
27906         local offset
27907         local file=$DIR/$tdir/$tfile
27908
27909         mkdir -p $DIR/$tdir
27910         # Empty layout lseek should fail
27911         $MCREATE $file
27912         # seek from 0
27913         printf "Seeking hole from 0 ... "
27914         lseek_test -l 0 $file && error "lseek should fail"
27915         printf "Seeking data from 0 ... "
27916         lseek_test -d 0 $file && error "lseek should fail"
27917         rm $file
27918
27919         # 1M-hole file
27920         $LFS setstripe -E 1M -c2 -E eof $file
27921         $TRUNCATE $file 1048576
27922         printf "Seeking hole from 1000000 ... "
27923         offset=$(lseek_test -l 1000000 $file)
27924         echo $offset
27925         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27926         printf "Seeking data from 1000000 ... "
27927         lseek_test -d 1000000 $file && error "lseek should fail"
27928         rm $file
27929
27930         # full component followed by non-inited one
27931         $LFS setstripe -E 1M -c2 -E eof $file
27932         dd if=/dev/urandom of=$file bs=1M count=1
27933         printf "Seeking hole from 1000000 ... "
27934         offset=$(lseek_test -l 1000000 $file)
27935         echo $offset
27936         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27937         printf "Seeking hole from 1048576 ... "
27938         lseek_test -l 1048576 $file && error "lseek should fail"
27939         # init second component and truncate back
27940         echo "123" >> $file
27941         $TRUNCATE $file 1048576
27942         printf "Seeking hole from 1000000 ... "
27943         offset=$(lseek_test -l 1000000 $file)
27944         echo $offset
27945         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27946         printf "Seeking hole from 1048576 ... "
27947         lseek_test -l 1048576 $file && error "lseek should fail"
27948         # boundary checks for big values
27949         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27950         offset=$(lseek_test -d 0 $file.10g)
27951         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27952         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27953         offset=$(lseek_test -d 0 $file.100g)
27954         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27955         return 0
27956 }
27957 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27958
27959 test_430c() {
27960         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27961                 skip "OST does not support SEEK_HOLE"
27962
27963         local file=$DIR/$tdir/$tfile
27964         local start
27965
27966         mkdir -p $DIR/$tdir
27967         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27968
27969         # cp version 8.33+ prefers lseek over fiemap
27970         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27971                 start=$SECONDS
27972                 time cp $file /dev/null
27973                 (( SECONDS - start < 5 )) ||
27974                         error "cp: too long runtime $((SECONDS - start))"
27975
27976         fi
27977         # tar version 1.29+ supports SEEK_HOLE/DATA
27978         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27979                 start=$SECONDS
27980                 time tar cS $file - | cat > /dev/null
27981                 (( SECONDS - start < 5 )) ||
27982                         error "tar: too long runtime $((SECONDS - start))"
27983         fi
27984 }
27985 run_test 430c "lseek: external tools check"
27986
27987 test_431() { # LU-14187
27988         local file=$DIR/$tdir/$tfile
27989
27990         mkdir -p $DIR/$tdir
27991         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27992         dd if=/dev/urandom of=$file bs=4k count=1
27993         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27994         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27995         #define OBD_FAIL_OST_RESTART_IO 0x251
27996         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27997         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27998         cp $file $file.0
27999         cancel_lru_locks
28000         sync_all_data
28001         echo 3 > /proc/sys/vm/drop_caches
28002         diff  $file $file.0 || error "data diff"
28003 }
28004 run_test 431 "Restart transaction for IO"
28005
28006 cleanup_test_432() {
28007         do_facet mgs $LCTL nodemap_activate 0
28008         wait_nm_sync active
28009 }
28010
28011 test_432() {
28012         local tmpdir=$TMP/dir432
28013
28014         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28015                 skip "Need MDS version at least 2.14.52"
28016
28017         stack_trap cleanup_test_432 EXIT
28018         mkdir $DIR/$tdir
28019         mkdir $tmpdir
28020
28021         do_facet mgs $LCTL nodemap_activate 1
28022         wait_nm_sync active
28023         do_facet mgs $LCTL nodemap_modify --name default \
28024                 --property admin --value 1
28025         do_facet mgs $LCTL nodemap_modify --name default \
28026                 --property trusted --value 1
28027         cancel_lru_locks mdc
28028         wait_nm_sync default admin_nodemap
28029         wait_nm_sync default trusted_nodemap
28030
28031         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28032                grep -ci "Operation not permitted") -ne 0 ]; then
28033                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28034         fi
28035 }
28036 run_test 432 "mv dir from outside Lustre"
28037
28038 test_433() {
28039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28040
28041         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28042                 skip "inode cache not supported"
28043
28044         $LCTL set_param llite.*.inode_cache=0
28045         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28046
28047         local count=256
28048         local before
28049         local after
28050
28051         cancel_lru_locks mdc
28052         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28053         createmany -m $DIR/$tdir/f $count
28054         createmany -d $DIR/$tdir/d $count
28055         ls -l $DIR/$tdir > /dev/null
28056         stack_trap "rm -rf $DIR/$tdir"
28057
28058         before=$(num_objects)
28059         cancel_lru_locks mdc
28060         after=$(num_objects)
28061
28062         # sometimes even @before is less than 2 * count
28063         while (( before - after < count )); do
28064                 sleep 1
28065                 after=$(num_objects)
28066                 wait=$((wait + 1))
28067                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28068                 if (( wait > 60 )); then
28069                         error "inode slab grew from $before to $after"
28070                 fi
28071         done
28072
28073         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28074 }
28075 run_test 433 "ldlm lock cancel releases dentries and inodes"
28076
28077 test_434() {
28078         local file
28079         local getxattr_count
28080         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28082
28083         [[ $(getenforce) == "Disabled" ]] ||
28084                 skip "lsm selinux module have to be disabled for this test"
28085
28086         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28087                 error "fail to create $DIR/$tdir/ on MDT0000"
28088
28089         touch $DIR/$tdir/$tfile-{001..100}
28090
28091         # disable the xattr cache
28092         save_lustre_params client "llite.*.xattr_cache" > $p
28093         lctl set_param llite.*.xattr_cache=0
28094         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28095
28096         # clear clients mdc stats
28097         clear_stats $mdc_stat_param ||
28098                 error "fail to clear stats on mdc MDT0000"
28099
28100         for file in $DIR/$tdir/$tfile-{001..100}; do
28101                 getfattr -n security.selinux $file |&
28102                         grep -q "Operation not supported" ||
28103                         error "getxattr on security.selinux should return EOPNOTSUPP"
28104         done
28105
28106         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28107         (( getxattr_count < 100 )) ||
28108                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28109 }
28110 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28111
28112 test_440() {
28113         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28114                 source $LUSTRE/scripts/bash-completion/lustre
28115         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28116                 source /usr/share/bash-completion/completions/lustre
28117         else
28118                 skip "bash completion scripts not found"
28119         fi
28120
28121         local lctl_completions
28122         local lfs_completions
28123
28124         lctl_completions=$(_lustre_cmds lctl)
28125         if [[ ! $lctl_completions =~ "get_param" ]]; then
28126                 error "lctl bash completion failed"
28127         fi
28128
28129         lfs_completions=$(_lustre_cmds lfs)
28130         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28131                 error "lfs bash completion failed"
28132         fi
28133 }
28134 run_test 440 "bash completion for lfs, lctl"
28135
28136 prep_801() {
28137         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28138         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28139                 skip "Need server version at least 2.9.55"
28140
28141         start_full_debug_logging
28142 }
28143
28144 post_801() {
28145         stop_full_debug_logging
28146 }
28147
28148 barrier_stat() {
28149         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28150                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28151                            awk '/The barrier for/ { print $7 }')
28152                 echo $st
28153         else
28154                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28155                 echo \'$st\'
28156         fi
28157 }
28158
28159 barrier_expired() {
28160         local expired
28161
28162         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28163                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28164                           awk '/will be expired/ { print $7 }')
28165         else
28166                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28167         fi
28168
28169         echo $expired
28170 }
28171
28172 test_801a() {
28173         prep_801
28174
28175         echo "Start barrier_freeze at: $(date)"
28176         #define OBD_FAIL_BARRIER_DELAY          0x2202
28177         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28178         # Do not reduce barrier time - See LU-11873
28179         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28180
28181         sleep 2
28182         local b_status=$(barrier_stat)
28183         echo "Got barrier status at: $(date)"
28184         [ "$b_status" = "'freezing_p1'" ] ||
28185                 error "(1) unexpected barrier status $b_status"
28186
28187         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28188         wait
28189         b_status=$(barrier_stat)
28190         [ "$b_status" = "'frozen'" ] ||
28191                 error "(2) unexpected barrier status $b_status"
28192
28193         local expired=$(barrier_expired)
28194         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28195         sleep $((expired + 3))
28196
28197         b_status=$(barrier_stat)
28198         [ "$b_status" = "'expired'" ] ||
28199                 error "(3) unexpected barrier status $b_status"
28200
28201         # Do not reduce barrier time - See LU-11873
28202         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28203                 error "(4) fail to freeze barrier"
28204
28205         b_status=$(barrier_stat)
28206         [ "$b_status" = "'frozen'" ] ||
28207                 error "(5) unexpected barrier status $b_status"
28208
28209         echo "Start barrier_thaw at: $(date)"
28210         #define OBD_FAIL_BARRIER_DELAY          0x2202
28211         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28212         do_facet mgs $LCTL barrier_thaw $FSNAME &
28213
28214         sleep 2
28215         b_status=$(barrier_stat)
28216         echo "Got barrier status at: $(date)"
28217         [ "$b_status" = "'thawing'" ] ||
28218                 error "(6) unexpected barrier status $b_status"
28219
28220         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28221         wait
28222         b_status=$(barrier_stat)
28223         [ "$b_status" = "'thawed'" ] ||
28224                 error "(7) unexpected barrier status $b_status"
28225
28226         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28227         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28228         do_facet mgs $LCTL barrier_freeze $FSNAME
28229
28230         b_status=$(barrier_stat)
28231         [ "$b_status" = "'failed'" ] ||
28232                 error "(8) unexpected barrier status $b_status"
28233
28234         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28235         do_facet mgs $LCTL barrier_thaw $FSNAME
28236
28237         post_801
28238 }
28239 run_test 801a "write barrier user interfaces and stat machine"
28240
28241 test_801b() {
28242         prep_801
28243
28244         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28245         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28246         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28247         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28248         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28249
28250         cancel_lru_locks mdc
28251
28252         # 180 seconds should be long enough
28253         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28254
28255         local b_status=$(barrier_stat)
28256         [ "$b_status" = "'frozen'" ] ||
28257                 error "(6) unexpected barrier status $b_status"
28258
28259         mkdir $DIR/$tdir/d0/d10 &
28260         mkdir_pid=$!
28261
28262         touch $DIR/$tdir/d1/f13 &
28263         touch_pid=$!
28264
28265         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28266         ln_pid=$!
28267
28268         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28269         mv_pid=$!
28270
28271         rm -f $DIR/$tdir/d4/f12 &
28272         rm_pid=$!
28273
28274         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28275
28276         # To guarantee taht the 'stat' is not blocked
28277         b_status=$(barrier_stat)
28278         [ "$b_status" = "'frozen'" ] ||
28279                 error "(8) unexpected barrier status $b_status"
28280
28281         # let above commands to run at background
28282         sleep 5
28283
28284         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28285         ps -p $touch_pid || error "(10) touch should be blocked"
28286         ps -p $ln_pid || error "(11) link should be blocked"
28287         ps -p $mv_pid || error "(12) rename should be blocked"
28288         ps -p $rm_pid || error "(13) unlink should be blocked"
28289
28290         b_status=$(barrier_stat)
28291         [ "$b_status" = "'frozen'" ] ||
28292                 error "(14) unexpected barrier status $b_status"
28293
28294         do_facet mgs $LCTL barrier_thaw $FSNAME
28295         b_status=$(barrier_stat)
28296         [ "$b_status" = "'thawed'" ] ||
28297                 error "(15) unexpected barrier status $b_status"
28298
28299         wait $mkdir_pid || error "(16) mkdir should succeed"
28300         wait $touch_pid || error "(17) touch should succeed"
28301         wait $ln_pid || error "(18) link should succeed"
28302         wait $mv_pid || error "(19) rename should succeed"
28303         wait $rm_pid || error "(20) unlink should succeed"
28304
28305         post_801
28306 }
28307 run_test 801b "modification will be blocked by write barrier"
28308
28309 test_801c() {
28310         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28311
28312         prep_801
28313
28314         stop mds2 || error "(1) Fail to stop mds2"
28315
28316         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28317
28318         local b_status=$(barrier_stat)
28319         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28320                 do_facet mgs $LCTL barrier_thaw $FSNAME
28321                 error "(2) unexpected barrier status $b_status"
28322         }
28323
28324         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28325                 error "(3) Fail to rescan barrier bitmap"
28326
28327         # Do not reduce barrier time - See LU-11873
28328         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28329
28330         b_status=$(barrier_stat)
28331         [ "$b_status" = "'frozen'" ] ||
28332                 error "(4) unexpected barrier status $b_status"
28333
28334         do_facet mgs $LCTL barrier_thaw $FSNAME
28335         b_status=$(barrier_stat)
28336         [ "$b_status" = "'thawed'" ] ||
28337                 error "(5) unexpected barrier status $b_status"
28338
28339         local devname=$(mdsdevname 2)
28340
28341         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28342
28343         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28344                 error "(7) Fail to rescan barrier bitmap"
28345
28346         post_801
28347 }
28348 run_test 801c "rescan barrier bitmap"
28349
28350 test_802b() {
28351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28352         remote_mds_nodsh && skip "remote MDS with nodsh"
28353
28354         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28355                 skip "readonly option not available"
28356
28357         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28358
28359         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28360                 error "(2) Fail to copy"
28361
28362         # write back all cached data before setting MDT to readonly
28363         cancel_lru_locks
28364         sync_all_data
28365
28366         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28367         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28368
28369         echo "Modify should be refused"
28370         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28371
28372         echo "Read should be allowed"
28373         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28374                 error "(7) Read should succeed under ro mode"
28375
28376         # disable readonly
28377         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28378 }
28379 run_test 802b "be able to set MDTs to readonly"
28380
28381 test_803a() {
28382         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28383         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28384                 skip "MDS needs to be newer than 2.10.54"
28385
28386         mkdir_on_mdt0 $DIR/$tdir
28387         # Create some objects on all MDTs to trigger related logs objects
28388         for idx in $(seq $MDSCOUNT); do
28389                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28390                         $DIR/$tdir/dir${idx} ||
28391                         error "Fail to create $DIR/$tdir/dir${idx}"
28392         done
28393
28394         wait_delete_completed # ensure old test cleanups are finished
28395         sleep 3
28396         echo "before create:"
28397         $LFS df -i $MOUNT
28398         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28399
28400         for i in {1..10}; do
28401                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28402                         error "Fail to create $DIR/$tdir/foo$i"
28403         done
28404
28405         # sync ZFS-on-MDS to refresh statfs data
28406         wait_zfs_commit mds1
28407         sleep 3
28408         echo "after create:"
28409         $LFS df -i $MOUNT
28410         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28411
28412         # allow for an llog to be cleaned up during the test
28413         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28414                 error "before ($before_used) + 10 > after ($after_used)"
28415
28416         for i in {1..10}; do
28417                 rm -rf $DIR/$tdir/foo$i ||
28418                         error "Fail to remove $DIR/$tdir/foo$i"
28419         done
28420
28421         # sync ZFS-on-MDS to refresh statfs data
28422         wait_zfs_commit mds1
28423         wait_delete_completed
28424         sleep 3 # avoid MDT return cached statfs
28425         echo "after unlink:"
28426         $LFS df -i $MOUNT
28427         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28428
28429         # allow for an llog to be created during the test
28430         [ $after_used -le $((before_used + 1)) ] ||
28431                 error "after ($after_used) > before ($before_used) + 1"
28432 }
28433 run_test 803a "verify agent object for remote object"
28434
28435 test_803b() {
28436         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28437         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28438                 skip "MDS needs to be newer than 2.13.56"
28439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28440
28441         for i in $(seq 0 $((MDSCOUNT - 1))); do
28442                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28443         done
28444
28445         local before=0
28446         local after=0
28447
28448         local tmp
28449
28450         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28451         for i in $(seq 0 $((MDSCOUNT - 1))); do
28452                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28453                         awk '/getattr/ { print $2 }')
28454                 before=$((before + tmp))
28455         done
28456         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28457         for i in $(seq 0 $((MDSCOUNT - 1))); do
28458                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28459                         awk '/getattr/ { print $2 }')
28460                 after=$((after + tmp))
28461         done
28462
28463         [ $before -eq $after ] || error "getattr count $before != $after"
28464 }
28465 run_test 803b "remote object can getattr from cache"
28466
28467 test_804() {
28468         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28469         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28470                 skip "MDS needs to be newer than 2.10.54"
28471         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28472
28473         mkdir -p $DIR/$tdir
28474         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28475                 error "Fail to create $DIR/$tdir/dir0"
28476
28477         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28478         local dev=$(mdsdevname 2)
28479
28480         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28481                 grep ${fid} || error "NOT found agent entry for dir0"
28482
28483         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28484                 error "Fail to create $DIR/$tdir/dir1"
28485
28486         touch $DIR/$tdir/dir1/foo0 ||
28487                 error "Fail to create $DIR/$tdir/dir1/foo0"
28488         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28489         local rc=0
28490
28491         for idx in $(seq $MDSCOUNT); do
28492                 dev=$(mdsdevname $idx)
28493                 do_facet mds${idx} \
28494                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28495                         grep ${fid} && rc=$idx
28496         done
28497
28498         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28499                 error "Fail to rename foo0 to foo1"
28500         if [ $rc -eq 0 ]; then
28501                 for idx in $(seq $MDSCOUNT); do
28502                         dev=$(mdsdevname $idx)
28503                         do_facet mds${idx} \
28504                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28505                         grep ${fid} && rc=$idx
28506                 done
28507         fi
28508
28509         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28510                 error "Fail to rename foo1 to foo2"
28511         if [ $rc -eq 0 ]; then
28512                 for idx in $(seq $MDSCOUNT); do
28513                         dev=$(mdsdevname $idx)
28514                         do_facet mds${idx} \
28515                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28516                         grep ${fid} && rc=$idx
28517                 done
28518         fi
28519
28520         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28521
28522         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28523                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28524         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28525                 error "Fail to rename foo2 to foo0"
28526         unlink $DIR/$tdir/dir1/foo0 ||
28527                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28528         rm -rf $DIR/$tdir/dir0 ||
28529                 error "Fail to rm $DIR/$tdir/dir0"
28530
28531         for idx in $(seq $MDSCOUNT); do
28532                 rc=0
28533
28534                 stop mds${idx}
28535                 dev=$(mdsdevname $idx)
28536                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28537                         rc=$?
28538                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28539                         error "mount mds$idx failed"
28540                 df $MOUNT > /dev/null 2>&1
28541
28542                 # e2fsck should not return error
28543                 [ $rc -eq 0 ] ||
28544                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28545         done
28546 }
28547 run_test 804 "verify agent entry for remote entry"
28548
28549 cleanup_805() {
28550         do_facet $SINGLEMDS zfs set quota=$old $fsset
28551         unlinkmany $DIR/$tdir/f- 1000000
28552         trap 0
28553 }
28554
28555 test_805() {
28556         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28557         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28558         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28559                 skip "netfree not implemented before 0.7"
28560         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28561                 skip "Need MDS version at least 2.10.57"
28562
28563         local fsset
28564         local freekb
28565         local usedkb
28566         local old
28567         local quota
28568         local pref="osd-zfs.$FSNAME-MDT0000."
28569
28570         # limit available space on MDS dataset to meet nospace issue
28571         # quickly. then ZFS 0.7.2 can use reserved space if asked
28572         # properly (using netfree flag in osd_declare_destroy()
28573         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28574         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28575                 gawk '{print $3}')
28576         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28577         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28578         let "usedkb=usedkb-freekb"
28579         let "freekb=freekb/2"
28580         if let "freekb > 5000"; then
28581                 let "freekb=5000"
28582         fi
28583         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28584         trap cleanup_805 EXIT
28585         mkdir_on_mdt0 $DIR/$tdir
28586         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28587                 error "Can't set PFL layout"
28588         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28589         rm -rf $DIR/$tdir || error "not able to remove"
28590         do_facet $SINGLEMDS zfs set quota=$old $fsset
28591         trap 0
28592 }
28593 run_test 805 "ZFS can remove from full fs"
28594
28595 # Size-on-MDS test
28596 check_lsom_data()
28597 {
28598         local file=$1
28599         local expect=$(stat -c %s $file)
28600
28601         check_lsom_size $1 $expect
28602
28603         local blocks=$($LFS getsom -b $file)
28604         expect=$(stat -c %b $file)
28605         [[ $blocks == $expect ]] ||
28606                 error "$file expected blocks: $expect, got: $blocks"
28607 }
28608
28609 check_lsom_size()
28610 {
28611         local size
28612         local expect=$2
28613
28614         cancel_lru_locks mdc
28615
28616         size=$($LFS getsom -s $1)
28617         [[ $size == $expect ]] ||
28618                 error "$file expected size: $expect, got: $size"
28619 }
28620
28621 test_806() {
28622         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28623                 skip "Need MDS version at least 2.11.52"
28624
28625         local bs=1048576
28626
28627         touch $DIR/$tfile || error "touch $tfile failed"
28628
28629         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28630         save_lustre_params client "llite.*.xattr_cache" > $save
28631         lctl set_param llite.*.xattr_cache=0
28632         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28633
28634         # single-threaded write
28635         echo "Test SOM for single-threaded write"
28636         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28637                 error "write $tfile failed"
28638         check_lsom_size $DIR/$tfile $bs
28639
28640         local num=32
28641         local size=$(($num * $bs))
28642         local offset=0
28643         local i
28644
28645         echo "Test SOM for single client multi-threaded($num) write"
28646         $TRUNCATE $DIR/$tfile 0
28647         for ((i = 0; i < $num; i++)); do
28648                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28649                 local pids[$i]=$!
28650                 offset=$((offset + $bs))
28651         done
28652         for (( i=0; i < $num; i++ )); do
28653                 wait ${pids[$i]}
28654         done
28655         check_lsom_size $DIR/$tfile $size
28656
28657         $TRUNCATE $DIR/$tfile 0
28658         for ((i = 0; i < $num; i++)); do
28659                 offset=$((offset - $bs))
28660                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28661                 local pids[$i]=$!
28662         done
28663         for (( i=0; i < $num; i++ )); do
28664                 wait ${pids[$i]}
28665         done
28666         check_lsom_size $DIR/$tfile $size
28667
28668         # multi-client writes
28669         num=$(get_node_count ${CLIENTS//,/ })
28670         size=$(($num * $bs))
28671         offset=0
28672         i=0
28673
28674         echo "Test SOM for multi-client ($num) writes"
28675         $TRUNCATE $DIR/$tfile 0
28676         for client in ${CLIENTS//,/ }; do
28677                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28678                 local pids[$i]=$!
28679                 i=$((i + 1))
28680                 offset=$((offset + $bs))
28681         done
28682         for (( i=0; i < $num; i++ )); do
28683                 wait ${pids[$i]}
28684         done
28685         check_lsom_size $DIR/$tfile $offset
28686
28687         i=0
28688         $TRUNCATE $DIR/$tfile 0
28689         for client in ${CLIENTS//,/ }; do
28690                 offset=$((offset - $bs))
28691                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28692                 local pids[$i]=$!
28693                 i=$((i + 1))
28694         done
28695         for (( i=0; i < $num; i++ )); do
28696                 wait ${pids[$i]}
28697         done
28698         check_lsom_size $DIR/$tfile $size
28699
28700         # verify truncate
28701         echo "Test SOM for truncate"
28702         $TRUNCATE $DIR/$tfile 1048576
28703         check_lsom_size $DIR/$tfile 1048576
28704         $TRUNCATE $DIR/$tfile 1234
28705         check_lsom_size $DIR/$tfile 1234
28706
28707         # verify SOM blocks count
28708         echo "Verify SOM block count"
28709         $TRUNCATE $DIR/$tfile 0
28710         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28711                 error "failed to write file $tfile"
28712         check_lsom_data $DIR/$tfile
28713 }
28714 run_test 806 "Verify Lazy Size on MDS"
28715
28716 test_807() {
28717         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28718         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28719                 skip "Need MDS version at least 2.11.52"
28720
28721         # Registration step
28722         changelog_register || error "changelog_register failed"
28723         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28724         changelog_users $SINGLEMDS | grep -q $cl_user ||
28725                 error "User $cl_user not found in changelog_users"
28726
28727         rm -rf $DIR/$tdir || error "rm $tdir failed"
28728         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28729         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28730         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28731         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28732                 error "truncate $tdir/trunc failed"
28733
28734         local bs=1048576
28735         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28736                 error "write $tfile failed"
28737
28738         # multi-client wirtes
28739         local num=$(get_node_count ${CLIENTS//,/ })
28740         local offset=0
28741         local i=0
28742
28743         echo "Test SOM for multi-client ($num) writes"
28744         touch $DIR/$tfile || error "touch $tfile failed"
28745         $TRUNCATE $DIR/$tfile 0
28746         for client in ${CLIENTS//,/ }; do
28747                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28748                 local pids[$i]=$!
28749                 i=$((i + 1))
28750                 offset=$((offset + $bs))
28751         done
28752         for (( i=0; i < $num; i++ )); do
28753                 wait ${pids[$i]}
28754         done
28755
28756         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28757         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28758         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28759         check_lsom_data $DIR/$tdir/trunc
28760         check_lsom_data $DIR/$tdir/single_dd
28761         check_lsom_data $DIR/$tfile
28762
28763         rm -rf $DIR/$tdir
28764         # Deregistration step
28765         changelog_deregister || error "changelog_deregister failed"
28766 }
28767 run_test 807 "verify LSOM syncing tool"
28768
28769 check_som_nologged()
28770 {
28771         local lines=$($LFS changelog $FSNAME-MDT0000 |
28772                 grep 'x=trusted.som' | wc -l)
28773         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28774 }
28775
28776 test_808() {
28777         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28778                 skip "Need MDS version at least 2.11.55"
28779
28780         # Registration step
28781         changelog_register || error "changelog_register failed"
28782
28783         touch $DIR/$tfile || error "touch $tfile failed"
28784         check_som_nologged
28785
28786         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28787                 error "write $tfile failed"
28788         check_som_nologged
28789
28790         $TRUNCATE $DIR/$tfile 1234
28791         check_som_nologged
28792
28793         $TRUNCATE $DIR/$tfile 1048576
28794         check_som_nologged
28795
28796         # Deregistration step
28797         changelog_deregister || error "changelog_deregister failed"
28798 }
28799 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28800
28801 check_som_nodata()
28802 {
28803         $LFS getsom $1
28804         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28805 }
28806
28807 test_809() {
28808         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28809                 skip "Need MDS version at least 2.11.56"
28810
28811         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28812                 error "failed to create DoM-only file $DIR/$tfile"
28813         touch $DIR/$tfile || error "touch $tfile failed"
28814         check_som_nodata $DIR/$tfile
28815
28816         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28817                 error "write $tfile failed"
28818         check_som_nodata $DIR/$tfile
28819
28820         $TRUNCATE $DIR/$tfile 1234
28821         check_som_nodata $DIR/$tfile
28822
28823         $TRUNCATE $DIR/$tfile 4097
28824         check_som_nodata $DIR/$file
28825 }
28826 run_test 809 "Verify no SOM xattr store for DoM-only files"
28827
28828 test_810() {
28829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28830         $GSS && skip_env "could not run with gss"
28831         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28832                 skip "OST < 2.12.58 doesn't align checksum"
28833
28834         set_checksums 1
28835         stack_trap "set_checksums $ORIG_CSUM" EXIT
28836         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28837
28838         local csum
28839         local before
28840         local after
28841         for csum in $CKSUM_TYPES; do
28842                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28843                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28844                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28845                         eval set -- $i
28846                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28847                         before=$(md5sum $DIR/$tfile)
28848                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28849                         after=$(md5sum $DIR/$tfile)
28850                         [ "$before" == "$after" ] ||
28851                                 error "$csum: $before != $after bs=$1 seek=$2"
28852                 done
28853         done
28854 }
28855 run_test 810 "partial page writes on ZFS (LU-11663)"
28856
28857 test_812a() {
28858         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28859                 skip "OST < 2.12.51 doesn't support this fail_loc"
28860
28861         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28862         # ensure ost1 is connected
28863         stat $DIR/$tfile >/dev/null || error "can't stat"
28864         wait_osc_import_state client ost1 FULL
28865         # no locks, no reqs to let the connection idle
28866         cancel_lru_locks osc
28867
28868         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28869 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28870         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28871         wait_osc_import_state client ost1 CONNECTING
28872         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28873
28874         stat $DIR/$tfile >/dev/null || error "can't stat file"
28875 }
28876 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28877
28878 test_812b() { # LU-12378
28879         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28880                 skip "OST < 2.12.51 doesn't support this fail_loc"
28881
28882         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28883         # ensure ost1 is connected
28884         stat $DIR/$tfile >/dev/null || error "can't stat"
28885         wait_osc_import_state client ost1 FULL
28886         # no locks, no reqs to let the connection idle
28887         cancel_lru_locks osc
28888
28889         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28890 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28891         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28892         wait_osc_import_state client ost1 CONNECTING
28893         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28894
28895         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28896         wait_osc_import_state client ost1 IDLE
28897 }
28898 run_test 812b "do not drop no resend request for idle connect"
28899
28900 test_812c() {
28901         local old
28902
28903         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28904
28905         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28906         $LFS getstripe $DIR/$tfile
28907         $LCTL set_param osc.*.idle_timeout=10
28908         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28909         # ensure ost1 is connected
28910         stat $DIR/$tfile >/dev/null || error "can't stat"
28911         wait_osc_import_state client ost1 FULL
28912         # no locks, no reqs to let the connection idle
28913         cancel_lru_locks osc
28914
28915 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28916         $LCTL set_param fail_loc=0x80000533
28917         sleep 15
28918         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28919 }
28920 run_test 812c "idle import vs lock enqueue race"
28921
28922 test_813() {
28923         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28924         [ -z "$file_heat_sav" ] && skip "no file heat support"
28925
28926         local readsample
28927         local writesample
28928         local readbyte
28929         local writebyte
28930         local readsample1
28931         local writesample1
28932         local readbyte1
28933         local writebyte1
28934
28935         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28936         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28937
28938         $LCTL set_param -n llite.*.file_heat=1
28939         echo "Turn on file heat"
28940         echo "Period second: $period_second, Decay percentage: $decay_pct"
28941
28942         echo "QQQQ" > $DIR/$tfile
28943         echo "QQQQ" > $DIR/$tfile
28944         echo "QQQQ" > $DIR/$tfile
28945         cat $DIR/$tfile > /dev/null
28946         cat $DIR/$tfile > /dev/null
28947         cat $DIR/$tfile > /dev/null
28948         cat $DIR/$tfile > /dev/null
28949
28950         local out=$($LFS heat_get $DIR/$tfile)
28951
28952         $LFS heat_get $DIR/$tfile
28953         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28954         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28955         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28956         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28957
28958         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28959         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28960         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28961         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28962
28963         sleep $((period_second + 3))
28964         echo "Sleep $((period_second + 3)) seconds..."
28965         # The recursion formula to calculate the heat of the file f is as
28966         # follow:
28967         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28968         # Where Hi is the heat value in the period between time points i*I and
28969         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28970         # to the weight of Ci.
28971         out=$($LFS heat_get $DIR/$tfile)
28972         $LFS heat_get $DIR/$tfile
28973         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28974         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28975         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28976         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28977
28978         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28979                 error "read sample ($readsample) is wrong"
28980         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28981                 error "write sample ($writesample) is wrong"
28982         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28983                 error "read bytes ($readbyte) is wrong"
28984         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28985                 error "write bytes ($writebyte) is wrong"
28986
28987         echo "QQQQ" > $DIR/$tfile
28988         echo "QQQQ" > $DIR/$tfile
28989         echo "QQQQ" > $DIR/$tfile
28990         cat $DIR/$tfile > /dev/null
28991         cat $DIR/$tfile > /dev/null
28992         cat $DIR/$tfile > /dev/null
28993         cat $DIR/$tfile > /dev/null
28994
28995         sleep $((period_second + 3))
28996         echo "Sleep $((period_second + 3)) seconds..."
28997
28998         out=$($LFS heat_get $DIR/$tfile)
28999         $LFS heat_get $DIR/$tfile
29000         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29001         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29002         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29003         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29004
29005         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29006                 4 * $decay_pct) / 100") -eq 1 ] ||
29007                 error "read sample ($readsample1) is wrong"
29008         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29009                 3 * $decay_pct) / 100") -eq 1 ] ||
29010                 error "write sample ($writesample1) is wrong"
29011         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29012                 20 * $decay_pct) / 100") -eq 1 ] ||
29013                 error "read bytes ($readbyte1) is wrong"
29014         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29015                 15 * $decay_pct) / 100") -eq 1 ] ||
29016                 error "write bytes ($writebyte1) is wrong"
29017
29018         echo "Turn off file heat for the file $DIR/$tfile"
29019         $LFS heat_set -o $DIR/$tfile
29020
29021         echo "QQQQ" > $DIR/$tfile
29022         echo "QQQQ" > $DIR/$tfile
29023         echo "QQQQ" > $DIR/$tfile
29024         cat $DIR/$tfile > /dev/null
29025         cat $DIR/$tfile > /dev/null
29026         cat $DIR/$tfile > /dev/null
29027         cat $DIR/$tfile > /dev/null
29028
29029         out=$($LFS heat_get $DIR/$tfile)
29030         $LFS heat_get $DIR/$tfile
29031         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29032         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29033         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29034         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29035
29036         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29037         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29038         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29039         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29040
29041         echo "Trun on file heat for the file $DIR/$tfile"
29042         $LFS heat_set -O $DIR/$tfile
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         out=$($LFS heat_get $DIR/$tfile)
29053         $LFS heat_get $DIR/$tfile
29054         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29055         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29056         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29057         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29058
29059         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29060         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29061         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29062         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29063
29064         $LFS heat_set -c $DIR/$tfile
29065         $LCTL set_param -n llite.*.file_heat=0
29066         echo "Turn off file heat support for the Lustre filesystem"
29067
29068         echo "QQQQ" > $DIR/$tfile
29069         echo "QQQQ" > $DIR/$tfile
29070         echo "QQQQ" > $DIR/$tfile
29071         cat $DIR/$tfile > /dev/null
29072         cat $DIR/$tfile > /dev/null
29073         cat $DIR/$tfile > /dev/null
29074         cat $DIR/$tfile > /dev/null
29075
29076         out=$($LFS heat_get $DIR/$tfile)
29077         $LFS heat_get $DIR/$tfile
29078         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29079         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29080         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29081         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29082
29083         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29084         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29085         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29086         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29087
29088         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29089         rm -f $DIR/$tfile
29090 }
29091 run_test 813 "File heat verfication"
29092
29093 test_814()
29094 {
29095         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29096         echo -n y >> $DIR/$tfile
29097         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29098         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29099 }
29100 run_test 814 "sparse cp works as expected (LU-12361)"
29101
29102 test_815()
29103 {
29104         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29105         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29106 }
29107 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29108
29109 test_816() {
29110         local ost1_imp=$(get_osc_import_name client ost1)
29111         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29112                          cut -d'.' -f2)
29113
29114         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29115         # ensure ost1 is connected
29116
29117         stat $DIR/$tfile >/dev/null || error "can't stat"
29118         wait_osc_import_state client ost1 FULL
29119         # no locks, no reqs to let the connection idle
29120         cancel_lru_locks osc
29121         lru_resize_disable osc
29122         local before
29123         local now
29124         before=$($LCTL get_param -n \
29125                  ldlm.namespaces.$imp_name.lru_size)
29126
29127         wait_osc_import_state client ost1 IDLE
29128         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29129         now=$($LCTL get_param -n \
29130               ldlm.namespaces.$imp_name.lru_size)
29131         [ $before == $now ] || error "lru_size changed $before != $now"
29132 }
29133 run_test 816 "do not reset lru_resize on idle reconnect"
29134
29135 cleanup_817() {
29136         umount $tmpdir
29137         exportfs -u localhost:$DIR/nfsexp
29138         rm -rf $DIR/nfsexp
29139 }
29140
29141 test_817() {
29142         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29143
29144         mkdir -p $DIR/nfsexp
29145         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29146                 error "failed to export nfs"
29147
29148         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29149         stack_trap cleanup_817 EXIT
29150
29151         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29152                 error "failed to mount nfs to $tmpdir"
29153
29154         cp /bin/true $tmpdir
29155         $DIR/nfsexp/true || error "failed to execute 'true' command"
29156 }
29157 run_test 817 "nfsd won't cache write lock for exec file"
29158
29159 test_818() {
29160         test_mkdir -i0 -c1 $DIR/$tdir
29161         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29162         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29163         stop $SINGLEMDS
29164
29165         # restore osp-syn threads
29166         stack_trap "fail $SINGLEMDS"
29167
29168         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29169         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29170         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29171                 error "start $SINGLEMDS failed"
29172         rm -rf $DIR/$tdir
29173
29174         local testid=$(echo $TESTNAME | tr '_' ' ')
29175
29176         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29177                 grep "run LFSCK" || error "run LFSCK is not suggested"
29178 }
29179 run_test 818 "unlink with failed llog"
29180
29181 test_819a() {
29182         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29183         cancel_lru_locks osc
29184         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29185         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29186         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29187         rm -f $TDIR/$tfile
29188 }
29189 run_test 819a "too big niobuf in read"
29190
29191 test_819b() {
29192         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29193         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29195         cancel_lru_locks osc
29196         sleep 1
29197         rm -f $TDIR/$tfile
29198 }
29199 run_test 819b "too big niobuf in write"
29200
29201
29202 function test_820_start_ost() {
29203         sleep 5
29204
29205         for num in $(seq $OSTCOUNT); do
29206                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29207         done
29208 }
29209
29210 test_820() {
29211         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29212
29213         mkdir $DIR/$tdir
29214         umount_client $MOUNT || error "umount failed"
29215         for num in $(seq $OSTCOUNT); do
29216                 stop ost$num
29217         done
29218
29219         # mount client with no active OSTs
29220         # so that the client can't initialize max LOV EA size
29221         # from OSC notifications
29222         mount_client $MOUNT || error "mount failed"
29223         # delay OST starting to keep this 0 max EA size for a while
29224         test_820_start_ost &
29225
29226         # create a directory on MDS2
29227         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29228                 error "Failed to create directory"
29229         # open intent should update default EA size
29230         # see mdc_update_max_ea_from_body()
29231         # notice this is the very first RPC to MDS2
29232         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29233         ret=$?
29234         echo $out
29235         # With SSK, this situation can lead to -EPERM being returned.
29236         # In that case, simply retry.
29237         if [ $ret -ne 0 ] && $SHARED_KEY; then
29238                 if echo "$out" | grep -q "not permitted"; then
29239                         cp /etc/services $DIR/$tdir/mds2
29240                         ret=$?
29241                 fi
29242         fi
29243         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29244 }
29245 run_test 820 "update max EA from open intent"
29246
29247 test_823() {
29248         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29249         local OST_MAX_PRECREATE=20000
29250
29251         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29252                 skip "Need MDS version at least 2.14.56"
29253
29254         save_lustre_params mds1 \
29255                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29256         do_facet $SINGLEMDS "$LCTL set_param -n \
29257                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29258         do_facet $SINGLEMDS "$LCTL set_param -n \
29259                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29260
29261         stack_trap "restore_lustre_params < $p; rm $p"
29262
29263         do_facet $SINGLEMDS "$LCTL set_param -n \
29264                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29265
29266         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29267                       osp.$FSNAME-OST0000*MDT0000.create_count")
29268         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29269                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29270         local expect_count=$(((($max/2)/256) * 256))
29271
29272         log "setting create_count to 100200:"
29273         log " -result- count: $count with max: $max, expecting: $expect_count"
29274
29275         [[ $count -eq expect_count ]] ||
29276                 error "Create count not set to max precreate."
29277 }
29278 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29279
29280 test_831() {
29281         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29282                 skip "Need MDS version 2.14.56"
29283
29284         local sync_changes=$(do_facet $SINGLEMDS \
29285                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29286
29287         [ "$sync_changes" -gt 100 ] &&
29288                 skip "Sync changes $sync_changes > 100 already"
29289
29290         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29291
29292         $LFS mkdir -i 0 $DIR/$tdir
29293         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29294
29295         save_lustre_params mds1 \
29296                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29297         save_lustre_params mds1 \
29298                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29299
29300         do_facet mds1 "$LCTL set_param -n \
29301                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29302                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29303         stack_trap "restore_lustre_params < $p" EXIT
29304
29305         createmany -o $DIR/$tdir/f- 1000
29306         unlinkmany $DIR/$tdir/f- 1000 &
29307         local UNLINK_PID=$!
29308
29309         while sleep 1; do
29310                 sync_changes=$(do_facet mds1 \
29311                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29312                 # the check in the code is racy, fail the test
29313                 # if the value above the limit by 10.
29314                 [ $sync_changes -gt 110 ] && {
29315                         kill -2 $UNLINK_PID
29316                         wait
29317                         error "osp changes throttling failed, $sync_changes>110"
29318                 }
29319                 kill -0 $UNLINK_PID 2> /dev/null || break
29320         done
29321         wait
29322 }
29323 run_test 831 "throttling unlink/setattr queuing on OSP"
29324
29325 test_832() {
29326         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29327         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29328                 skip "Need MDS version 2.15.52+"
29329         is_rmentry_supported || skip "rm_entry not supported"
29330
29331         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29332         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29333         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29334                 error "mkdir remote_dir failed"
29335         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29336                 error "mkdir striped_dir failed"
29337         touch $DIR/$tdir/file || error "touch file failed"
29338         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29339         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29340 }
29341 run_test 832 "lfs rm_entry"
29342
29343 #
29344 # tests that do cleanup/setup should be run at the end
29345 #
29346
29347 test_900() {
29348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29349         local ls
29350
29351         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29352         $LCTL set_param fail_loc=0x903
29353
29354         cancel_lru_locks MGC
29355
29356         FAIL_ON_ERROR=true cleanup
29357         FAIL_ON_ERROR=true setup
29358 }
29359 run_test 900 "umount should not race with any mgc requeue thread"
29360
29361 # LUS-6253/LU-11185
29362 test_901() {
29363         local old
29364         local count
29365         local oldc
29366         local newc
29367         local olds
29368         local news
29369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29370
29371         # some get_param have a bug to handle dot in param name
29372         cancel_lru_locks MGC
29373         old=$(mount -t lustre | wc -l)
29374         # 1 config+sptlrpc
29375         # 2 params
29376         # 3 nodemap
29377         # 4 IR
29378         old=$((old * 4))
29379         oldc=0
29380         count=0
29381         while [ $old -ne $oldc ]; do
29382                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29383                 sleep 1
29384                 ((count++))
29385                 if [ $count -ge $TIMEOUT ]; then
29386                         error "too large timeout"
29387                 fi
29388         done
29389         umount_client $MOUNT || error "umount failed"
29390         mount_client $MOUNT || error "mount failed"
29391         cancel_lru_locks MGC
29392         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29393
29394         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29395
29396         return 0
29397 }
29398 run_test 901 "don't leak a mgc lock on client umount"
29399
29400 # LU-13377
29401 test_902() {
29402         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29403                 skip "client does not have LU-13377 fix"
29404         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29405         $LCTL set_param fail_loc=0x1415
29406         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29407         cancel_lru_locks osc
29408         rm -f $DIR/$tfile
29409 }
29410 run_test 902 "test short write doesn't hang lustre"
29411
29412 # LU-14711
29413 test_903() {
29414         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29415         echo "blah" > $DIR/${tfile}-2
29416         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29417         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29418         $LCTL set_param fail_loc=0x417 fail_val=20
29419
29420         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29421         sleep 1 # To start the destroy
29422         wait_destroy_complete 150 || error "Destroy taking too long"
29423         cat $DIR/$tfile > /dev/null || error "Evicted"
29424 }
29425 run_test 903 "Test long page discard does not cause evictions"
29426
29427 test_904() {
29428         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29429         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29430                 grep -q project || skip "skip project quota not supported"
29431
29432         local testfile="$DIR/$tdir/$tfile"
29433         local xattr="trusted.projid"
29434         local projid
29435         local mdts=$(comma_list $(mdts_nodes))
29436         local saved=$(do_facet mds1 $LCTL get_param -n \
29437                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29438
29439         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29440         stack_trap "do_nodes $mdts $LCTL set_param \
29441                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29442
29443         mkdir -p $DIR/$tdir
29444         touch $testfile
29445         #hide projid xattr on server
29446         $LFS project -p 1 $testfile ||
29447                 error "set $testfile project id failed"
29448         getfattr -m - $testfile | grep $xattr &&
29449                 error "do not show trusted.projid when disabled on server"
29450         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29451         #should be hidden when projid is 0
29452         $LFS project -p 0 $testfile ||
29453                 error "set $testfile project id failed"
29454         getfattr -m - $testfile | grep $xattr &&
29455                 error "do not show trusted.projid with project ID 0"
29456
29457         #still can getxattr explicitly
29458         projid=$(getfattr -n $xattr $testfile |
29459                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29460         [ $projid == "0" ] ||
29461                 error "projid expected 0 not $projid"
29462
29463         #set the projid via setxattr
29464         setfattr -n $xattr -v "1000" $testfile ||
29465                 error "setattr failed with $?"
29466         projid=($($LFS project $testfile))
29467         [ ${projid[0]} == "1000" ] ||
29468                 error "projid expected 1000 not $projid"
29469
29470         #check the new projid via getxattr
29471         $LFS project -p 1001 $testfile ||
29472                 error "set $testfile project id failed"
29473         getfattr -m - $testfile | grep $xattr ||
29474                 error "should show trusted.projid when project ID != 0"
29475         projid=$(getfattr -n $xattr $testfile |
29476                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29477         [ $projid == "1001" ] ||
29478                 error "projid expected 1001 not $projid"
29479
29480         #try to set invalid projid
29481         setfattr -n $xattr -v "4294967295" $testfile &&
29482                 error "set invalid projid should fail"
29483
29484         #remove the xattr means setting projid to 0
29485         setfattr -x $xattr $testfile ||
29486                 error "setfattr failed with $?"
29487         projid=($($LFS project $testfile))
29488         [ ${projid[0]} == "0" ] ||
29489                 error "projid expected 0 not $projid"
29490
29491         #should be hidden when parent has inherit flag and same projid
29492         $LFS project -srp 1002 $DIR/$tdir ||
29493                 error "set $tdir project id failed"
29494         getfattr -m - $testfile | grep $xattr &&
29495                 error "do not show trusted.projid with inherit flag"
29496
29497         #still can getxattr explicitly
29498         projid=$(getfattr -n $xattr $testfile |
29499                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29500         [ $projid == "1002" ] ||
29501                 error "projid expected 1002 not $projid"
29502 }
29503 run_test 904 "virtual project ID xattr"
29504
29505 # LU-8582
29506 test_905() {
29507         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29508                 skip "lustre < 2.8.54 does not support ladvise"
29509
29510         remote_ost_nodsh && skip "remote OST with nodsh"
29511         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29512
29513         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29514
29515         #define OBD_FAIL_OST_OPCODE 0x253
29516         # OST_LADVISE = 21
29517         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29518         $LFS ladvise -a willread $DIR/$tfile &&
29519                 error "unexpected success of ladvise with fault injection"
29520         $LFS ladvise -a willread $DIR/$tfile |&
29521                 grep -q "Operation not supported"
29522         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29523 }
29524 run_test 905 "bad or new opcode should not stuck client"
29525
29526 test_906() {
29527         grep -q io_uring_setup /proc/kallsyms ||
29528                 skip "Client OS does not support io_uring I/O engine"
29529         io_uring_probe || skip "kernel does not support io_uring fully"
29530         which fio || skip_env "no fio installed"
29531         fio --enghelp | grep -q io_uring ||
29532                 skip_env "fio does not support io_uring I/O engine"
29533
29534         local file=$DIR/$tfile
29535         local ioengine="io_uring"
29536         local numjobs=2
29537         local size=50M
29538
29539         fio --name=seqwrite --ioengine=$ioengine        \
29540                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29541                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29542                 error "fio seqwrite $file failed"
29543
29544         fio --name=seqread --ioengine=$ioengine \
29545                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29546                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29547                 error "fio seqread $file failed"
29548
29549         rm -f $file || error "rm -f $file failed"
29550 }
29551 run_test 906 "Simple test for io_uring I/O engine via fio"
29552
29553
29554 complete $SECONDS
29555 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29556 check_and_cleanup_lustre
29557 if [ "$I_MOUNTED" != "yes" ]; then
29558         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29559 fi
29560 exit_status