Whamcloud - gitweb
LU-16392 utils: use --list-commands for bash completion
[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 #                                  5              12     8   12  15   (min)"
66 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
67
68 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
69         #                                               13    (min)"
70         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
71 fi
72
73 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
74         always_except LU-1941 130b 130c 130d 130e 130f 130g
75         always_except LU-9054 312
76 fi
77
78 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
79
80 # Get the SLES distro version
81 #
82 # Returns a version string that should only be used in comparing
83 # strings returned by version_code()
84 sles_version_code()
85 {
86         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
87
88         # All SuSE Linux versions have one decimal. version_code expects two
89         local sles_version=$version.0
90         version_code $sles_version
91 }
92
93 # Check if we are running on Ubuntu or SLES so we can make decisions on
94 # what tests to run
95 if [ -r /etc/SuSE-release ]; then
96         sles_version=$(sles_version_code)
97         [ $sles_version -lt $(version_code 11.4.0) ] &&
98                 always_except LU-4341 170
99
100         [ $sles_version -lt $(version_code 12.0.0) ] &&
101                 always_except LU-3703 234
102 elif [ -r /etc/os-release ]; then
103         if grep -qi ubuntu /etc/os-release; then
104                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
105                                                 -e 's/^VERSION=//p' \
106                                                 /etc/os-release |
107                                                 awk '{ print $1 }'))
108
109                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
110                         always_except LU-10366 410
111                 fi
112         fi
113 fi
114
115 build_test_filter
116 FAIL_ON_ERROR=false
117
118 cleanup() {
119         echo -n "cln.."
120         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
121         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
122 }
123 setup() {
124         echo -n "mnt.."
125         load_modules
126         setupall || exit 10
127         echo "done"
128 }
129
130 check_swap_layouts_support()
131 {
132         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
133                 skip "Does not support layout lock."
134 }
135
136 check_swap_layout_no_dom()
137 {
138         local FOLDER=$1
139         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
140         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
141 }
142
143 check_and_setup_lustre
144 DIR=${DIR:-$MOUNT}
145 assert_DIR
146
147 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
148
149 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
150 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
151 rm -rf $DIR/[Rdfs][0-9]*
152
153 # $RUNAS_ID may get set incorrectly somewhere else
154 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
155         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
156
157 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
158
159 if [ "${ONLY}" = "MOUNT" ] ; then
160         echo "Lustre is up, please go on"
161         exit
162 fi
163
164 echo "preparing for tests involving mounts"
165 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
166 touch $EXT2_DEV
167 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
168 echo # add a newline after mke2fs.
169
170 umask 077
171
172 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
173 lctl set_param debug=-1 2> /dev/null || true
174 test_0a() {
175         touch $DIR/$tfile
176         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
177         rm $DIR/$tfile
178         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
179 }
180 run_test 0a "touch; rm ====================="
181
182 test_0b() {
183         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
184         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
185 }
186 run_test 0b "chmod 0755 $DIR ============================="
187
188 test_0c() {
189         $LCTL get_param mdc.*.import | grep "state: FULL" ||
190                 error "import not FULL"
191         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
192                 error "bad target"
193 }
194 run_test 0c "check import proc"
195
196 test_0d() { # LU-3397
197         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
198                 skip "proc exports not supported before 2.10.57"
199
200         local mgs_exp="mgs.MGS.exports"
201         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
202         local exp_client_nid
203         local exp_client_version
204         local exp_val
205         local imp_val
206         local temp_imp=$DIR/$tfile.import
207         local temp_exp=$DIR/$tfile.export
208
209         # save mgc import file to $temp_imp
210         $LCTL get_param mgc.*.import | tee $temp_imp
211         # Check if client uuid is found in MGS export
212         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
213                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
214                         $client_uuid ] &&
215                         break;
216         done
217         # save mgs export file to $temp_exp
218         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
219
220         # Compare the value of field "connect_flags"
221         imp_val=$(grep "connect_flags" $temp_imp)
222         exp_val=$(grep "connect_flags" $temp_exp)
223         [ "$exp_val" == "$imp_val" ] ||
224                 error "export flags '$exp_val' != import flags '$imp_val'"
225
226         # Compare client versions.  Only compare top-3 fields for compatibility
227         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
228         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
229         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
230         [ "$exp_val" == "$imp_val" ] ||
231                 error "exp version '$exp_client_version'($exp_val) != " \
232                         "'$(lustre_build_version client)'($imp_val)"
233 }
234 run_test 0d "check export proc ============================="
235
236 test_0e() { # LU-13417
237         (( $MDSCOUNT > 1 )) ||
238                 skip "We need at least 2 MDTs for this test"
239
240         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
241                 skip "Need server version at least 2.14.51"
242
243         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
244         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
245
246         [ $default_lmv_count -eq 1 ] ||
247                 error "$MOUNT default stripe count $default_lmv_count"
248
249         [ $default_lmv_index -eq -1 ] ||
250                 error "$MOUNT default stripe index $default_lmv_index"
251
252         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
253         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
254
255         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
256         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
257
258         [ $mdt_index1 -eq $mdt_index2 ] &&
259                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
260
261         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
262 }
263 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
264
265 test_1() {
266         test_mkdir $DIR/$tdir
267         test_mkdir $DIR/$tdir/d2
268         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
269         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
270         rmdir $DIR/$tdir/d2
271         rmdir $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
273 }
274 run_test 1 "mkdir; remkdir; rmdir"
275
276 test_2() {
277         test_mkdir $DIR/$tdir
278         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
279         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
280         rm -r $DIR/$tdir
281         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
282 }
283 run_test 2 "mkdir; touch; rmdir; check file"
284
285 test_3() {
286         test_mkdir $DIR/$tdir
287         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
288         touch $DIR/$tdir/$tfile
289         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
290         rm -r $DIR/$tdir
291         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
292 }
293 run_test 3 "mkdir; touch; rmdir; check dir"
294
295 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
296 test_4() {
297         test_mkdir -i 1 $DIR/$tdir
298
299         touch $DIR/$tdir/$tfile ||
300                 error "Create file under remote directory failed"
301
302         rmdir $DIR/$tdir &&
303                 error "Expect error removing in-use dir $DIR/$tdir"
304
305         test -d $DIR/$tdir || error "Remote directory disappeared"
306
307         rm -rf $DIR/$tdir || error "remove remote dir error"
308 }
309 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
310
311 test_5() {
312         test_mkdir $DIR/$tdir
313         test_mkdir $DIR/$tdir/d2
314         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
315         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
316         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
317 }
318 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
319
320 test_6a() {
321         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
322         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile does not have perm 0666 or UID $UID"
325         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
326         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
327                 error "$tfile should be 0666 and owned by UID $UID"
328 }
329 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
330
331 test_6c() {
332         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
333
334         touch $DIR/$tfile
335         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
339         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
340                 error "$tfile should be owned by UID $RUNAS_ID"
341 }
342 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
343
344 test_6e() {
345         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
346
347         touch $DIR/$tfile
348         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by GID $UID"
351         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
352         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
353                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
354 }
355 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
356
357 test_6g() {
358         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
359
360         test_mkdir $DIR/$tdir
361         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
362         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
363         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
364         test_mkdir $DIR/$tdir/d/subdir
365         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
366                 error "$tdir/d/subdir should be GID $RUNAS_GID"
367         if [[ $MDSCOUNT -gt 1 ]]; then
368                 # check remote dir sgid inherite
369                 $LFS mkdir -i 0 $DIR/$tdir.local ||
370                         error "mkdir $tdir.local failed"
371                 chmod g+s $DIR/$tdir.local ||
372                         error "chmod $tdir.local failed"
373                 chgrp $RUNAS_GID $DIR/$tdir.local ||
374                         error "chgrp $tdir.local failed"
375                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
376                         error "mkdir $tdir.remote failed"
377                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
379                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
380                         error "$tdir.remote should be mode 02755"
381         fi
382 }
383 run_test 6g "verify new dir in sgid dir inherits group"
384
385 test_6h() { # bug 7331
386         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
387
388         touch $DIR/$tfile || error "touch failed"
389         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
390         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
391                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
392         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
393                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
394 }
395 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
396
397 test_7a() {
398         test_mkdir $DIR/$tdir
399         $MCREATE $DIR/$tdir/$tfile
400         chmod 0666 $DIR/$tdir/$tfile
401         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
402                 error "$tdir/$tfile should be mode 0666"
403 }
404 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
405
406 test_7b() {
407         if [ ! -d $DIR/$tdir ]; then
408                 test_mkdir $DIR/$tdir
409         fi
410         $MCREATE $DIR/$tdir/$tfile
411         echo -n foo > $DIR/$tdir/$tfile
412         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
413         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
414 }
415 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
416
417 test_8() {
418         test_mkdir $DIR/$tdir
419         touch $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tfile mode not 0666"
423 }
424 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
425
426 test_9() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         test_mkdir $DIR/$tdir/d2/d3
430         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
431 }
432 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
433
434 test_10() {
435         test_mkdir $DIR/$tdir
436         test_mkdir $DIR/$tdir/d2
437         touch $DIR/$tdir/d2/$tfile
438         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
439                 error "$tdir/d2/$tfile not a file"
440 }
441 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
442
443 test_11() {
444         test_mkdir $DIR/$tdir
445         test_mkdir $DIR/$tdir/d2
446         chmod 0666 $DIR/$tdir/d2
447         chmod 0705 $DIR/$tdir/d2
448         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
449                 error "$tdir/d2 mode not 0705"
450 }
451 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
452
453 test_12() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         chmod 0666 $DIR/$tdir/$tfile
457         chmod 0654 $DIR/$tdir/$tfile
458         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
459                 error "$tdir/d2 mode not 0654"
460 }
461 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
462
463 test_13() {
464         test_mkdir $DIR/$tdir
465         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
466         >  $DIR/$tdir/$tfile
467         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
468                 error "$tdir/$tfile size not 0 after truncate"
469 }
470 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
471
472 test_14() {
473         test_mkdir $DIR/$tdir
474         touch $DIR/$tdir/$tfile
475         rm $DIR/$tdir/$tfile
476         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
477 }
478 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
479
480 test_15() {
481         test_mkdir $DIR/$tdir
482         touch $DIR/$tdir/$tfile
483         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
484         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
485                 error "$tdir/${tfile_2} not a file after rename"
486         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
487 }
488 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
489
490 test_16() {
491         test_mkdir $DIR/$tdir
492         touch $DIR/$tdir/$tfile
493         rm -rf $DIR/$tdir/$tfile
494         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
495 }
496 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
497
498 test_17a() {
499         test_mkdir $DIR/$tdir
500         touch $DIR/$tdir/$tfile
501         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
502         ls -l $DIR/$tdir
503         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not a symlink"
505         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
506                 error "$tdir/l-exist not referencing a file"
507         rm -f $DIR/$tdir/l-exist
508         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
509 }
510 run_test 17a "symlinks: create, remove (real)"
511
512 test_17b() {
513         test_mkdir $DIR/$tdir
514         ln -s no-such-file $DIR/$tdir/l-dangle
515         ls -l $DIR/$tdir
516         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing no-such-file"
518         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
519                 error "$tdir/l-dangle not referencing non-existent file"
520         rm -f $DIR/$tdir/l-dangle
521         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
522 }
523 run_test 17b "symlinks: create, remove (dangling)"
524
525 test_17c() { # bug 3440 - don't save failed open RPC for replay
526         test_mkdir $DIR/$tdir
527         ln -s foo $DIR/$tdir/$tfile
528         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
529 }
530 run_test 17c "symlinks: open dangling (should return error)"
531
532 test_17d() {
533         test_mkdir $DIR/$tdir
534         ln -s foo $DIR/$tdir/$tfile
535         touch $DIR/$tdir/$tfile || error "creating to new symlink"
536 }
537 run_test 17d "symlinks: create dangling"
538
539 test_17e() {
540         test_mkdir $DIR/$tdir
541         local foo=$DIR/$tdir/$tfile
542         ln -s $foo $foo || error "create symlink failed"
543         ls -l $foo || error "ls -l failed"
544         ls $foo && error "ls not failed" || true
545 }
546 run_test 17e "symlinks: create recursive symlink (should return error)"
547
548 test_17f() {
549         test_mkdir $DIR/$tdir
550         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
553         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
554         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
555         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
556         ls -l  $DIR/$tdir
557 }
558 run_test 17f "symlinks: long and very long symlink name"
559
560 # str_repeat(S, N) generate a string that is string S repeated N times
561 str_repeat() {
562         local s=$1
563         local n=$2
564         local ret=''
565         while [ $((n -= 1)) -ge 0 ]; do
566                 ret=$ret$s
567         done
568         echo $ret
569 }
570
571 # Long symlinks and LU-2241
572 test_17g() {
573         test_mkdir $DIR/$tdir
574         local TESTS="59 60 61 4094 4095"
575
576         # Fix for inode size boundary in 2.1.4
577         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
578                 TESTS="4094 4095"
579
580         # Patch not applied to 2.2 or 2.3 branches
581         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
582         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
583                 TESTS="4094 4095"
584
585         for i in $TESTS; do
586                 local SYMNAME=$(str_repeat 'x' $i)
587                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
588                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
589         done
590 }
591 run_test 17g "symlinks: really long symlink name and inode boundaries"
592
593 test_17h() { #bug 17378
594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
595         remote_mds_nodsh && skip "remote MDS with nodsh"
596
597         local mdt_idx
598
599         test_mkdir $DIR/$tdir
600         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
601         $LFS setstripe -c -1 $DIR/$tdir
602         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
603         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
604         touch $DIR/$tdir/$tfile || true
605 }
606 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
607
608 test_17i() { #bug 20018
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         remote_mds_nodsh && skip "remote MDS with nodsh"
611
612         local foo=$DIR/$tdir/$tfile
613         local mdt_idx
614
615         test_mkdir -c1 $DIR/$tdir
616         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
617         ln -s $foo $foo || error "create symlink failed"
618 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
619         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
620         ls -l $foo && error "error not detected"
621         return 0
622 }
623 run_test 17i "don't panic on short symlink (should return error)"
624
625 test_17k() { #bug 22301
626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
627         [[ -z "$(which rsync 2>/dev/null)" ]] &&
628                 skip "no rsync command"
629         rsync --help | grep -q xattr ||
630                 skip_env "$(rsync --version | head -n1) does not support xattrs"
631         test_mkdir $DIR/$tdir
632         test_mkdir $DIR/$tdir.new
633         touch $DIR/$tdir/$tfile
634         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
635         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
636                 error "rsync failed with xattrs enabled"
637 }
638 run_test 17k "symlinks: rsync with xattrs enabled"
639
640 test_17l() { # LU-279
641         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
642                 skip "no getfattr command"
643
644         test_mkdir $DIR/$tdir
645         touch $DIR/$tdir/$tfile
646         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
647         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
648                 # -h to not follow symlinks. -m '' to list all the xattrs.
649                 # grep to remove first line: '# file: $path'.
650                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
651                 do
652                         lgetxattr_size_check $path $xattr ||
653                                 error "lgetxattr_size_check $path $xattr failed"
654                 done
655         done
656 }
657 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
658
659 # LU-1540
660 test_17m() {
661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
662         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
663         remote_mds_nodsh && skip "remote MDS with nodsh"
664         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
665         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
666                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
667
668         local short_sym="0123456789"
669         local wdir=$DIR/$tdir
670         local i
671
672         test_mkdir $wdir
673         long_sym=$short_sym
674         # create a long symlink file
675         for ((i = 0; i < 4; ++i)); do
676                 long_sym=${long_sym}${long_sym}
677         done
678
679         echo "create 512 short and long symlink files under $wdir"
680         for ((i = 0; i < 256; ++i)); do
681                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
682                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
683         done
684
685         echo "erase them"
686         rm -f $wdir/*
687         sync
688         wait_delete_completed
689
690         echo "recreate the 512 symlink files with a shorter string"
691         for ((i = 0; i < 512; ++i)); do
692                 # rewrite the symlink file with a shorter string
693                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
694                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
695         done
696
697         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
698
699         echo "stop and checking mds${mds_index}:"
700         # e2fsck should not return error
701         stop mds${mds_index}
702         local devname=$(mdsdevname $mds_index)
703         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
704         rc=$?
705
706         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
707                 error "start mds${mds_index} failed"
708         df $MOUNT > /dev/null 2>&1
709         [ $rc -eq 0 ] ||
710                 error "e2fsck detected error for short/long symlink: rc=$rc"
711         rm -f $wdir/*
712 }
713 run_test 17m "run e2fsck against MDT which contains short/long symlink"
714
715 check_fs_consistency_17n() {
716         local mdt_index
717         local rc=0
718
719         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
720         # so it only check MDT1/MDT2 instead of all of MDTs.
721         for mdt_index in 1 2; do
722                 # e2fsck should not return error
723                 stop mds${mdt_index}
724                 local devname=$(mdsdevname $mdt_index)
725                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
726                         rc=$((rc + $?))
727
728                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
729                         error "mount mds$mdt_index failed"
730                 df $MOUNT > /dev/null 2>&1
731         done
732         return $rc
733 }
734
735 test_17n() {
736         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
738         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
739         remote_mds_nodsh && skip "remote MDS with nodsh"
740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
741         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
742                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
743
744         local i
745
746         test_mkdir $DIR/$tdir
747         for ((i=0; i<10; i++)); do
748                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
749                         error "create remote dir error $i"
750                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
751                         error "create files under remote dir failed $i"
752         done
753
754         check_fs_consistency_17n ||
755                 error "e2fsck report error after create files under remote dir"
756
757         for ((i = 0; i < 10; i++)); do
758                 rm -rf $DIR/$tdir/remote_dir_${i} ||
759                         error "destroy remote dir error $i"
760         done
761
762         check_fs_consistency_17n ||
763                 error "e2fsck report error after unlink files under remote dir"
764
765         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
766                 skip "lustre < 2.4.50 does not support migrate mv"
767
768         for ((i = 0; i < 10; i++)); do
769                 mkdir -p $DIR/$tdir/remote_dir_${i}
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
773                         error "migrate remote dir error $i"
774         done
775         check_fs_consistency_17n || error "e2fsck report error after migration"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n || error "e2fsck report error after unlink"
783 }
784 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
785
786 test_17o() {
787         remote_mds_nodsh && skip "remote MDS with nodsh"
788         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
789                 skip "Need MDS version at least 2.3.64"
790
791         local wdir=$DIR/${tdir}o
792         local mdt_index
793         local rc=0
794
795         test_mkdir $wdir
796         touch $wdir/$tfile
797         mdt_index=$($LFS getstripe -m $wdir/$tfile)
798         mdt_index=$((mdt_index + 1))
799
800         cancel_lru_locks mdc
801         #fail mds will wait the failover finish then set
802         #following fail_loc to avoid interfer the recovery process.
803         fail mds${mdt_index}
804
805         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
806         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
807         ls -l $wdir/$tfile && rc=1
808         do_facet mds${mdt_index} lctl set_param fail_loc=0
809         [[ $rc -eq 0 ]] || error "stat file should fail"
810 }
811 run_test 17o "stat file with incompat LMA feature"
812
813 test_18() {
814         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
815         ls $DIR || error "Failed to ls $DIR: $?"
816 }
817 run_test 18 "touch .../f ; ls ... =============================="
818
819 test_19a() {
820         touch $DIR/$tfile
821         ls -l $DIR
822         rm $DIR/$tfile
823         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
824 }
825 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
826
827 test_19b() {
828         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
829 }
830 run_test 19b "ls -l .../f19 (should return error) =============="
831
832 test_19c() {
833         [ $RUNAS_ID -eq $UID ] &&
834                 skip_env "RUNAS_ID = UID = $UID -- skipping"
835
836         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
837 }
838 run_test 19c "$RUNAS touch .../f19 (should return error) =="
839
840 test_19d() {
841         cat $DIR/f19 && error || true
842 }
843 run_test 19d "cat .../f19 (should return error) =============="
844
845 test_20() {
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         touch $DIR/$tfile
851         rm $DIR/$tfile
852         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
853 }
854 run_test 20 "touch .../f ; ls -l ..."
855
856 test_21() {
857         test_mkdir $DIR/$tdir
858         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
859         ln -s dangle $DIR/$tdir/link
860         echo foo >> $DIR/$tdir/link
861         cat $DIR/$tdir/dangle
862         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
863         $CHECKSTAT -f -t file $DIR/$tdir/link ||
864                 error "$tdir/link not linked to a file"
865 }
866 run_test 21 "write to dangling link"
867
868 test_22() {
869         local wdir=$DIR/$tdir
870         test_mkdir $wdir
871         chown $RUNAS_ID:$RUNAS_GID $wdir
872         (cd $wdir || error "cd $wdir failed";
873                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
874                 $RUNAS tar xf -)
875         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
876         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
877         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
878                 error "checkstat -u failed"
879 }
880 run_test 22 "unpack tar archive as non-root user"
881
882 # was test_23
883 test_23a() {
884         test_mkdir $DIR/$tdir
885         local file=$DIR/$tdir/$tfile
886
887         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
888         openfile -f O_CREAT:O_EXCL $file &&
889                 error "$file recreate succeeded" || true
890 }
891 run_test 23a "O_CREAT|O_EXCL in subdir"
892
893 test_23b() { # bug 18988
894         test_mkdir $DIR/$tdir
895         local file=$DIR/$tdir/$tfile
896
897         rm -f $file
898         echo foo > $file || error "write filed"
899         echo bar >> $file || error "append filed"
900         $CHECKSTAT -s 8 $file || error "wrong size"
901         rm $file
902 }
903 run_test 23b "O_APPEND check"
904
905 # LU-9409, size with O_APPEND and tiny writes
906 test_23c() {
907         local file=$DIR/$tfile
908
909         # single dd
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
911         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
912         rm -f $file
913
914         # racing tiny writes
915         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
916         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
917         wait
918         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
919         rm -f $file
920
921         #racing tiny & normal writes
922         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
923         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
924         wait
925         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
926         rm -f $file
927
928         #racing tiny & normal writes 2, ugly numbers
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
931         wait
932         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
933         rm -f $file
934 }
935 run_test 23c "O_APPEND size checks for tiny writes"
936
937 # LU-11069 file offset is correct after appending writes
938 test_23d() {
939         local file=$DIR/$tfile
940         local offset
941
942         echo CentaurHauls > $file
943         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
944         if ((offset != 26)); then
945                 error "wrong offset, expected 26, got '$offset'"
946         fi
947 }
948 run_test 23d "file offset is correct after appending writes"
949
950 # rename sanity
951 test_24a() {
952         echo '-- same directory rename'
953         test_mkdir $DIR/$tdir
954         touch $DIR/$tdir/$tfile.1
955         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
956         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
957 }
958 run_test 24a "rename file to non-existent target"
959
960 test_24b() {
961         test_mkdir $DIR/$tdir
962         touch $DIR/$tdir/$tfile.{1,2}
963         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
964         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
965         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
966 }
967 run_test 24b "rename file to existing target"
968
969 test_24c() {
970         test_mkdir $DIR/$tdir
971         test_mkdir $DIR/$tdir/d$testnum.1
972         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
973         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
974         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
975 }
976 run_test 24c "rename directory to non-existent target"
977
978 test_24d() {
979         test_mkdir -c1 $DIR/$tdir
980         test_mkdir -c1 $DIR/$tdir/d$testnum.1
981         test_mkdir -c1 $DIR/$tdir/d$testnum.2
982         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
983         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
984         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
985 }
986 run_test 24d "rename directory to existing target"
987
988 test_24e() {
989         echo '-- cross directory renames --'
990         test_mkdir $DIR/R5a
991         test_mkdir $DIR/R5b
992         touch $DIR/R5a/f
993         mv $DIR/R5a/f $DIR/R5b/g
994         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
995         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
996 }
997 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
998
999 test_24f() {
1000         test_mkdir $DIR/R6a
1001         test_mkdir $DIR/R6b
1002         touch $DIR/R6a/f $DIR/R6b/g
1003         mv $DIR/R6a/f $DIR/R6b/g
1004         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1005         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1006 }
1007 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1008
1009 test_24g() {
1010         test_mkdir $DIR/R7a
1011         test_mkdir $DIR/R7b
1012         test_mkdir $DIR/R7a/d
1013         mv $DIR/R7a/d $DIR/R7b/e
1014         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1015         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1016 }
1017 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1018
1019 test_24h() {
1020         test_mkdir -c1 $DIR/R8a
1021         test_mkdir -c1 $DIR/R8b
1022         test_mkdir -c1 $DIR/R8a/d
1023         test_mkdir -c1 $DIR/R8b/e
1024         mrename $DIR/R8a/d $DIR/R8b/e
1025         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1026         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1027 }
1028 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1029
1030 test_24i() {
1031         echo "-- rename error cases"
1032         test_mkdir $DIR/R9
1033         test_mkdir $DIR/R9/a
1034         touch $DIR/R9/f
1035         mrename $DIR/R9/f $DIR/R9/a
1036         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1037         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1038         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1039 }
1040 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1041
1042 test_24j() {
1043         test_mkdir $DIR/R10
1044         mrename $DIR/R10/f $DIR/R10/g
1045         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1046         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1047         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1048 }
1049 run_test 24j "source does not exist ============================"
1050
1051 test_24k() {
1052         test_mkdir $DIR/R11a
1053         test_mkdir $DIR/R11a/d
1054         touch $DIR/R11a/f
1055         mv $DIR/R11a/f $DIR/R11a/d
1056         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1057         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1058 }
1059 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1060
1061 # bug 2429 - rename foo foo foo creates invalid file
1062 test_24l() {
1063         f="$DIR/f24l"
1064         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1065 }
1066 run_test 24l "Renaming a file to itself ========================"
1067
1068 test_24m() {
1069         f="$DIR/f24m"
1070         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1071         # on ext3 this does not remove either the source or target files
1072         # though the "expected" operation would be to remove the source
1073         $CHECKSTAT -t file ${f} || error "${f} missing"
1074         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1075 }
1076 run_test 24m "Renaming a file to a hard link to itself ========="
1077
1078 test_24n() {
1079     f="$DIR/f24n"
1080     # this stats the old file after it was renamed, so it should fail
1081     touch ${f}
1082     $CHECKSTAT ${f} || error "${f} missing"
1083     mv ${f} ${f}.rename
1084     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1085     $CHECKSTAT -a ${f} || error "${f} exists"
1086 }
1087 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1088
1089 test_24o() {
1090         test_mkdir $DIR/$tdir
1091         rename_many -s random -v -n 10 $DIR/$tdir
1092 }
1093 run_test 24o "rename of files during htree split"
1094
1095 test_24p() {
1096         test_mkdir $DIR/R12a
1097         test_mkdir $DIR/R12b
1098         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1099         mrename $DIR/R12a $DIR/R12b
1100         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1101         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1102         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1103         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1104 }
1105 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1106
1107 cleanup_multiop_pause() {
1108         trap 0
1109         kill -USR1 $MULTIPID
1110 }
1111
1112 test_24q() {
1113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1114
1115         test_mkdir $DIR/R13a
1116         test_mkdir $DIR/R13b
1117         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1118         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1119         MULTIPID=$!
1120
1121         trap cleanup_multiop_pause EXIT
1122         mrename $DIR/R13a $DIR/R13b
1123         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1124         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1125         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1126         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1127         cleanup_multiop_pause
1128         wait $MULTIPID || error "multiop close failed"
1129 }
1130 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1131
1132 test_24r() { #bug 3789
1133         test_mkdir $DIR/R14a
1134         test_mkdir $DIR/R14a/b
1135         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1137         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1138 }
1139 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1140
1141 test_24s() {
1142         test_mkdir $DIR/R15a
1143         test_mkdir $DIR/R15a/b
1144         test_mkdir $DIR/R15a/b/c
1145         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1146         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1147         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1148 }
1149 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1150
1151 test_24t() {
1152         test_mkdir $DIR/R16a
1153         test_mkdir $DIR/R16a/b
1154         test_mkdir $DIR/R16a/b/c
1155         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1157         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1158 }
1159 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1160
1161 test_24u() { # bug12192
1162         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1163         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1164 }
1165 run_test 24u "create stripe file"
1166
1167 simple_cleanup_common() {
1168         local createmany=$1
1169         local rc=0
1170
1171         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1172
1173         local start=$SECONDS
1174
1175         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1176         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1177         rc=$?
1178         wait_delete_completed
1179         echo "cleanup time $((SECONDS - start))"
1180         return $rc
1181 }
1182
1183 max_pages_per_rpc() {
1184         local mdtname="$(printf "MDT%04x" ${1:-0})"
1185         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1186 }
1187
1188 test_24v() {
1189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1190
1191         local nrfiles=${COUNT:-100000}
1192         local fname="$DIR/$tdir/$tfile"
1193
1194         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1195         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1196
1197         test_mkdir "$(dirname $fname)"
1198         # assume MDT0000 has the fewest inodes
1199         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1200         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1201         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1202
1203         stack_trap "simple_cleanup_common $nrfiles"
1204
1205         createmany -m "$fname" $nrfiles
1206
1207         cancel_lru_locks mdc
1208         lctl set_param mdc.*.stats clear
1209
1210         # was previously test_24D: LU-6101
1211         # readdir() returns correct number of entries after cursor reload
1212         local num_ls=$(ls $DIR/$tdir | wc -l)
1213         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1214         local num_all=$(ls -a $DIR/$tdir | wc -l)
1215         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1216                 [ $num_all -ne $((nrfiles + 2)) ]; then
1217                         error "Expected $nrfiles files, got $num_ls " \
1218                                 "($num_uniq unique $num_all .&..)"
1219         fi
1220         # LU-5 large readdir
1221         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1222         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1223         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1224         # take into account of overhead in lu_dirpage header and end mark in
1225         # each page, plus one in rpc_num calculation.
1226         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1227         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1228         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1229         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1230         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1231         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1232         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1233         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1234                 error "large readdir doesn't take effect: " \
1235                       "$mds_readpage should be about $rpc_max"
1236 }
1237 run_test 24v "list large directory (test hash collision, b=17560)"
1238
1239 test_24w() { # bug21506
1240         SZ1=234852
1241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1242         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1243         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1244         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1245         [[ "$SZ1" -eq "$SZ2" ]] ||
1246                 error "Error reading at the end of the file $tfile"
1247 }
1248 run_test 24w "Reading a file larger than 4Gb"
1249
1250 test_24x() {
1251         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1253         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1254                 skip "Need MDS version at least 2.7.56"
1255
1256         local MDTIDX=1
1257         local remote_dir=$DIR/$tdir/remote_dir
1258
1259         test_mkdir $DIR/$tdir
1260         $LFS mkdir -i $MDTIDX $remote_dir ||
1261                 error "create remote directory failed"
1262
1263         test_mkdir $DIR/$tdir/src_dir
1264         touch $DIR/$tdir/src_file
1265         test_mkdir $remote_dir/tgt_dir
1266         touch $remote_dir/tgt_file
1267
1268         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1269                 error "rename dir cross MDT failed!"
1270
1271         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1272                 error "rename file cross MDT failed!"
1273
1274         touch $DIR/$tdir/ln_file
1275         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1276                 error "ln file cross MDT failed"
1277
1278         rm -rf $DIR/$tdir || error "Can not delete directories"
1279 }
1280 run_test 24x "cross MDT rename/link"
1281
1282 test_24y() {
1283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1285
1286         local remote_dir=$DIR/$tdir/remote_dir
1287         local mdtidx=1
1288
1289         test_mkdir $DIR/$tdir
1290         $LFS mkdir -i $mdtidx $remote_dir ||
1291                 error "create remote directory failed"
1292
1293         test_mkdir $remote_dir/src_dir
1294         touch $remote_dir/src_file
1295         test_mkdir $remote_dir/tgt_dir
1296         touch $remote_dir/tgt_file
1297
1298         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1299                 error "rename subdir in the same remote dir failed!"
1300
1301         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1302                 error "rename files in the same remote dir failed!"
1303
1304         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1305                 error "link files in the same remote dir failed!"
1306
1307         rm -rf $DIR/$tdir || error "Can not delete directories"
1308 }
1309 run_test 24y "rename/link on the same dir should succeed"
1310
1311 test_24z() {
1312         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1313         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1314                 skip "Need MDS version at least 2.12.51"
1315
1316         local index
1317
1318         for index in 0 1; do
1319                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1320                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1321         done
1322
1323         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1324
1325         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1326         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1327
1328         local mdts=$(comma_list $(mdts_nodes))
1329
1330         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1331         stack_trap "do_nodes $mdts $LCTL \
1332                 set_param mdt.*.enable_remote_rename=1" EXIT
1333
1334         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1335
1336         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1337         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1338 }
1339 run_test 24z "cross-MDT rename is done as cp"
1340
1341 test_24A() { # LU-3182
1342         local NFILES=5000
1343
1344         test_mkdir $DIR/$tdir
1345         stack_trap "simple_cleanup_common $NFILES"
1346         createmany -m $DIR/$tdir/$tfile $NFILES
1347         local t=$(ls $DIR/$tdir | wc -l)
1348         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1349         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1350
1351         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1352                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1353 }
1354 run_test 24A "readdir() returns correct number of entries."
1355
1356 test_24B() { # LU-4805
1357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1358
1359         local count
1360
1361         test_mkdir $DIR/$tdir
1362         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1363                 error "create striped dir failed"
1364
1365         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1366         [ $count -eq 2 ] || error "Expected 2, got $count"
1367
1368         touch $DIR/$tdir/striped_dir/a
1369
1370         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1371         [ $count -eq 3 ] || error "Expected 3, got $count"
1372
1373         touch $DIR/$tdir/striped_dir/.f
1374
1375         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1376         [ $count -eq 4 ] || error "Expected 4, got $count"
1377
1378         rm -rf $DIR/$tdir || error "Can not delete directories"
1379 }
1380 run_test 24B "readdir for striped dir return correct number of entries"
1381
1382 test_24C() {
1383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1384
1385         mkdir $DIR/$tdir
1386         mkdir $DIR/$tdir/d0
1387         mkdir $DIR/$tdir/d1
1388
1389         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1390                 error "create striped dir failed"
1391
1392         cd $DIR/$tdir/d0/striped_dir
1393
1394         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1395         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1396         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1397
1398         [ "$d0_ino" = "$parent_ino" ] ||
1399                 error ".. wrong, expect $d0_ino, get $parent_ino"
1400
1401         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1402                 error "mv striped dir failed"
1403
1404         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1405
1406         [ "$d1_ino" = "$parent_ino" ] ||
1407                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1408 }
1409 run_test 24C "check .. in striped dir"
1410
1411 test_24E() {
1412         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1414
1415         mkdir -p $DIR/$tdir
1416         mkdir $DIR/$tdir/src_dir
1417         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1418                 error "create remote source failed"
1419
1420         touch $DIR/$tdir/src_dir/src_child/a
1421
1422         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1423                 error "create remote target dir failed"
1424
1425         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "create remote target child failed"
1427
1428         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1429                 error "rename dir cross MDT failed!"
1430
1431         find $DIR/$tdir
1432
1433         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1434                 error "src_child still exists after rename"
1435
1436         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1437                 error "missing file(a) after rename"
1438
1439         rm -rf $DIR/$tdir || error "Can not delete directories"
1440 }
1441 run_test 24E "cross MDT rename/link"
1442
1443 test_24F () {
1444         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1445
1446         local repeats=1000
1447         [ "$SLOW" = "no" ] && repeats=100
1448
1449         mkdir -p $DIR/$tdir
1450
1451         echo "$repeats repeats"
1452         for ((i = 0; i < repeats; i++)); do
1453                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1454                 touch $DIR/$tdir/test/a || error "touch fails"
1455                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1456                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1457         done
1458
1459         true
1460 }
1461 run_test 24F "hash order vs readdir (LU-11330)"
1462
1463 test_24G () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1465
1466         local ino1
1467         local ino2
1468
1469         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1470         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1471         touch $DIR/$tdir-0/f1 || error "touch f1"
1472         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1473         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1474         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1475         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1476         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1477 }
1478 run_test 24G "migrate symlink in rename"
1479
1480 test_24H() {
1481         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1482         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1483                 skip "MDT1 should be on another node"
1484
1485         test_mkdir -i 1 -c 1 $DIR/$tdir
1486 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1487         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1488         touch $DIR/$tdir/$tfile || error "touch failed"
1489 }
1490 run_test 24H "repeat FLD_QUERY rpc"
1491
1492 test_25a() {
1493         echo '== symlink sanity ============================================='
1494
1495         test_mkdir $DIR/d25
1496         ln -s d25 $DIR/s25
1497         touch $DIR/s25/foo ||
1498                 error "File creation in symlinked directory failed"
1499 }
1500 run_test 25a "create file in symlinked directory ==============="
1501
1502 test_25b() {
1503         [ ! -d $DIR/d25 ] && test_25a
1504         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1505 }
1506 run_test 25b "lookup file in symlinked directory ==============="
1507
1508 test_26a() {
1509         test_mkdir $DIR/d26
1510         test_mkdir $DIR/d26/d26-2
1511         ln -s d26/d26-2 $DIR/s26
1512         touch $DIR/s26/foo || error "File creation failed"
1513 }
1514 run_test 26a "multiple component symlink ======================="
1515
1516 test_26b() {
1517         test_mkdir -p $DIR/$tdir/d26-2
1518         ln -s $tdir/d26-2/foo $DIR/s26-2
1519         touch $DIR/s26-2 || error "File creation failed"
1520 }
1521 run_test 26b "multiple component symlink at end of lookup ======"
1522
1523 test_26c() {
1524         test_mkdir $DIR/d26.2
1525         touch $DIR/d26.2/foo
1526         ln -s d26.2 $DIR/s26.2-1
1527         ln -s s26.2-1 $DIR/s26.2-2
1528         ln -s s26.2-2 $DIR/s26.2-3
1529         chmod 0666 $DIR/s26.2-3/foo
1530 }
1531 run_test 26c "chain of symlinks"
1532
1533 # recursive symlinks (bug 439)
1534 test_26d() {
1535         ln -s d26-3/foo $DIR/d26-3
1536 }
1537 run_test 26d "create multiple component recursive symlink"
1538
1539 test_26e() {
1540         [ ! -h $DIR/d26-3 ] && test_26d
1541         rm $DIR/d26-3
1542 }
1543 run_test 26e "unlink multiple component recursive symlink"
1544
1545 # recursive symlinks (bug 7022)
1546 test_26f() {
1547         test_mkdir $DIR/$tdir
1548         test_mkdir $DIR/$tdir/$tfile
1549         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1550         test_mkdir -p lndir/bar1
1551         test_mkdir $DIR/$tdir/$tfile/$tfile
1552         cd $tfile                || error "cd $tfile failed"
1553         ln -s .. dotdot          || error "ln dotdot failed"
1554         ln -s dotdot/lndir lndir || error "ln lndir failed"
1555         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1556         output=`ls $tfile/$tfile/lndir/bar1`
1557         [ "$output" = bar1 ] && error "unexpected output"
1558         rm -r $tfile             || error "rm $tfile failed"
1559         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1560 }
1561 run_test 26f "rm -r of a directory which has recursive symlink"
1562
1563 test_27a() {
1564         test_mkdir $DIR/$tdir
1565         $LFS getstripe $DIR/$tdir
1566         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1567         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1568         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1569 }
1570 run_test 27a "one stripe file"
1571
1572 test_27b() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1574
1575         test_mkdir $DIR/$tdir
1576         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $LFS getstripe -c $DIR/$tdir/$tfile
1578         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1579                 error "two-stripe file doesn't have two stripes"
1580
1581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1582 }
1583 run_test 27b "create and write to two stripe file"
1584
1585 # 27c family tests specific striping, setstripe -o
1586 test_27ca() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1588         test_mkdir -p $DIR/$tdir
1589         local osts="1"
1590
1591         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1592         $LFS getstripe -i $DIR/$tdir/$tfile
1593         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1594                 error "stripe not on specified OST"
1595
1596         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1597 }
1598 run_test 27ca "one stripe on specified OST"
1599
1600 test_27cb() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cb "two stripes on specified OSTs"
1617
1618 test_27cc() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622
1623         test_mkdir -p $DIR/$tdir
1624         local osts="0,0"
1625         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1626         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1627         echo "$getstripe"
1628
1629         # Strip getstripe output to a space separated list of OSTs
1630         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1631                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1632         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1633                 error "stripes not on specified OSTs"
1634
1635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1636 }
1637 run_test 27cc "two stripes on the same OST"
1638
1639 test_27cd() {
1640         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,1,1,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cd "four stripes on two OSTs"
1658
1659 test_27ce() {
1660         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1661                 skip_env "too many osts, skipping"
1662         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1663                 skip "server does not support overstriping"
1664         # We do one more stripe than we have OSTs
1665         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1666                 skip_env "ea_inode feature disabled"
1667
1668         test_mkdir -p $DIR/$tdir
1669         local osts=""
1670         for i in $(seq 0 $OSTCOUNT);
1671         do
1672                 osts=$osts"0"
1673                 if [ $i -ne $OSTCOUNT ]; then
1674                         osts=$osts","
1675                 fi
1676         done
1677         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1678         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1679         echo "$getstripe"
1680
1681         # Strip getstripe output to a space separated list of OSTs
1682         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1683                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1684         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1685                 error "stripes not on specified OSTs"
1686
1687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1688 }
1689 run_test 27ce "more stripes than OSTs with -o"
1690
1691 test_27cf() {
1692         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1693         local pid=0
1694
1695         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1696         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1697         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1698         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1699                 error "failed to set $osp_proc=0"
1700
1701         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1702         pid=$!
1703         sleep 1
1704         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1706                 error "failed to set $osp_proc=1"
1707         wait $pid
1708         [[ $pid -ne 0 ]] ||
1709                 error "should return error due to $osp_proc=0"
1710 }
1711 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1712
1713 test_27d() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1716                 error "setstripe failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1719 }
1720 run_test 27d "create file with default settings"
1721
1722 test_27e() {
1723         # LU-5839 adds check for existed layout before setting it
1724         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1725                 skip "Need MDS version at least 2.7.56"
1726
1727         test_mkdir $DIR/$tdir
1728         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1729         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1730         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1731 }
1732 run_test 27e "setstripe existing file (should return error)"
1733
1734 test_27f() {
1735         test_mkdir $DIR/$tdir
1736         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1737                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1738         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1739                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1741         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1742 }
1743 run_test 27f "setstripe with bad stripe size (should return error)"
1744
1745 test_27g() {
1746         test_mkdir $DIR/$tdir
1747         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1748         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1749                 error "$DIR/$tdir/$tfile has object"
1750 }
1751 run_test 27g "$LFS getstripe with no objects"
1752
1753 test_27ga() {
1754         test_mkdir $DIR/$tdir
1755         touch $DIR/$tdir/$tfile || error "touch failed"
1756         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1757         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1758         local rc=$?
1759         (( rc == 2 )) || error "getstripe did not return ENOENT"
1760 }
1761 run_test 27ga "$LFS getstripe with missing file (should return error)"
1762
1763 test_27i() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1767                 error "missing objects"
1768 }
1769 run_test 27i "$LFS getstripe with some objects"
1770
1771 test_27j() {
1772         test_mkdir $DIR/$tdir
1773         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1774                 error "setstripe failed" || true
1775 }
1776 run_test 27j "setstripe with bad stripe offset (should return error)"
1777
1778 test_27k() { # bug 2844
1779         test_mkdir $DIR/$tdir
1780         local file=$DIR/$tdir/$tfile
1781         local ll_max_blksize=$((4 * 1024 * 1024))
1782         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1783         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1784         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1785         dd if=/dev/zero of=$file bs=4k count=1
1786         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1787         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1788 }
1789 run_test 27k "limit i_blksize for broken user apps"
1790
1791 test_27l() {
1792         mcreate $DIR/$tfile || error "creating file"
1793         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1794                 error "setstripe should have failed" || true
1795 }
1796 run_test 27l "check setstripe permissions (should return error)"
1797
1798 test_27m() {
1799         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1800
1801         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1802                 skip_env "multiple clients -- skipping"
1803
1804         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1805                    head -n1)
1806         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1807                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1808         fi
1809         stack_trap simple_cleanup_common
1810         test_mkdir $DIR/$tdir
1811         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1813                 error "dd should fill OST0"
1814         i=2
1815         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1816                 i=$((i + 1))
1817                 [ $i -gt 256 ] && break
1818         done
1819         i=$((i + 1))
1820         touch $DIR/$tdir/$tfile.$i
1821         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1822             awk '{print $1}'| grep -w "0") ] &&
1823                 error "OST0 was full but new created file still use it"
1824         i=$((i + 1))
1825         touch $DIR/$tdir/$tfile.$i
1826         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1827             awk '{print $1}'| grep -w "0") ] &&
1828                 error "OST0 was full but new created file still use it" || true
1829 }
1830 run_test 27m "create file while OST0 was full"
1831
1832 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1833 # if the OST isn't full anymore.
1834 reset_enospc() {
1835         local ostidx=${1:-""}
1836         local delay
1837         local ready
1838         local get_prealloc
1839
1840         local list=$(comma_list $(osts_nodes))
1841         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1842
1843         do_nodes $list lctl set_param fail_loc=0
1844         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1845         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1846                 awk '{print $1 * 2;exit;}')
1847         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1848                         grep -v \"^0$\""
1849         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1850 }
1851
1852 test_27n() {
1853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1855         remote_mds_nodsh && skip "remote MDS with nodsh"
1856         remote_ost_nodsh && skip "remote OST with nodsh"
1857
1858         reset_enospc
1859         rm -f $DIR/$tdir/$tfile
1860         exhaust_precreations 0 0x80000215
1861         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1862         touch $DIR/$tdir/$tfile || error "touch failed"
1863         $LFS getstripe $DIR/$tdir/$tfile
1864         reset_enospc
1865 }
1866 run_test 27n "create file with some full OSTs"
1867
1868 test_27o() {
1869         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1871         remote_mds_nodsh && skip "remote MDS with nodsh"
1872         remote_ost_nodsh && skip "remote OST with nodsh"
1873
1874         reset_enospc
1875         rm -f $DIR/$tdir/$tfile
1876         exhaust_all_precreations 0x215
1877
1878         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1879
1880         reset_enospc
1881         rm -rf $DIR/$tdir/*
1882 }
1883 run_test 27o "create file with all full OSTs (should error)"
1884
1885 function create_and_checktime() {
1886         local fname=$1
1887         local loops=$2
1888         local i
1889
1890         for ((i=0; i < $loops; i++)); do
1891                 local start=$SECONDS
1892                 multiop $fname-$i Oc
1893                 ((SECONDS-start < TIMEOUT)) ||
1894                         error "creation took " $((SECONDS-$start)) && return 1
1895         done
1896 }
1897
1898 test_27oo() {
1899         local mdts=$(comma_list $(mdts_nodes))
1900
1901         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1902                 skip "Need MDS version at least 2.13.57"
1903
1904         local f0=$DIR/${tfile}-0
1905         local f1=$DIR/${tfile}-1
1906
1907         wait_delete_completed
1908
1909         # refill precreated objects
1910         $LFS setstripe -i0 -c1 $f0
1911
1912         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1913         # force QoS allocation policy
1914         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1915         stack_trap "do_nodes $mdts $LCTL set_param \
1916                 lov.*.qos_threshold_rr=$saved" EXIT
1917         sleep_maxage
1918
1919         # one OST is unavailable, but still have few objects preallocated
1920         stop ost1
1921         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1922                 rm -rf $f1 $DIR/$tdir*" EXIT
1923
1924         for ((i=0; i < 7; i++)); do
1925                 mkdir $DIR/$tdir$i || error "can't create dir"
1926                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1927                         error "can't set striping"
1928         done
1929         for ((i=0; i < 7; i++)); do
1930                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1931         done
1932         wait
1933 }
1934 run_test 27oo "don't let few threads to reserve too many objects"
1935
1936 test_27p() {
1937         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1939         remote_mds_nodsh && skip "remote MDS with nodsh"
1940         remote_ost_nodsh && skip "remote OST with nodsh"
1941
1942         reset_enospc
1943         rm -f $DIR/$tdir/$tfile
1944         test_mkdir $DIR/$tdir
1945
1946         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1947         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1948         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1949
1950         exhaust_precreations 0 0x80000215
1951         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1952         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1953         $LFS getstripe $DIR/$tdir/$tfile
1954
1955         reset_enospc
1956 }
1957 run_test 27p "append to a truncated file with some full OSTs"
1958
1959 test_27q() {
1960         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1962         remote_mds_nodsh && skip "remote MDS with nodsh"
1963         remote_ost_nodsh && skip "remote OST with nodsh"
1964
1965         reset_enospc
1966         rm -f $DIR/$tdir/$tfile
1967
1968         mkdir_on_mdt0 $DIR/$tdir
1969         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1970         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1971                 error "truncate $DIR/$tdir/$tfile failed"
1972         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1973
1974         exhaust_all_precreations 0x215
1975
1976         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1977         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1978
1979         reset_enospc
1980 }
1981 run_test 27q "append to truncated file with all OSTs full (should error)"
1982
1983 test_27r() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         exhaust_precreations 0 0x80000215
1992
1993         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1994
1995         reset_enospc
1996 }
1997 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1998
1999 test_27s() { # bug 10725
2000         test_mkdir $DIR/$tdir
2001         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2002         local stripe_count=0
2003         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2004         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2005                 error "stripe width >= 2^32 succeeded" || true
2006
2007 }
2008 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2009
2010 test_27t() { # bug 10864
2011         WDIR=$(pwd)
2012         WLFS=$(which lfs)
2013         cd $DIR
2014         touch $tfile
2015         $WLFS getstripe $tfile
2016         cd $WDIR
2017 }
2018 run_test 27t "check that utils parse path correctly"
2019
2020 test_27u() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023
2024         local index
2025         local list=$(comma_list $(mdts_nodes))
2026
2027 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2028         do_nodes $list $LCTL set_param fail_loc=0x139
2029         test_mkdir -p $DIR/$tdir
2030         stack_trap "simple_cleanup_common 1000"
2031         createmany -o $DIR/$tdir/$tfile 1000
2032         do_nodes $list $LCTL set_param fail_loc=0
2033
2034         TLOG=$TMP/$tfile.getstripe
2035         $LFS getstripe $DIR/$tdir > $TLOG
2036         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2037         [[ $OBJS -gt 0 ]] &&
2038                 error "$OBJS objects created on OST-0. See $TLOG" ||
2039                 rm -f $TLOG
2040 }
2041 run_test 27u "skip object creation on OSC w/o objects"
2042
2043 test_27v() { # bug 4900
2044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2046         remote_mds_nodsh && skip "remote MDS with nodsh"
2047         remote_ost_nodsh && skip "remote OST with nodsh"
2048
2049         exhaust_all_precreations 0x215
2050         reset_enospc
2051
2052         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2053
2054         touch $DIR/$tdir/$tfile
2055         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2056         # all except ost1
2057         for (( i=1; i < OSTCOUNT; i++ )); do
2058                 do_facet ost$i lctl set_param fail_loc=0x705
2059         done
2060         local START=`date +%s`
2061         createmany -o $DIR/$tdir/$tfile 32
2062
2063         local FINISH=`date +%s`
2064         local TIMEOUT=`lctl get_param -n timeout`
2065         local PROCESS=$((FINISH - START))
2066         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2067                error "$FINISH - $START >= $TIMEOUT / 2"
2068         sleep $((TIMEOUT / 2 - PROCESS))
2069         reset_enospc
2070 }
2071 run_test 27v "skip object creation on slow OST"
2072
2073 test_27w() { # bug 10997
2074         test_mkdir $DIR/$tdir
2075         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2076         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2077                 error "stripe size $size != 65536" || true
2078         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2079                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2080 }
2081 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2082
2083 test_27wa() {
2084         [[ $OSTCOUNT -lt 2 ]] &&
2085                 skip_env "skipping multiple stripe count/offset test"
2086
2087         test_mkdir $DIR/$tdir
2088         for i in $(seq 1 $OSTCOUNT); do
2089                 offset=$((i - 1))
2090                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2091                         error "setstripe -c $i -i $offset failed"
2092                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2093                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2094                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2095                 [ $index -ne $offset ] &&
2096                         error "stripe offset $index != $offset" || true
2097         done
2098 }
2099 run_test 27wa "check $LFS setstripe -c -i options"
2100
2101 test_27x() {
2102         remote_ost_nodsh && skip "remote OST with nodsh"
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105
2106         OFFSET=$(($OSTCOUNT - 1))
2107         OSTIDX=0
2108         local OST=$(ostname_from_index $OSTIDX)
2109
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2112         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2113         sleep_maxage
2114         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2115         for i in $(seq 0 $OFFSET); do
2116                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2117                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2118                 error "OST0 was degraded but new created file still use it"
2119         done
2120         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2121 }
2122 run_test 27x "create files while OST0 is degraded"
2123
2124 test_27y() {
2125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2126         remote_mds_nodsh && skip "remote MDS with nodsh"
2127         remote_ost_nodsh && skip "remote OST with nodsh"
2128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2129
2130         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2131         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2132                 osp.$mdtosc.prealloc_last_id)
2133         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2134                 osp.$mdtosc.prealloc_next_id)
2135         local fcount=$((last_id - next_id))
2136         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2137         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2138
2139         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2140                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2141         local OST_DEACTIVE_IDX=-1
2142         local OSC
2143         local OSTIDX
2144         local OST
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2150                         OST_DEACTIVE_IDX=$OSTIDX
2151                 fi
2152                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2153                         echo $OSC "is Deactivated:"
2154                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2155                 fi
2156         done
2157
2158         OSTIDX=$(index_from_ostuuid $OST)
2159         test_mkdir $DIR/$tdir
2160         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2161
2162         for OSC in $MDS_OSCS; do
2163                 OST=$(osc_to_ost $OSC)
2164                 OSTIDX=$(index_from_ostuuid $OST)
2165                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2166                         echo $OST "is degraded:"
2167                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2168                                                 obdfilter.$OST.degraded=1
2169                 fi
2170         done
2171
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $fcount
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is recovered from degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=0
2182                 else
2183                         do_facet $SINGLEMDS lctl --device %$OSC activate
2184                 fi
2185         done
2186
2187         # all osp devices get activated, hence -1 stripe count restored
2188         local stripe_count=0
2189
2190         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2191         # devices get activated.
2192         sleep_maxage
2193         $LFS setstripe -c -1 $DIR/$tfile
2194         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2195         rm -f $DIR/$tfile
2196         [ $stripe_count -ne $OSTCOUNT ] &&
2197                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2198         return 0
2199 }
2200 run_test 27y "create files while OST0 is degraded and the rest inactive"
2201
2202 check_seq_oid()
2203 {
2204         log "check file $1"
2205
2206         lmm_count=$($LFS getstripe -c $1)
2207         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2208         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2209
2210         local old_ifs="$IFS"
2211         IFS=$'[:]'
2212         fid=($($LFS path2fid $1))
2213         IFS="$old_ifs"
2214
2215         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2216         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2217
2218         # compare lmm_seq and lu_fid->f_seq
2219         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2220         # compare lmm_object_id and lu_fid->oid
2221         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2222
2223         # check the trusted.fid attribute of the OST objects of the file
2224         local have_obdidx=false
2225         local stripe_nr=0
2226         $LFS getstripe $1 | while read obdidx oid hex seq; do
2227                 # skip lines up to and including "obdidx"
2228                 [ -z "$obdidx" ] && break
2229                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2230                 $have_obdidx || continue
2231
2232                 local ost=$((obdidx + 1))
2233                 local dev=$(ostdevname $ost)
2234                 local oid_hex
2235
2236                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2237
2238                 seq=$(echo $seq | sed -e "s/^0x//g")
2239                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2240                         oid_hex=$(echo $oid)
2241                 else
2242                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2243                 fi
2244                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2245
2246                 local ff=""
2247                 #
2248                 # Don't unmount/remount the OSTs if we don't need to do that.
2249                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2250                 # update too, until that use mount/ll_decode_filter_fid/mount.
2251                 # Re-enable when debugfs will understand new filter_fid.
2252                 #
2253                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2254                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2255                                 $dev 2>/dev/null" | grep "parent=")
2256                 fi
2257                 if [ -z "$ff" ]; then
2258                         stop ost$ost
2259                         mount_fstype ost$ost
2260                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2261                                 $(facet_mntpt ost$ost)/$obj_file)
2262                         unmount_fstype ost$ost
2263                         start ost$ost $dev $OST_MOUNT_OPTS
2264                         clients_up
2265                 fi
2266
2267                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2268
2269                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2270
2271                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2272                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2273                 #
2274                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2275                 #       stripe_size=1048576 component_id=1 component_start=0 \
2276                 #       component_end=33554432
2277                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2278                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2279                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2280                 local ff_pstripe
2281                 if grep -q 'stripe=' <<<$ff; then
2282                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2283                 else
2284                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2285                         # into f_ver in this case.  See comment on ff_parent.
2286                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2287                 fi
2288
2289                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2290                 [ $ff_pseq = $lmm_seq ] ||
2291                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2292                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2293                 [ $ff_poid = $lmm_oid ] ||
2294                         error "FF parent OID $ff_poid != $lmm_oid"
2295                 (($ff_pstripe == $stripe_nr)) ||
2296                         error "FF stripe $ff_pstripe != $stripe_nr"
2297
2298                 stripe_nr=$((stripe_nr + 1))
2299                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2300                         continue
2301                 if grep -q 'stripe_count=' <<<$ff; then
2302                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2303                                             -e 's/ .*//' <<<$ff)
2304                         [ $lmm_count = $ff_scnt ] ||
2305                                 error "FF stripe count $lmm_count != $ff_scnt"
2306                 fi
2307         done
2308 }
2309
2310 test_27z() {
2311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2312         remote_ost_nodsh && skip "remote OST with nodsh"
2313
2314         test_mkdir $DIR/$tdir
2315         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2316                 { error "setstripe -c -1 failed"; return 1; }
2317         # We need to send a write to every object to get parent FID info set.
2318         # This _should_ also work for setattr, but does not currently.
2319         # touch $DIR/$tdir/$tfile-1 ||
2320         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2321                 { error "dd $tfile-1 failed"; return 2; }
2322         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2323                 { error "setstripe -c -1 failed"; return 3; }
2324         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2325                 { error "dd $tfile-2 failed"; return 4; }
2326
2327         # make sure write RPCs have been sent to OSTs
2328         sync; sleep 5; sync
2329
2330         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2331         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2332 }
2333 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2334
2335 test_27A() { # b=19102
2336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2337
2338         save_layout_restore_at_exit $MOUNT
2339         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2340         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2341                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2342         local default_size=$($LFS getstripe -S $MOUNT)
2343         local default_offset=$($LFS getstripe -i $MOUNT)
2344         local dsize=$(do_facet $SINGLEMDS \
2345                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2346         [ $default_size -eq $dsize ] ||
2347                 error "stripe size $default_size != $dsize"
2348         [ $default_offset -eq -1 ] ||
2349                 error "stripe offset $default_offset != -1"
2350 }
2351 run_test 27A "check filesystem-wide default LOV EA values"
2352
2353 test_27B() { # LU-2523
2354         test_mkdir $DIR/$tdir
2355         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2356         touch $DIR/$tdir/f0
2357         # open f1 with O_LOV_DELAY_CREATE
2358         # rename f0 onto f1
2359         # call setstripe ioctl on open file descriptor for f1
2360         # close
2361         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2362                 $DIR/$tdir/f0
2363
2364         rm -f $DIR/$tdir/f1
2365         # open f1 with O_LOV_DELAY_CREATE
2366         # unlink f1
2367         # call setstripe ioctl on open file descriptor for f1
2368         # close
2369         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2370
2371         # Allow multiop to fail in imitation of NFS's busted semantics.
2372         true
2373 }
2374 run_test 27B "call setstripe on open unlinked file/rename victim"
2375
2376 # 27C family tests full striping and overstriping
2377 test_27Ca() { #LU-2871
2378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2379
2380         declare -a ost_idx
2381         local index
2382         local found
2383         local i
2384         local j
2385
2386         test_mkdir $DIR/$tdir
2387         cd $DIR/$tdir
2388         for i in $(seq 0 $((OSTCOUNT - 1))); do
2389                 # set stripe across all OSTs starting from OST$i
2390                 $LFS setstripe -i $i -c -1 $tfile$i
2391                 # get striping information
2392                 ost_idx=($($LFS getstripe $tfile$i |
2393                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2394                 echo "OST Index: ${ost_idx[*]}"
2395
2396                 # check the layout
2397                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2398                         error "${#ost_idx[@]} != $OSTCOUNT"
2399
2400                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2401                         found=0
2402                         for j in "${ost_idx[@]}"; do
2403                                 if [ $index -eq $j ]; then
2404                                         found=1
2405                                         break
2406                                 fi
2407                         done
2408                         [ $found = 1 ] ||
2409                                 error "Can not find $index in ${ost_idx[*]}"
2410                 done
2411         done
2412 }
2413 run_test 27Ca "check full striping across all OSTs"
2414
2415 test_27Cb() {
2416         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2417                 skip "server does not support overstriping"
2418         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2419                 skip_env "too many osts, skipping"
2420
2421         test_mkdir -p $DIR/$tdir
2422         local setcount=$(($OSTCOUNT * 2))
2423         [ $setcount -lt 160 ] || large_xattr_enabled ||
2424                 skip_env "ea_inode feature disabled"
2425
2426         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2427                 error "setstripe failed"
2428
2429         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2430         [ $count -eq $setcount ] ||
2431                 error "stripe count $count, should be $setcount"
2432
2433         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2434                 error "overstriped should be set in pattern"
2435
2436         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2437                 error "dd failed"
2438 }
2439 run_test 27Cb "more stripes than OSTs with -C"
2440
2441 test_27Cc() {
2442         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2443                 skip "server does not support overstriping"
2444         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2445
2446         test_mkdir -p $DIR/$tdir
2447         local setcount=$(($OSTCOUNT - 1))
2448
2449         [ $setcount -lt 160 ] || large_xattr_enabled ||
2450                 skip_env "ea_inode feature disabled"
2451
2452         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2453                 error "setstripe failed"
2454
2455         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2456         [ $count -eq $setcount ] ||
2457                 error "stripe count $count, should be $setcount"
2458
2459         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2460                 error "overstriped should not be set in pattern"
2461
2462         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2463                 error "dd failed"
2464 }
2465 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2466
2467 test_27Cd() {
2468         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2469                 skip "server does not support overstriping"
2470         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2471         large_xattr_enabled || skip_env "ea_inode feature disabled"
2472
2473         test_mkdir -p $DIR/$tdir
2474         local setcount=$LOV_MAX_STRIPE_COUNT
2475
2476         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2477                 error "setstripe failed"
2478
2479         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2480         [ $count -eq $setcount ] ||
2481                 error "stripe count $count, should be $setcount"
2482
2483         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2484                 error "overstriped should be set in pattern"
2485
2486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2487                 error "dd failed"
2488
2489         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2490 }
2491 run_test 27Cd "test maximum stripe count"
2492
2493 test_27Ce() {
2494         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2495                 skip "server does not support overstriping"
2496         test_mkdir -p $DIR/$tdir
2497
2498         pool_add $TESTNAME || error "Pool creation failed"
2499         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2500
2501         local setcount=8
2502
2503         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2504                 error "setstripe failed"
2505
2506         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2507         [ $count -eq $setcount ] ||
2508                 error "stripe count $count, should be $setcount"
2509
2510         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2511                 error "overstriped should be set in pattern"
2512
2513         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2514                 error "dd failed"
2515
2516         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2517 }
2518 run_test 27Ce "test pool with overstriping"
2519
2520 test_27Cf() {
2521         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2522                 skip "server does not support overstriping"
2523         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2524                 skip_env "too many osts, skipping"
2525
2526         test_mkdir -p $DIR/$tdir
2527
2528         local setcount=$(($OSTCOUNT * 2))
2529         [ $setcount -lt 160 ] || large_xattr_enabled ||
2530                 skip_env "ea_inode feature disabled"
2531
2532         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2533                 error "setstripe failed"
2534
2535         echo 1 > $DIR/$tdir/$tfile
2536
2537         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2538         [ $count -eq $setcount ] ||
2539                 error "stripe count $count, should be $setcount"
2540
2541         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2542                 error "overstriped should be set in pattern"
2543
2544         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2545                 error "dd failed"
2546
2547         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2548 }
2549 run_test 27Cf "test default inheritance with overstriping"
2550
2551 test_27D() {
2552         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2553         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2554         remote_mds_nodsh && skip "remote MDS with nodsh"
2555
2556         local POOL=${POOL:-testpool}
2557         local first_ost=0
2558         local last_ost=$(($OSTCOUNT - 1))
2559         local ost_step=1
2560         local ost_list=$(seq $first_ost $ost_step $last_ost)
2561         local ost_range="$first_ost $last_ost $ost_step"
2562
2563         test_mkdir $DIR/$tdir
2564         pool_add $POOL || error "pool_add failed"
2565         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2566
2567         local skip27D
2568         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2569                 skip27D+="-s 29"
2570         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2571                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2572                         skip27D+=" -s 30,31"
2573         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2574           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2575                 skip27D+=" -s 32,33"
2576         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2577                 skip27D+=" -s 34"
2578         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2579                 error "llapi_layout_test failed"
2580
2581         destroy_test_pools || error "destroy test pools failed"
2582 }
2583 run_test 27D "validate llapi_layout API"
2584
2585 # Verify that default_easize is increased from its initial value after
2586 # accessing a widely striped file.
2587 test_27E() {
2588         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2589         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2590                 skip "client does not have LU-3338 fix"
2591
2592         # 72 bytes is the minimum space required to store striping
2593         # information for a file striped across one OST:
2594         # (sizeof(struct lov_user_md_v3) +
2595         #  sizeof(struct lov_user_ost_data_v1))
2596         local min_easize=72
2597         $LCTL set_param -n llite.*.default_easize $min_easize ||
2598                 error "lctl set_param failed"
2599         local easize=$($LCTL get_param -n llite.*.default_easize)
2600
2601         [ $easize -eq $min_easize ] ||
2602                 error "failed to set default_easize"
2603
2604         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2605                 error "setstripe failed"
2606         # In order to ensure stat() call actually talks to MDS we need to
2607         # do something drastic to this file to shake off all lock, e.g.
2608         # rename it (kills lookup lock forcing cache cleaning)
2609         mv $DIR/$tfile $DIR/${tfile}-1
2610         ls -l $DIR/${tfile}-1
2611         rm $DIR/${tfile}-1
2612
2613         easize=$($LCTL get_param -n llite.*.default_easize)
2614
2615         [ $easize -gt $min_easize ] ||
2616                 error "default_easize not updated"
2617 }
2618 run_test 27E "check that default extended attribute size properly increases"
2619
2620 test_27F() { # LU-5346/LU-7975
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2623         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2624                 skip "Need MDS version at least 2.8.51"
2625         remote_ost_nodsh && skip "remote OST with nodsh"
2626
2627         test_mkdir $DIR/$tdir
2628         rm -f $DIR/$tdir/f0
2629         $LFS setstripe -c 2 $DIR/$tdir
2630
2631         # stop all OSTs to reproduce situation for LU-7975 ticket
2632         for num in $(seq $OSTCOUNT); do
2633                 stop ost$num
2634         done
2635
2636         # open/create f0 with O_LOV_DELAY_CREATE
2637         # truncate f0 to a non-0 size
2638         # close
2639         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2640
2641         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2642         # open/write it again to force delayed layout creation
2643         cat /etc/hosts > $DIR/$tdir/f0 &
2644         catpid=$!
2645
2646         # restart OSTs
2647         for num in $(seq $OSTCOUNT); do
2648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2649                         error "ost$num failed to start"
2650         done
2651
2652         wait $catpid || error "cat failed"
2653
2654         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2655         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2656                 error "wrong stripecount"
2657
2658 }
2659 run_test 27F "Client resend delayed layout creation with non-zero size"
2660
2661 test_27G() { #LU-10629
2662         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2663                 skip "Need MDS version at least 2.11.51"
2664         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2665         remote_mds_nodsh && skip "remote MDS with nodsh"
2666         local POOL=${POOL:-testpool}
2667         local ostrange="0 0 1"
2668
2669         test_mkdir $DIR/$tdir
2670         touch $DIR/$tdir/$tfile.nopool
2671         pool_add $POOL || error "pool_add failed"
2672         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2673         $LFS setstripe -p $POOL $DIR/$tdir
2674
2675         local pool=$($LFS getstripe -p $DIR/$tdir)
2676
2677         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2678         touch $DIR/$tdir/$tfile.default
2679         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2680         $LFS find $DIR/$tdir -type f --pool $POOL
2681         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2682         [[ "$found" == "2" ]] ||
2683                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2684
2685         $LFS setstripe -d $DIR/$tdir
2686
2687         pool=$($LFS getstripe -p -d $DIR/$tdir)
2688
2689         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2690 }
2691 run_test 27G "Clear OST pool from stripe"
2692
2693 test_27H() {
2694         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2695                 skip "Need MDS version newer than 2.11.54"
2696         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2697         test_mkdir $DIR/$tdir
2698         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2699         touch $DIR/$tdir/$tfile
2700         $LFS getstripe -c $DIR/$tdir/$tfile
2701         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2702                 error "two-stripe file doesn't have two stripes"
2703
2704         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2705         $LFS getstripe -y $DIR/$tdir/$tfile
2706         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2707              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2708                 error "expected l_ost_idx: [02]$ not matched"
2709
2710         # make sure ost list has been cleared
2711         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2712         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2713                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2714         touch $DIR/$tdir/f3
2715         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2716 }
2717 run_test 27H "Set specific OSTs stripe"
2718
2719 test_27I() {
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2723                 skip "Need MDS version newer than 2.12.52"
2724         local pool=$TESTNAME
2725         local ostrange="1 1 1"
2726
2727         save_layout_restore_at_exit $MOUNT
2728         $LFS setstripe -c 2 -i 0 $MOUNT
2729         pool_add $pool || error "pool_add failed"
2730         pool_add_targets $pool $ostrange ||
2731                 error "pool_add_targets failed"
2732         test_mkdir $DIR/$tdir
2733         $LFS setstripe -p $pool $DIR/$tdir
2734         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2735         $LFS getstripe $DIR/$tdir/$tfile
2736 }
2737 run_test 27I "check that root dir striping does not break parent dir one"
2738
2739 test_27J() {
2740         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2741                 skip "Need MDS version newer than 2.12.51"
2742
2743         test_mkdir $DIR/$tdir
2744         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2745         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2746
2747         # create foreign file (raw way)
2748         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2749                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2750
2751         ! $LFS setstripe --foreign --flags foo \
2752                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2753                         error "creating $tfile with '--flags foo' should fail"
2754
2755         ! $LFS setstripe --foreign --flags 0xffffffff \
2756                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2757                         error "creating $tfile w/ 0xffffffff flags should fail"
2758
2759         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2760                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2761
2762         # verify foreign file (raw way)
2763         parse_foreign_file -f $DIR/$tdir/$tfile |
2764                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2765                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2766         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2767                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2768         parse_foreign_file -f $DIR/$tdir/$tfile |
2769                 grep "lov_foreign_size: 73" ||
2770                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2771         parse_foreign_file -f $DIR/$tdir/$tfile |
2772                 grep "lov_foreign_type: 1" ||
2773                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2774         parse_foreign_file -f $DIR/$tdir/$tfile |
2775                 grep "lov_foreign_flags: 0x0000DA08" ||
2776                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2777         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2778                 grep "lov_foreign_value: 0x" |
2779                 sed -e 's/lov_foreign_value: 0x//')
2780         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2781         [[ $lov = ${lov2// /} ]] ||
2782                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2783
2784         # create foreign file (lfs + API)
2785         $LFS setstripe --foreign=none --flags 0xda08 \
2786                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2787                 error "$DIR/$tdir/${tfile}2: create failed"
2788
2789         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2790                 grep "lfm_magic:.*0x0BD70BD0" ||
2791                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2792         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2793         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2794                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2795         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2796                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2797         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2798                 grep "lfm_flags:.*0x0000DA08" ||
2799                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2800         $LFS getstripe $DIR/$tdir/${tfile}2 |
2801                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2802                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2803
2804         # modify striping should fail
2805         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2806                 error "$DIR/$tdir/$tfile: setstripe should fail"
2807         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2808                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2809
2810         # R/W should fail
2811         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2812         cat $DIR/$tdir/${tfile}2 &&
2813                 error "$DIR/$tdir/${tfile}2: read should fail"
2814         cat /etc/passwd > $DIR/$tdir/$tfile &&
2815                 error "$DIR/$tdir/$tfile: write should fail"
2816         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2817                 error "$DIR/$tdir/${tfile}2: write should fail"
2818
2819         # chmod should work
2820         chmod 222 $DIR/$tdir/$tfile ||
2821                 error "$DIR/$tdir/$tfile: chmod failed"
2822         chmod 222 $DIR/$tdir/${tfile}2 ||
2823                 error "$DIR/$tdir/${tfile}2: chmod failed"
2824
2825         # chown should work
2826         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2827                 error "$DIR/$tdir/$tfile: chown failed"
2828         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2829                 error "$DIR/$tdir/${tfile}2: chown failed"
2830
2831         # rename should work
2832         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2833                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2834         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2835                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2836
2837         #remove foreign file
2838         rm $DIR/$tdir/${tfile}.new ||
2839                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2840         rm $DIR/$tdir/${tfile}2.new ||
2841                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2842 }
2843 run_test 27J "basic ops on file with foreign LOV"
2844
2845 test_27K() {
2846         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2847                 skip "Need MDS version newer than 2.12.49"
2848
2849         test_mkdir $DIR/$tdir
2850         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2851         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2852
2853         # create foreign dir (raw way)
2854         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2855                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2856
2857         ! $LFS setdirstripe --foreign --flags foo \
2858                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2859                         error "creating $tdir with '--flags foo' should fail"
2860
2861         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2862                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2863                         error "creating $tdir w/ 0xffffffff flags should fail"
2864
2865         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2866                 error "create_foreign_dir FAILED"
2867
2868         # verify foreign dir (raw way)
2869         parse_foreign_dir -d $DIR/$tdir/$tdir |
2870                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2871                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2872         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2873                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2874         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2875                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_flags: 55813$" ||
2878                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2879         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2880                 grep "lmv_foreign_value: 0x" |
2881                 sed 's/lmv_foreign_value: 0x//')
2882         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2883                 sed 's/ //g')
2884         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2885
2886         # create foreign dir (lfs + API)
2887         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2888                 $DIR/$tdir/${tdir}2 ||
2889                 error "$DIR/$tdir/${tdir}2: create failed"
2890
2891         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2892
2893         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2894                 grep "lfm_magic:.*0x0CD50CD0" ||
2895                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2896         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2897         # - sizeof(lfm_type) - sizeof(lfm_flags)
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2900         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2902         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2903                 grep "lfm_flags:.*0x0000DA05" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2905         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2906                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2908
2909         # file create in dir should fail
2910         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2911         touch $DIR/$tdir/${tdir}2/$tfile &&
2912                 error "$DIR/${tdir}2: file create should fail"
2913
2914         # chmod should work
2915         chmod 777 $DIR/$tdir/$tdir ||
2916                 error "$DIR/$tdir: chmod failed"
2917         chmod 777 $DIR/$tdir/${tdir}2 ||
2918                 error "$DIR/${tdir}2: chmod failed"
2919
2920         # chown should work
2921         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2922                 error "$DIR/$tdir: chown failed"
2923         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2924                 error "$DIR/${tdir}2: chown failed"
2925
2926         # rename should work
2927         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2928                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2929         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2930                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2931
2932         #remove foreign dir
2933         rmdir $DIR/$tdir/${tdir}.new ||
2934                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2935         rmdir $DIR/$tdir/${tdir}2.new ||
2936                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2937 }
2938 run_test 27K "basic ops on dir with foreign LMV"
2939
2940 test_27L() {
2941         remote_mds_nodsh && skip "remote MDS with nodsh"
2942
2943         local POOL=${POOL:-$TESTNAME}
2944
2945         pool_add $POOL || error "pool_add failed"
2946
2947         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2948                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2949                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2950 }
2951 run_test 27L "lfs pool_list gives correct pool name"
2952
2953 test_27M() {
2954         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2955                 skip "Need MDS version >= than 2.12.57"
2956         remote_mds_nodsh && skip "remote MDS with nodsh"
2957         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2958
2959         # Set default striping on directory
2960         local setcount=4
2961         local stripe_opt
2962         local mdts=$(comma_list $(mdts_nodes))
2963
2964         # if we run against a 2.12 server which lacks overstring support
2965         # then the connect_flag will not report overstriping, even if client
2966         # is 2.14+
2967         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2968                 stripe_opt="-C $setcount"
2969         elif (( $OSTCOUNT >= $setcount )); then
2970                 stripe_opt="-c $setcount"
2971         else
2972                 skip "server does not support overstriping"
2973         fi
2974
2975         test_mkdir $DIR/$tdir
2976
2977         # Validate existing append_* params and ensure restore
2978         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
2979         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
2980         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
2981
2982         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2983         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
2984         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
2985
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         local appendcount=$orig_count
2994         echo 1 >> $DIR/$tdir/${tfile}.2_append
2995         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2996         [ $count -eq $appendcount ] ||
2997                 error "(2)stripe count $count, should be $appendcount for append"
2998
2999         # Disable O_APPEND striping, verify it works
3000         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3001
3002         # Should now get the default striping, which is 4
3003         setcount=4
3004         echo 1 >> $DIR/$tdir/${tfile}.3_append
3005         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3006         [ $count -eq $setcount ] ||
3007                 error "(3) stripe count $count, should be $setcount"
3008
3009         # Try changing the stripe count for append files
3010         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3011
3012         # Append striping is now 2 (directory default is still 4)
3013         appendcount=2
3014         echo 1 >> $DIR/$tdir/${tfile}.4_append
3015         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3016         [ $count -eq $appendcount ] ||
3017                 error "(4) stripe count $count, should be $appendcount for append"
3018
3019         # Test append stripe count of -1
3020         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3021         appendcount=$OSTCOUNT
3022         echo 1 >> $DIR/$tdir/${tfile}.5
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3024         [ $count -eq $appendcount ] ||
3025                 error "(5) stripe count $count, should be $appendcount for append"
3026
3027         # Set append striping back to default of 1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3029
3030         # Try a new default striping, PFL + DOM
3031         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3032
3033         # Create normal DOM file, DOM returns stripe count == 0
3034         setcount=0
3035         touch $DIR/$tdir/${tfile}.6
3036         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3037         [ $count -eq $setcount ] ||
3038                 error "(6) stripe count $count, should be $setcount"
3039
3040         # Show
3041         appendcount=1
3042         echo 1 >> $DIR/$tdir/${tfile}.7_append
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3044         [ $count -eq $appendcount ] ||
3045                 error "(7) stripe count $count, should be $appendcount for append"
3046
3047         # Clean up DOM layout
3048         $LFS setstripe -d $DIR/$tdir
3049
3050         save_layout_restore_at_exit $MOUNT
3051         # Now test that append striping works when layout is from root
3052         $LFS setstripe -c 2 $MOUNT
3053         # Make a special directory for this
3054         mkdir $DIR/${tdir}/${tdir}.2
3055
3056         # Verify for normal file
3057         setcount=2
3058         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3059         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3060         [ $count -eq $setcount ] ||
3061                 error "(8) stripe count $count, should be $setcount"
3062
3063         appendcount=1
3064         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3065         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3066         [ $count -eq $appendcount ] ||
3067                 error "(9) stripe count $count, should be $appendcount for append"
3068
3069         # Now test O_APPEND striping with pools
3070         pool_add $TESTNAME || error "pool creation failed"
3071         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3072         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3073
3074         echo 1 >> $DIR/$tdir/${tfile}.10_append
3075
3076         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3077         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3078
3079         # Check that count is still correct
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.11_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(11) stripe count $count, should be $appendcount for append"
3085
3086         # Disable O_APPEND stripe count, verify pool works separately
3087         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3088
3089         echo 1 >> $DIR/$tdir/${tfile}.12_append
3090
3091         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3092         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3093
3094         # Remove pool setting, verify it's not applied
3095         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.13_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3100         [ "$pool" = "" ] || error "(13) pool found: $pool"
3101 }
3102 run_test 27M "test O_APPEND striping"
3103
3104 test_27N() {
3105         combined_mgs_mds && skip "needs separate MGS/MDT"
3106
3107         pool_add $TESTNAME || error "pool_add failed"
3108         do_facet mgs "$LCTL pool_list $FSNAME" |
3109                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3110                 error "lctl pool_list on MGS failed"
3111 }
3112 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3113
3114 clean_foreign_symlink() {
3115         trap 0
3116         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3117         for i in $DIR/$tdir/* ; do
3118                 $LFS unlink_foreign $i || true
3119         done
3120 }
3121
3122 test_27O() {
3123         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3124                 skip "Need MDS version newer than 2.12.51"
3125
3126         test_mkdir $DIR/$tdir
3127         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3128         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3129
3130         trap clean_foreign_symlink EXIT
3131
3132         # enable foreign_symlink behaviour
3133         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3134
3135         # foreign symlink LOV format is a partial path by default
3136
3137         # create foreign file (lfs + API)
3138         $LFS setstripe --foreign=symlink --flags 0xda05 \
3139                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3140                 error "$DIR/$tdir/${tfile}: create failed"
3141
3142         $LFS getstripe -v $DIR/$tdir/${tfile} |
3143                 grep "lfm_magic:.*0x0BD70BD0" ||
3144                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3145         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} |
3148                 grep "lfm_flags:.*0x0000DA05" ||
3149                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3150         $LFS getstripe $DIR/$tdir/${tfile} |
3151                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3153
3154         # modify striping should fail
3155         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3156                 error "$DIR/$tdir/$tfile: setstripe should fail"
3157
3158         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3159         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3160         cat /etc/passwd > $DIR/$tdir/$tfile &&
3161                 error "$DIR/$tdir/$tfile: write should fail"
3162
3163         # rename should succeed
3164         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3165                 error "$DIR/$tdir/$tfile: rename has failed"
3166
3167         #remove foreign_symlink file should fail
3168         rm $DIR/$tdir/${tfile}.new &&
3169                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3170
3171         #test fake symlink
3172         mkdir /tmp/${uuid1} ||
3173                 error "/tmp/${uuid1}: mkdir has failed"
3174         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3175                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3176         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3177         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3178                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3179         #read should succeed now
3180         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3181                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3182         #write should succeed now
3183         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3184                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3185         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3187         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3188                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3189
3190         #check that getstripe still works
3191         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3193
3194         # chmod should still succeed
3195         chmod 644 $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3197
3198         # chown should still succeed
3199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3201
3202         # rename should still succeed
3203         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3204                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3205
3206         #remove foreign_symlink file should still fail
3207         rm $DIR/$tdir/${tfile} &&
3208                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3209
3210         #use special ioctl() to unlink foreign_symlink file
3211         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3213
3214 }
3215 run_test 27O "basic ops on foreign file of symlink type"
3216
3217 test_27P() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3219                 skip "Need MDS version newer than 2.12.49"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LMV format is a partial path by default
3231
3232         # create foreign dir (lfs + API)
3233         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3234                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3235                 error "$DIR/$tdir/${tdir}: create failed"
3236
3237         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27T() {
3377         [ $(facet_host client) == $(facet_host ost1) ] &&
3378                 skip "need ost1 and client on different nodes"
3379
3380 #define OBD_FAIL_OSC_NO_GRANT            0x411
3381         $LCTL set_param fail_loc=0x20000411 fail_val=1
3382 #define OBD_FAIL_OST_ENOSPC              0x215
3383         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3384         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3385         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3386                 error "multiop failed"
3387 }
3388 run_test 27T "no eio on close on partial write due to enosp"
3389
3390 test_27U() {
3391         local dir=$DIR/$tdir
3392         local file=$dir/$tfile
3393         local append_pool=${TESTNAME}-append
3394         local normal_pool=${TESTNAME}-normal
3395         local pool
3396         local stripe_count
3397         local stripe_count2
3398         local mdts=$(comma_list $(mdts_nodes))
3399
3400         # FIMXE
3401         # (( $MDS1_VERSION >= $(version_code 2.15.42) )) ||
3402         #       skip "Need MDS version at least 2.15.42"
3403
3404         # Validate existing append_* params and ensure restore
3405         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3406         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3407         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3408
3409         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3410         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3411         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3412
3413         pool_add $append_pool || error "pool creation failed"
3414         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3415
3416         pool_add $normal_pool || error "pool creation failed"
3417         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3418
3419         test_mkdir $dir
3420         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3421
3422         echo XXX >> $file.1
3423         $LFS getstripe $file.1
3424
3425         pool=$($LFS getstripe -p $file.1)
3426         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3427
3428         stripe_count2=$($LFS getstripe -c $file.1)
3429         ((stripe_count2 == stripe_count)) ||
3430                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3431
3432         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3433
3434         echo XXX >> $file.2
3435         $LFS getstripe $file.2
3436
3437         pool=$($LFS getstripe -p $file.2)
3438         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3439
3440         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3441
3442         echo XXX >> $file.3
3443         $LFS getstripe $file.3
3444
3445         stripe_count2=$($LFS getstripe -c $file.3)
3446         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3447 }
3448 run_test 27U "append pool and stripe count work with composite default layout"
3449
3450 # createtest also checks that device nodes are created and
3451 # then visible correctly (#2091)
3452 test_28() { # bug 2091
3453         test_mkdir $DIR/d28
3454         $CREATETEST $DIR/d28/ct || error "createtest failed"
3455 }
3456 run_test 28 "create/mknod/mkdir with bad file types ============"
3457
3458 test_29() {
3459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3460
3461         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3462                 disable_opencache
3463                 stack_trap "restore_opencache"
3464         }
3465
3466         sync; sleep 1; sync # flush out any dirty pages from previous tests
3467         cancel_lru_locks
3468         test_mkdir $DIR/d29
3469         touch $DIR/d29/foo
3470         log 'first d29'
3471         ls -l $DIR/d29
3472
3473         declare -i LOCKCOUNTORIG=0
3474         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3475                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3476         done
3477         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3478
3479         declare -i LOCKUNUSEDCOUNTORIG=0
3480         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3481                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3482         done
3483
3484         log 'second d29'
3485         ls -l $DIR/d29
3486         log 'done'
3487
3488         declare -i LOCKCOUNTCURRENT=0
3489         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3490                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3491         done
3492
3493         declare -i LOCKUNUSEDCOUNTCURRENT=0
3494         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3495                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3496         done
3497
3498         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3499                 $LCTL set_param -n ldlm.dump_namespaces ""
3500                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3501                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3502                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3503                 return 2
3504         fi
3505         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3506                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3507                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3508                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3509                 return 3
3510         fi
3511 }
3512 run_test 29 "IT_GETATTR regression  ============================"
3513
3514 test_30a() { # was test_30
3515         cp $(which ls) $DIR || cp /bin/ls $DIR
3516         $DIR/ls / || error "Can't execute binary from lustre"
3517         rm $DIR/ls
3518 }
3519 run_test 30a "execute binary from Lustre (execve) =============="
3520
3521 test_30b() {
3522         cp `which ls` $DIR || cp /bin/ls $DIR
3523         chmod go+rx $DIR/ls
3524         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3525         rm $DIR/ls
3526 }
3527 run_test 30b "execute binary from Lustre as non-root ==========="
3528
3529 test_30c() { # b=22376
3530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3531
3532         cp $(which ls) $DIR || cp /bin/ls $DIR
3533         chmod a-rw $DIR/ls
3534         cancel_lru_locks mdc
3535         cancel_lru_locks osc
3536         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3537         rm -f $DIR/ls
3538 }
3539 run_test 30c "execute binary from Lustre without read perms ===="
3540
3541 test_30d() {
3542         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3543
3544         for i in {1..10}; do
3545                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3546                 local PID=$!
3547                 sleep 1
3548                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3549                 wait $PID || error "executing dd from Lustre failed"
3550                 rm -f $DIR/$tfile
3551         done
3552
3553         rm -f $DIR/dd
3554 }
3555 run_test 30d "execute binary from Lustre while clear locks"
3556
3557 test_31a() {
3558         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3559         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3560 }
3561 run_test 31a "open-unlink file =================================="
3562
3563 test_31b() {
3564         touch $DIR/f31 || error "touch $DIR/f31 failed"
3565         ln $DIR/f31 $DIR/f31b || error "ln failed"
3566         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3567         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3568 }
3569 run_test 31b "unlink file with multiple links while open ======="
3570
3571 test_31c() {
3572         touch $DIR/f31 || error "touch $DIR/f31 failed"
3573         ln $DIR/f31 $DIR/f31c || error "ln failed"
3574         multiop_bg_pause $DIR/f31 O_uc ||
3575                 error "multiop_bg_pause for $DIR/f31 failed"
3576         MULTIPID=$!
3577         $MULTIOP $DIR/f31c Ouc
3578         kill -USR1 $MULTIPID
3579         wait $MULTIPID
3580 }
3581 run_test 31c "open-unlink file with multiple links ============="
3582
3583 test_31d() {
3584         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3585         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3586 }
3587 run_test 31d "remove of open directory ========================="
3588
3589 test_31e() { # bug 2904
3590         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3591 }
3592 run_test 31e "remove of open non-empty directory ==============="
3593
3594 test_31f() { # bug 4554
3595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3596
3597         set -vx
3598         test_mkdir $DIR/d31f
3599         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3600         cp /etc/hosts $DIR/d31f
3601         ls -l $DIR/d31f
3602         $LFS getstripe $DIR/d31f/hosts
3603         multiop_bg_pause $DIR/d31f D_c || return 1
3604         MULTIPID=$!
3605
3606         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3607         test_mkdir $DIR/d31f
3608         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3609         cp /etc/hosts $DIR/d31f
3610         ls -l $DIR/d31f
3611         $LFS getstripe $DIR/d31f/hosts
3612         multiop_bg_pause $DIR/d31f D_c || return 1
3613         MULTIPID2=$!
3614
3615         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3616         wait $MULTIPID || error "first opendir $MULTIPID failed"
3617
3618         sleep 6
3619
3620         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3621         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3622         set +vx
3623 }
3624 run_test 31f "remove of open directory with open-unlink file ==="
3625
3626 test_31g() {
3627         echo "-- cross directory link --"
3628         test_mkdir -c1 $DIR/${tdir}ga
3629         test_mkdir -c1 $DIR/${tdir}gb
3630         touch $DIR/${tdir}ga/f
3631         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3632         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3633         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3634         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3635         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3636 }
3637 run_test 31g "cross directory link==============="
3638
3639 test_31h() {
3640         echo "-- cross directory link --"
3641         test_mkdir -c1 $DIR/${tdir}
3642         test_mkdir -c1 $DIR/${tdir}/dir
3643         touch $DIR/${tdir}/f
3644         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3645         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3646         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3647         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3648         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3649 }
3650 run_test 31h "cross directory link under child==============="
3651
3652 test_31i() {
3653         echo "-- cross directory link --"
3654         test_mkdir -c1 $DIR/$tdir
3655         test_mkdir -c1 $DIR/$tdir/dir
3656         touch $DIR/$tdir/dir/f
3657         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3658         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3659         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3660         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3661         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3662 }
3663 run_test 31i "cross directory link under parent==============="
3664
3665 test_31j() {
3666         test_mkdir -c1 -p $DIR/$tdir
3667         test_mkdir -c1 -p $DIR/$tdir/dir1
3668         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3669         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3670         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3671         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3672         return 0
3673 }
3674 run_test 31j "link for directory==============="
3675
3676 test_31k() {
3677         test_mkdir -c1 -p $DIR/$tdir
3678         touch $DIR/$tdir/s
3679         touch $DIR/$tdir/exist
3680         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3681         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3682         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3683         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3684         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3685         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3686         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3687         return 0
3688 }
3689 run_test 31k "link to file: the same, non-existing, dir==============="
3690
3691 test_31m() {
3692         mkdir $DIR/d31m
3693         touch $DIR/d31m/s
3694         mkdir $DIR/d31m2
3695         touch $DIR/d31m2/exist
3696         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3697         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3698         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3699         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3700         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3701         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3702         return 0
3703 }
3704 run_test 31m "link to file: the same, non-existing, dir==============="
3705
3706 test_31n() {
3707         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3708         nlink=$(stat --format=%h $DIR/$tfile)
3709         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3710         local fd=$(free_fd)
3711         local cmd="exec $fd<$DIR/$tfile"
3712         eval $cmd
3713         cmd="exec $fd<&-"
3714         trap "eval $cmd" EXIT
3715         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3716         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3717         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3718         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3719         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3720         eval $cmd
3721 }
3722 run_test 31n "check link count of unlinked file"
3723
3724 link_one() {
3725         local tempfile=$(mktemp $1_XXXXXX)
3726         mlink $tempfile $1 2> /dev/null &&
3727                 echo "$BASHPID: link $tempfile to $1 succeeded"
3728         munlink $tempfile
3729 }
3730
3731 test_31o() { # LU-2901
3732         test_mkdir $DIR/$tdir
3733         for LOOP in $(seq 100); do
3734                 rm -f $DIR/$tdir/$tfile*
3735                 for THREAD in $(seq 8); do
3736                         link_one $DIR/$tdir/$tfile.$LOOP &
3737                 done
3738                 wait
3739                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3740                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3741                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3742                         break || true
3743         done
3744 }
3745 run_test 31o "duplicate hard links with same filename"
3746
3747 test_31p() {
3748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3752         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3753
3754         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3755                 error "open unlink test1 failed"
3756         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3757                 error "open unlink test2 failed"
3758
3759         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3760                 error "test1 still exists"
3761         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3762                 error "test2 still exists"
3763 }
3764 run_test 31p "remove of open striped directory"
3765
3766 test_31q() {
3767         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3768
3769         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3770         index=$($LFS getdirstripe -i $DIR/$tdir)
3771         [ $index -eq 3 ] || error "first stripe index $index != 3"
3772         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3773         [ $index -eq 1 ] || error "second stripe index $index != 1"
3774
3775         # when "-c <stripe_count>" is set, the number of MDTs specified after
3776         # "-i" should equal to the stripe count
3777         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3778 }
3779 run_test 31q "create striped directory on specific MDTs"
3780
3781 #LU-14949
3782 test_31r() {
3783         touch $DIR/$tfile.target
3784         touch $DIR/$tfile.source
3785
3786         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3787         $LCTL set_param fail_loc=0x1419 fail_val=3
3788         cat $DIR/$tfile.target &
3789         CATPID=$!
3790
3791         # Guarantee open is waiting before we get here
3792         sleep 1
3793         mv $DIR/$tfile.source $DIR/$tfile.target
3794
3795         wait $CATPID
3796         RC=$?
3797         if [[ $RC -ne 0 ]]; then
3798                 error "open with cat failed, rc=$RC"
3799         fi
3800 }
3801 run_test 31r "open-rename(replace) race"
3802
3803 cleanup_test32_mount() {
3804         local rc=0
3805         trap 0
3806         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3807         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3808         losetup -d $loopdev || true
3809         rm -rf $DIR/$tdir
3810         return $rc
3811 }
3812
3813 test_32a() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         echo "== more mountpoints and symlinks ================="
3817         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3818         trap cleanup_test32_mount EXIT
3819         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3820         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3821                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3822         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3823                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3824         cleanup_test32_mount
3825 }
3826 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3827
3828 test_32b() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3837                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3838         cleanup_test32_mount
3839 }
3840 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3841
3842 test_32c() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2/test_dir
3851         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3852                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3853         cleanup_test32_mount
3854 }
3855 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3856
3857 test_32d() {
3858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3859
3860         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3861         trap cleanup_test32_mount EXIT
3862         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3863         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3864                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3865         test_mkdir -p $DIR/$tdir/d2/test_dir
3866         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3867                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3868         cleanup_test32_mount
3869 }
3870 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3871
3872 test_32e() {
3873         rm -fr $DIR/$tdir
3874         test_mkdir -p $DIR/$tdir/tmp
3875         local tmp_dir=$DIR/$tdir/tmp
3876         ln -s $DIR/$tdir $tmp_dir/symlink11
3877         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3878         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3879         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3880 }
3881 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3882
3883 test_32f() {
3884         rm -fr $DIR/$tdir
3885         test_mkdir -p $DIR/$tdir/tmp
3886         local tmp_dir=$DIR/$tdir/tmp
3887         ln -s $DIR/$tdir $tmp_dir/symlink11
3888         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3889         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3890         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3891 }
3892 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3893
3894 test_32g() {
3895         local tmp_dir=$DIR/$tdir/tmp
3896         test_mkdir -p $tmp_dir
3897         test_mkdir $DIR/${tdir}2
3898         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3899         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3900         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3901         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3902         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3903         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3904 }
3905 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3906
3907 test_32h() {
3908         rm -fr $DIR/$tdir $DIR/${tdir}2
3909         tmp_dir=$DIR/$tdir/tmp
3910         test_mkdir -p $tmp_dir
3911         test_mkdir $DIR/${tdir}2
3912         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3913         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3914         ls $tmp_dir/symlink12 || error "listing symlink12"
3915         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3916 }
3917 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3918
3919 test_32i() {
3920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3921
3922         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3923         trap cleanup_test32_mount EXIT
3924         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3925         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3926                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3927         touch $DIR/$tdir/test_file
3928         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3929                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3930         cleanup_test32_mount
3931 }
3932 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3933
3934 test_32j() {
3935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3936
3937         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3938         trap cleanup_test32_mount EXIT
3939         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3940         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3941                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3942         touch $DIR/$tdir/test_file
3943         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3944                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3945         cleanup_test32_mount
3946 }
3947 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3948
3949 test_32k() {
3950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3951
3952         rm -fr $DIR/$tdir
3953         trap cleanup_test32_mount EXIT
3954         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3955         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3956                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3957         test_mkdir -p $DIR/$tdir/d2
3958         touch $DIR/$tdir/d2/test_file || error "touch failed"
3959         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3960                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3961         cleanup_test32_mount
3962 }
3963 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3964
3965 test_32l() {
3966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3967
3968         rm -fr $DIR/$tdir
3969         trap cleanup_test32_mount EXIT
3970         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3971         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3972                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3973         test_mkdir -p $DIR/$tdir/d2
3974         touch $DIR/$tdir/d2/test_file || error "touch failed"
3975         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3976                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3977         cleanup_test32_mount
3978 }
3979 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3980
3981 test_32m() {
3982         rm -fr $DIR/d32m
3983         test_mkdir -p $DIR/d32m/tmp
3984         TMP_DIR=$DIR/d32m/tmp
3985         ln -s $DIR $TMP_DIR/symlink11
3986         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3987         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3988                 error "symlink11 not a link"
3989         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3990                 error "symlink01 not a link"
3991 }
3992 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3993
3994 test_32n() {
3995         rm -fr $DIR/d32n
3996         test_mkdir -p $DIR/d32n/tmp
3997         TMP_DIR=$DIR/d32n/tmp
3998         ln -s $DIR $TMP_DIR/symlink11
3999         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4000         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4001         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4002 }
4003 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4004
4005 test_32o() {
4006         touch $DIR/$tfile
4007         test_mkdir -p $DIR/d32o/tmp
4008         TMP_DIR=$DIR/d32o/tmp
4009         ln -s $DIR/$tfile $TMP_DIR/symlink12
4010         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4011         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4012                 error "symlink12 not a link"
4013         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4014         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4015                 error "$DIR/d32o/tmp/symlink12 not file type"
4016         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4017                 error "$DIR/d32o/symlink02 not file type"
4018 }
4019 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4020
4021 test_32p() {
4022         log 32p_1
4023         rm -fr $DIR/d32p
4024         log 32p_2
4025         rm -f $DIR/$tfile
4026         log 32p_3
4027         touch $DIR/$tfile
4028         log 32p_4
4029         test_mkdir -p $DIR/d32p/tmp
4030         log 32p_5
4031         TMP_DIR=$DIR/d32p/tmp
4032         log 32p_6
4033         ln -s $DIR/$tfile $TMP_DIR/symlink12
4034         log 32p_7
4035         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4036         log 32p_8
4037         cat $DIR/d32p/tmp/symlink12 ||
4038                 error "Can't open $DIR/d32p/tmp/symlink12"
4039         log 32p_9
4040         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4041         log 32p_10
4042 }
4043 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4044
4045 test_32q() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4055         cleanup_test32_mount
4056 }
4057 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4058
4059 test_32r() {
4060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4061
4062         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4063         trap cleanup_test32_mount EXIT
4064         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4065         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4069         cleanup_test32_mount
4070 }
4071 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4072
4073 test_33aa() {
4074         rm -f $DIR/$tfile
4075         touch $DIR/$tfile
4076         chmod 444 $DIR/$tfile
4077         chown $RUNAS_ID $DIR/$tfile
4078         log 33_1
4079         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4080         log 33_2
4081 }
4082 run_test 33aa "write file with mode 444 (should return error)"
4083
4084 test_33a() {
4085         rm -fr $DIR/$tdir
4086         test_mkdir $DIR/$tdir
4087         chown $RUNAS_ID $DIR/$tdir
4088         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4089                 error "$RUNAS create $tdir/$tfile failed"
4090         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4091                 error "open RDWR" || true
4092 }
4093 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4094
4095 test_33b() {
4096         rm -fr $DIR/$tdir
4097         test_mkdir $DIR/$tdir
4098         chown $RUNAS_ID $DIR/$tdir
4099         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4100 }
4101 run_test 33b "test open file with malformed flags (No panic)"
4102
4103 test_33c() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105         remote_ost_nodsh && skip "remote OST with nodsh"
4106
4107         local ostnum
4108         local ostname
4109         local write_bytes
4110         local all_zeros
4111
4112         all_zeros=true
4113         test_mkdir $DIR/$tdir
4114         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4115
4116         sync
4117         for ostnum in $(seq $OSTCOUNT); do
4118                 # test-framework's OST numbering is one-based, while Lustre's
4119                 # is zero-based
4120                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4121                 # check if at least some write_bytes stats are counted
4122                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4123                               obdfilter.$ostname.stats |
4124                               awk '/^write_bytes/ {print $7}' )
4125                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4126                 if (( ${write_bytes:-0} > 0 )); then
4127                         all_zeros=false
4128                         break
4129                 fi
4130         done
4131
4132         $all_zeros || return 0
4133
4134         # Write four bytes
4135         echo foo > $DIR/$tdir/bar
4136         # Really write them
4137         sync
4138
4139         # Total up write_bytes after writing.  We'd better find non-zeros.
4140         for ostnum in $(seq $OSTCOUNT); do
4141                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4142                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4143                               obdfilter/$ostname/stats |
4144                               awk '/^write_bytes/ {print $7}' )
4145                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4146                 if (( ${write_bytes:-0} > 0 )); then
4147                         all_zeros=false
4148                         break
4149                 fi
4150         done
4151
4152         if $all_zeros; then
4153                 for ostnum in $(seq $OSTCOUNT); do
4154                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4155                         echo "Check write_bytes is in obdfilter.*.stats:"
4156                         do_facet ost$ostnum lctl get_param -n \
4157                                 obdfilter.$ostname.stats
4158                 done
4159                 error "OST not keeping write_bytes stats (b=22312)"
4160         fi
4161 }
4162 run_test 33c "test write_bytes stats"
4163
4164 test_33d() {
4165         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4167
4168         local MDTIDX=1
4169         local remote_dir=$DIR/$tdir/remote_dir
4170
4171         test_mkdir $DIR/$tdir
4172         $LFS mkdir -i $MDTIDX $remote_dir ||
4173                 error "create remote directory failed"
4174
4175         touch $remote_dir/$tfile
4176         chmod 444 $remote_dir/$tfile
4177         chown $RUNAS_ID $remote_dir/$tfile
4178
4179         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4180
4181         chown $RUNAS_ID $remote_dir
4182         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4183                                         error "create" || true
4184         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4185                                     error "open RDWR" || true
4186         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4187 }
4188 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4189
4190 test_33e() {
4191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4192
4193         mkdir $DIR/$tdir
4194
4195         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4196         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4197         mkdir $DIR/$tdir/local_dir
4198
4199         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4200         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4201         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4202
4203         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4204                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4205
4206         rmdir $DIR/$tdir/* || error "rmdir failed"
4207
4208         umask 777
4209         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4210         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4211         mkdir $DIR/$tdir/local_dir
4212
4213         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4214         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4215         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4216
4217         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4218                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4219
4220         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4221
4222         umask 000
4223         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4224         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4225         mkdir $DIR/$tdir/local_dir
4226
4227         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4228         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4229         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4230
4231         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4232                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4233 }
4234 run_test 33e "mkdir and striped directory should have same mode"
4235
4236 cleanup_33f() {
4237         trap 0
4238         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4239 }
4240
4241 test_33f() {
4242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4243         remote_mds_nodsh && skip "remote MDS with nodsh"
4244
4245         mkdir $DIR/$tdir
4246         chmod go+rwx $DIR/$tdir
4247         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4248         trap cleanup_33f EXIT
4249
4250         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4251                 error "cannot create striped directory"
4252
4253         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4254                 error "cannot create files in striped directory"
4255
4256         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4257                 error "cannot remove files in striped directory"
4258
4259         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4260                 error "cannot remove striped directory"
4261
4262         cleanup_33f
4263 }
4264 run_test 33f "nonroot user can create, access, and remove a striped directory"
4265
4266 test_33g() {
4267         mkdir -p $DIR/$tdir/dir2
4268
4269         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4270         echo $err
4271         [[ $err =~ "exists" ]] || error "Not exists error"
4272 }
4273 run_test 33g "nonroot user create already existing root created file"
4274
4275 sub_33h() {
4276         local hash_type=$1
4277         local count=250
4278
4279         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4280                 error "lfs mkdir -H $hash_type $tdir failed"
4281         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4282
4283         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4284         local index2
4285         local fname
4286
4287         for fname in $DIR/$tdir/$tfile.bak \
4288                      $DIR/$tdir/$tfile.SAV \
4289                      $DIR/$tdir/$tfile.orig \
4290                      $DIR/$tdir/$tfile~; do
4291                 touch $fname || error "touch $fname failed"
4292                 index2=$($LFS getstripe -m $fname)
4293                 (( $index == $index2 )) ||
4294                         error "$fname MDT index mismatch $index != $index2"
4295         done
4296
4297         local failed=0
4298         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4299         local pattern
4300
4301         for pattern in ${patterns[*]}; do
4302                 echo "pattern $pattern"
4303                 fname=$DIR/$tdir/$pattern
4304                 for (( i = 0; i < $count; i++ )); do
4305                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4306                                 error "mktemp $DIR/$tdir/$pattern failed"
4307                         index2=$($LFS getstripe -m $fname)
4308                         (( $index == $index2 )) && continue
4309
4310                         failed=$((failed + 1))
4311                         echo "$fname MDT index mismatch $index != $index2"
4312                 done
4313         done
4314
4315         echo "$failed/$count MDT index mismatches, expect ~2-4"
4316         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4317
4318         local same=0
4319         local expect
4320
4321         # verify that "crush" is still broken with all files on same MDT,
4322         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4323         [[ "$hash_type" == "crush" ]] && expect=$count ||
4324                 expect=$((count / MDSCOUNT))
4325
4326         # crush2 doesn't put all-numeric suffixes on the same MDT,
4327         # filename like $tfile.12345678 should *not* be considered temp
4328         for pattern in ${patterns[*]}; do
4329                 local base=${pattern%%X*}
4330                 local suff=${pattern#$base}
4331
4332                 echo "pattern $pattern"
4333                 for (( i = 0; i < $count; i++ )); do
4334                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4335                         touch $fname || error "touch $fname failed"
4336                         index2=$($LFS getstripe -m $fname)
4337                         (( $index != $index2 )) && continue
4338
4339                         same=$((same + 1))
4340                 done
4341         done
4342
4343         # the number of "bad" hashes is random, as it depends on the random
4344         # filenames generated by "mktemp".  Allow some margin in the results.
4345         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4346         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4347            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4348                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4349         same=0
4350
4351         # crush2 doesn't put suffixes with special characters on the same MDT
4352         # filename like $tfile.txt.1234 should *not* be considered temp
4353         for pattern in ${patterns[*]}; do
4354                 local base=${pattern%%X*}
4355                 local suff=${pattern#$base}
4356
4357                 pattern=$base...${suff/XXX}
4358                 echo "pattern=$pattern"
4359                 for (( i = 0; i < $count; i++ )); do
4360                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4361                                 error "touch $fname failed"
4362                         index2=$($LFS getstripe -m $fname)
4363                         (( $index != $index2 )) && continue
4364
4365                         same=$((same + 1))
4366                 done
4367         done
4368
4369         # the number of "bad" hashes is random, as it depends on the random
4370         # filenames generated by "mktemp".  Allow some margin in the results.
4371         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4372         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4373            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4374                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4375 }
4376
4377 test_33h() {
4378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4379         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4380                 skip "Need MDS version at least 2.13.50"
4381
4382         sub_33h crush
4383 }
4384 run_test 33h "temp file is located on the same MDT as target (crush)"
4385
4386 test_33hh() {
4387         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4388         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4389         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4390                 skip "Need MDS version at least 2.15.0 for crush2"
4391
4392         sub_33h crush2
4393 }
4394 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4395
4396 test_33i()
4397 {
4398         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4399
4400         local FNAME=$(str_repeat 'f' 250)
4401
4402         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4403         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4404
4405         local count
4406         local total
4407
4408         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4409
4410         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4411
4412         lctl --device %$MDC deactivate
4413         stack_trap "lctl --device %$MDC activate"
4414         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4415         total=$(\ls -l $DIR/$tdir | wc -l)
4416         # "ls -l" will list total in the first line
4417         total=$((total - 1))
4418         (( total + count == 1000 )) ||
4419                 error "ls list $total files, $count files on MDT1"
4420 }
4421 run_test 33i "striped directory can be accessed when one MDT is down"
4422
4423 test_33j() {
4424         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4425
4426         mkdir -p $DIR/$tdir/
4427
4428         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4429                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4430
4431         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4432                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4433
4434         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4435                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4436
4437         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4438                 error "-D was not specified, but still failed"
4439 }
4440 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4441
4442 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4443 test_34a() {
4444         rm -f $DIR/f34
4445         $MCREATE $DIR/f34 || error "mcreate failed"
4446         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4447                 error "getstripe failed"
4448         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4449         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4450                 error "getstripe failed"
4451         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4452                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4453 }
4454 run_test 34a "truncate file that has not been opened ==========="
4455
4456 test_34b() {
4457         [ ! -f $DIR/f34 ] && test_34a
4458         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4459                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4460         $OPENFILE -f O_RDONLY $DIR/f34
4461         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4462                 error "getstripe failed"
4463         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4464                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4465 }
4466 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4467
4468 test_34c() {
4469         [ ! -f $DIR/f34 ] && test_34a
4470         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4471                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4472         $OPENFILE -f O_RDWR $DIR/f34
4473         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4474                 error "$LFS getstripe failed"
4475         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4476                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4477 }
4478 run_test 34c "O_RDWR opening file-with-size works =============="
4479
4480 test_34d() {
4481         [ ! -f $DIR/f34 ] && test_34a
4482         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4483                 error "dd failed"
4484         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4485                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4486         rm $DIR/f34
4487 }
4488 run_test 34d "write to sparse file ============================="
4489
4490 test_34e() {
4491         rm -f $DIR/f34e
4492         $MCREATE $DIR/f34e || error "mcreate failed"
4493         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4494         $CHECKSTAT -s 1000 $DIR/f34e ||
4495                 error "Size of $DIR/f34e not equal to 1000 bytes"
4496         $OPENFILE -f O_RDWR $DIR/f34e
4497         $CHECKSTAT -s 1000 $DIR/f34e ||
4498                 error "Size of $DIR/f34e not equal to 1000 bytes"
4499 }
4500 run_test 34e "create objects, some with size and some without =="
4501
4502 test_34f() { # bug 6242, 6243
4503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4504
4505         SIZE34F=48000
4506         rm -f $DIR/f34f
4507         $MCREATE $DIR/f34f || error "mcreate failed"
4508         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4509         dd if=$DIR/f34f of=$TMP/f34f
4510         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4511         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4512         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4513         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4514         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4515 }
4516 run_test 34f "read from a file with no objects until EOF ======="
4517
4518 test_34g() {
4519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4520
4521         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4522                 error "dd failed"
4523         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4524         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4525                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4526         cancel_lru_locks osc
4527         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4528                 error "wrong size after lock cancel"
4529
4530         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4531         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4532                 error "expanding truncate failed"
4533         cancel_lru_locks osc
4534         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4535                 error "wrong expanded size after lock cancel"
4536 }
4537 run_test 34g "truncate long file ==============================="
4538
4539 test_34h() {
4540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4541
4542         local gid=10
4543         local sz=1000
4544
4545         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4546         sync # Flush the cache so that multiop below does not block on cache
4547              # flush when getting the group lock
4548         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4549         MULTIPID=$!
4550
4551         # Since just timed wait is not good enough, let's do a sync write
4552         # that way we are sure enough time for a roundtrip + processing
4553         # passed + 2 seconds of extra margin.
4554         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4555         rm $DIR/${tfile}-1
4556         sleep 2
4557
4558         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4559                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4560                 kill -9 $MULTIPID
4561         fi
4562         wait $MULTIPID
4563         local nsz=`stat -c %s $DIR/$tfile`
4564         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4565 }
4566 run_test 34h "ftruncate file under grouplock should not block"
4567
4568 test_35a() {
4569         cp /bin/sh $DIR/f35a
4570         chmod 444 $DIR/f35a
4571         chown $RUNAS_ID $DIR/f35a
4572         $RUNAS $DIR/f35a && error || true
4573         rm $DIR/f35a
4574 }
4575 run_test 35a "exec file with mode 444 (should return and not leak)"
4576
4577 test_36a() {
4578         rm -f $DIR/f36
4579         utime $DIR/f36 || error "utime failed for MDS"
4580 }
4581 run_test 36a "MDS utime check (mknod, utime)"
4582
4583 test_36b() {
4584         echo "" > $DIR/f36
4585         utime $DIR/f36 || error "utime failed for OST"
4586 }
4587 run_test 36b "OST utime check (open, utime)"
4588
4589 test_36c() {
4590         rm -f $DIR/d36/f36
4591         test_mkdir $DIR/d36
4592         chown $RUNAS_ID $DIR/d36
4593         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4594 }
4595 run_test 36c "non-root MDS utime check (mknod, utime)"
4596
4597 test_36d() {
4598         [ ! -d $DIR/d36 ] && test_36c
4599         echo "" > $DIR/d36/f36
4600         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4601 }
4602 run_test 36d "non-root OST utime check (open, utime)"
4603
4604 test_36e() {
4605         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4606
4607         test_mkdir $DIR/$tdir
4608         touch $DIR/$tdir/$tfile
4609         $RUNAS utime $DIR/$tdir/$tfile &&
4610                 error "utime worked, expected failure" || true
4611 }
4612 run_test 36e "utime on non-owned file (should return error)"
4613
4614 subr_36fh() {
4615         local fl="$1"
4616         local LANG_SAVE=$LANG
4617         local LC_LANG_SAVE=$LC_LANG
4618         export LANG=C LC_LANG=C # for date language
4619
4620         DATESTR="Dec 20  2000"
4621         test_mkdir $DIR/$tdir
4622         lctl set_param fail_loc=$fl
4623         date; date +%s
4624         cp /etc/hosts $DIR/$tdir/$tfile
4625         sync & # write RPC generated with "current" inode timestamp, but delayed
4626         sleep 1
4627         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4628         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4629         cancel_lru_locks $OSC
4630         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4631         date; date +%s
4632         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4633                 echo "BEFORE: $LS_BEFORE" && \
4634                 echo "AFTER : $LS_AFTER" && \
4635                 echo "WANT  : $DATESTR" && \
4636                 error "$DIR/$tdir/$tfile timestamps changed" || true
4637
4638         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4639 }
4640
4641 test_36f() {
4642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4643
4644         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4645         subr_36fh "0x80000214"
4646 }
4647 run_test 36f "utime on file racing with OST BRW write =========="
4648
4649 test_36g() {
4650         remote_ost_nodsh && skip "remote OST with nodsh"
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4653                 skip "Need MDS version at least 2.12.51"
4654
4655         local fmd_max_age
4656         local fmd
4657         local facet="ost1"
4658         local tgt="obdfilter"
4659
4660         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4661
4662         test_mkdir $DIR/$tdir
4663         fmd_max_age=$(do_facet $facet \
4664                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4665                 head -n 1")
4666
4667         echo "FMD max age: ${fmd_max_age}s"
4668         touch $DIR/$tdir/$tfile
4669         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4670                 gawk '{cnt=cnt+$1}  END{print cnt}')
4671         echo "FMD before: $fmd"
4672         [[ $fmd == 0 ]] &&
4673                 error "FMD wasn't create by touch"
4674         sleep $((fmd_max_age + 12))
4675         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4676                 gawk '{cnt=cnt+$1}  END{print cnt}')
4677         echo "FMD after: $fmd"
4678         [[ $fmd == 0 ]] ||
4679                 error "FMD wasn't expired by ping"
4680 }
4681 run_test 36g "FMD cache expiry ====================="
4682
4683 test_36h() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4687         subr_36fh "0x80000227"
4688 }
4689 run_test 36h "utime on file racing with OST BRW write =========="
4690
4691 test_36i() {
4692         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4693
4694         test_mkdir $DIR/$tdir
4695         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4696
4697         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4698         local new_mtime=$((mtime + 200))
4699
4700         #change Modify time of striped dir
4701         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4702                         error "change mtime failed"
4703
4704         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4705
4706         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4707 }
4708 run_test 36i "change mtime on striped directory"
4709
4710 # test_37 - duplicate with tests 32q 32r
4711
4712 test_38() {
4713         local file=$DIR/$tfile
4714         touch $file
4715         openfile -f O_DIRECTORY $file
4716         local RC=$?
4717         local ENOTDIR=20
4718         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4719         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4720 }
4721 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4722
4723 test_39a() { # was test_39
4724         touch $DIR/$tfile
4725         touch $DIR/${tfile}2
4726 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4727 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4728 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4729         sleep 2
4730         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4731         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4732                 echo "mtime"
4733                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4734                 echo "atime"
4735                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4736                 echo "ctime"
4737                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4738                 error "O_TRUNC didn't change timestamps"
4739         fi
4740 }
4741 run_test 39a "mtime changed on create"
4742
4743 test_39b() {
4744         test_mkdir -c1 $DIR/$tdir
4745         cp -p /etc/passwd $DIR/$tdir/fopen
4746         cp -p /etc/passwd $DIR/$tdir/flink
4747         cp -p /etc/passwd $DIR/$tdir/funlink
4748         cp -p /etc/passwd $DIR/$tdir/frename
4749         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4750
4751         sleep 1
4752         echo "aaaaaa" >> $DIR/$tdir/fopen
4753         echo "aaaaaa" >> $DIR/$tdir/flink
4754         echo "aaaaaa" >> $DIR/$tdir/funlink
4755         echo "aaaaaa" >> $DIR/$tdir/frename
4756
4757         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4758         local link_new=`stat -c %Y $DIR/$tdir/flink`
4759         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4760         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4761
4762         cat $DIR/$tdir/fopen > /dev/null
4763         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4764         rm -f $DIR/$tdir/funlink2
4765         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4769                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4770                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4771                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4772
4773                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4774                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4775                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4776                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4777
4778                 cancel_lru_locks $OSC
4779                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4780         done
4781 }
4782 run_test 39b "mtime change on open, link, unlink, rename  ======"
4783
4784 # this should be set to past
4785 TEST_39_MTIME=`date -d "1 year ago" +%s`
4786
4787 # bug 11063
4788 test_39c() {
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local mtime0=`stat -c %Y $DIR1/$tfile`
4792
4793         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4794         local mtime1=`stat -c %Y $DIR1/$tfile`
4795         [ "$mtime1" = $TEST_39_MTIME ] || \
4796                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4797
4798         local d1=`date +%s`
4799         echo hello >> $DIR1/$tfile
4800         local d2=`date +%s`
4801         local mtime2=`stat -c %Y $DIR1/$tfile`
4802         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4803                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4804
4805         mv $DIR1/$tfile $DIR1/$tfile-1
4806
4807         for (( i=0; i < 2; i++ )) ; do
4808                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4809                 [ "$mtime2" = "$mtime3" ] || \
4810                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4811
4812                 cancel_lru_locks $OSC
4813                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4814         done
4815 }
4816 run_test 39c "mtime change on rename ==========================="
4817
4818 # bug 21114
4819 test_39d() {
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821
4822         touch $DIR1/$tfile
4823         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4824
4825         for (( i=0; i < 2; i++ )) ; do
4826                 local mtime=`stat -c %Y $DIR1/$tfile`
4827                 [ $mtime = $TEST_39_MTIME ] || \
4828                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4829
4830                 cancel_lru_locks $OSC
4831                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4832         done
4833 }
4834 run_test 39d "create, utime, stat =============================="
4835
4836 # bug 21114
4837 test_39e() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         touch $DIR1/$tfile
4841         local mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4844
4845         for (( i=0; i < 2; i++ )) ; do
4846                 local mtime2=`stat -c %Y $DIR1/$tfile`
4847                 [ $mtime2 = $TEST_39_MTIME ] || \
4848                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4849
4850                 cancel_lru_locks $OSC
4851                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4852         done
4853 }
4854 run_test 39e "create, stat, utime, stat ========================"
4855
4856 # bug 21114
4857 test_39f() {
4858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4859
4860         touch $DIR1/$tfile
4861         mtime1=`stat -c %Y $DIR1/$tfile`
4862
4863         sleep 2
4864         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4865
4866         for (( i=0; i < 2; i++ )) ; do
4867                 local mtime2=`stat -c %Y $DIR1/$tfile`
4868                 [ $mtime2 = $TEST_39_MTIME ] || \
4869                         error "mtime($mtime2) 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 39f "create, stat, sleep, utime, stat ================="
4876
4877 # bug 11063
4878 test_39g() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         echo hello >> $DIR1/$tfile
4882         local mtime1=`stat -c %Y $DIR1/$tfile`
4883
4884         sleep 2
4885         chmod o+r $DIR1/$tfile
4886
4887         for (( i=0; i < 2; i++ )) ; do
4888                 local mtime2=`stat -c %Y $DIR1/$tfile`
4889                 [ "$mtime1" = "$mtime2" ] || \
4890                         error "lost mtime: $mtime2, should be $mtime1"
4891
4892                 cancel_lru_locks $OSC
4893                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4894         done
4895 }
4896 run_test 39g "write, chmod, stat ==============================="
4897
4898 # bug 11063
4899 test_39h() {
4900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4901
4902         touch $DIR1/$tfile
4903         sleep 1
4904
4905         local d1=`date`
4906         echo hello >> $DIR1/$tfile
4907         local mtime1=`stat -c %Y $DIR1/$tfile`
4908
4909         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4910         local d2=`date`
4911         if [ "$d1" != "$d2" ]; then
4912                 echo "write and touch not within one second"
4913         else
4914                 for (( i=0; i < 2; i++ )) ; do
4915                         local mtime2=`stat -c %Y $DIR1/$tfile`
4916                         [ "$mtime2" = $TEST_39_MTIME ] || \
4917                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4918
4919                         cancel_lru_locks $OSC
4920                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4921                 done
4922         fi
4923 }
4924 run_test 39h "write, utime within one second, stat ============="
4925
4926 test_39i() {
4927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4928
4929         touch $DIR1/$tfile
4930         sleep 1
4931
4932         echo hello >> $DIR1/$tfile
4933         local mtime1=`stat -c %Y $DIR1/$tfile`
4934
4935         mv $DIR1/$tfile $DIR1/$tfile-1
4936
4937         for (( i=0; i < 2; i++ )) ; do
4938                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4939
4940                 [ "$mtime1" = "$mtime2" ] || \
4941                         error "lost mtime: $mtime2, should be $mtime1"
4942
4943                 cancel_lru_locks $OSC
4944                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4945         done
4946 }
4947 run_test 39i "write, rename, stat =============================="
4948
4949 test_39j() {
4950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4951
4952         start_full_debug_logging
4953         touch $DIR1/$tfile
4954         sleep 1
4955
4956         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4957         lctl set_param fail_loc=0x80000412
4958         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4959                 error "multiop failed"
4960         local multipid=$!
4961         local mtime1=`stat -c %Y $DIR1/$tfile`
4962
4963         mv $DIR1/$tfile $DIR1/$tfile-1
4964
4965         kill -USR1 $multipid
4966         wait $multipid || error "multiop close failed"
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4970                 [ "$mtime1" = "$mtime2" ] ||
4971                         error "mtime is lost on close: $mtime2, " \
4972                               "should be $mtime1"
4973
4974                 cancel_lru_locks
4975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4976         done
4977         lctl set_param fail_loc=0
4978         stop_full_debug_logging
4979 }
4980 run_test 39j "write, rename, close, stat ======================="
4981
4982 test_39k() {
4983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4984
4985         touch $DIR1/$tfile
4986         sleep 1
4987
4988         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4989         local multipid=$!
4990         local mtime1=`stat -c %Y $DIR1/$tfile`
4991
4992         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4993
4994         kill -USR1 $multipid
4995         wait $multipid || error "multiop close failed"
4996
4997         for (( i=0; i < 2; i++ )) ; do
4998                 local mtime2=`stat -c %Y $DIR1/$tfile`
4999
5000                 [ "$mtime2" = $TEST_39_MTIME ] || \
5001                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5002
5003                 cancel_lru_locks
5004                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5005         done
5006 }
5007 run_test 39k "write, utime, close, stat ========================"
5008
5009 # this should be set to future
5010 TEST_39_ATIME=`date -d "1 year" +%s`
5011
5012 test_39l() {
5013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5014         remote_mds_nodsh && skip "remote MDS with nodsh"
5015
5016         local atime_diff=$(do_facet $SINGLEMDS \
5017                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5018         rm -rf $DIR/$tdir
5019         mkdir_on_mdt0 $DIR/$tdir
5020
5021         # test setting directory atime to future
5022         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5023         local atime=$(stat -c %X $DIR/$tdir)
5024         [ "$atime" = $TEST_39_ATIME ] ||
5025                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5026
5027         # test setting directory atime from future to now
5028         local now=$(date +%s)
5029         touch -a -d @$now $DIR/$tdir
5030
5031         atime=$(stat -c %X $DIR/$tdir)
5032         [ "$atime" -eq "$now"  ] ||
5033                 error "atime is not updated from future: $atime, $now"
5034
5035         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5036         sleep 3
5037
5038         # test setting directory atime when now > dir atime + atime_diff
5039         local d1=$(date +%s)
5040         ls $DIR/$tdir
5041         local d2=$(date +%s)
5042         cancel_lru_locks mdc
5043         atime=$(stat -c %X $DIR/$tdir)
5044         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5045                 error "atime is not updated  : $atime, should be $d2"
5046
5047         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5048         sleep 3
5049
5050         # test not setting directory atime when now < dir atime + atime_diff
5051         ls $DIR/$tdir
5052         cancel_lru_locks mdc
5053         atime=$(stat -c %X $DIR/$tdir)
5054         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5055                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5056
5057         do_facet $SINGLEMDS \
5058                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5059 }
5060 run_test 39l "directory atime update ==========================="
5061
5062 test_39m() {
5063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5064
5065         touch $DIR1/$tfile
5066         sleep 2
5067         local far_past_mtime=$(date -d "May 29 1953" +%s)
5068         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5069
5070         touch -m -d @$far_past_mtime $DIR1/$tfile
5071         touch -a -d @$far_past_atime $DIR1/$tfile
5072
5073         for (( i=0; i < 2; i++ )) ; do
5074                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5075                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5076                         error "atime or mtime set incorrectly"
5077
5078                 cancel_lru_locks $OSC
5079                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5080         done
5081 }
5082 run_test 39m "test atime and mtime before 1970"
5083
5084 test_39n() { # LU-3832
5085         remote_mds_nodsh && skip "remote MDS with nodsh"
5086
5087         local atime_diff=$(do_facet $SINGLEMDS \
5088                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5089         local atime0
5090         local atime1
5091         local atime2
5092
5093         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5094
5095         rm -rf $DIR/$tfile
5096         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5097         atime0=$(stat -c %X $DIR/$tfile)
5098
5099         sleep 5
5100         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5101         atime1=$(stat -c %X $DIR/$tfile)
5102
5103         sleep 5
5104         cancel_lru_locks mdc
5105         cancel_lru_locks osc
5106         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5107         atime2=$(stat -c %X $DIR/$tfile)
5108
5109         do_facet $SINGLEMDS \
5110                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5111
5112         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5113         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5114 }
5115 run_test 39n "check that O_NOATIME is honored"
5116
5117 test_39o() {
5118         TESTDIR=$DIR/$tdir/$tfile
5119         [ -e $TESTDIR ] && rm -rf $TESTDIR
5120         mkdir -p $TESTDIR
5121         cd $TESTDIR
5122         links1=2
5123         ls
5124         mkdir a b
5125         ls
5126         links2=$(stat -c %h .)
5127         [ $(($links1 + 2)) != $links2 ] &&
5128                 error "wrong links count $(($links1 + 2)) != $links2"
5129         rmdir b
5130         links3=$(stat -c %h .)
5131         [ $(($links1 + 1)) != $links3 ] &&
5132                 error "wrong links count $links1 != $links3"
5133         return 0
5134 }
5135 run_test 39o "directory cached attributes updated after create"
5136
5137 test_39p() {
5138         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5139
5140         local MDTIDX=1
5141         TESTDIR=$DIR/$tdir/$tdir
5142         [ -e $TESTDIR ] && rm -rf $TESTDIR
5143         test_mkdir -p $TESTDIR
5144         cd $TESTDIR
5145         links1=2
5146         ls
5147         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5148         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5149         ls
5150         links2=$(stat -c %h .)
5151         [ $(($links1 + 2)) != $links2 ] &&
5152                 error "wrong links count $(($links1 + 2)) != $links2"
5153         rmdir remote_dir2
5154         links3=$(stat -c %h .)
5155         [ $(($links1 + 1)) != $links3 ] &&
5156                 error "wrong links count $links1 != $links3"
5157         return 0
5158 }
5159 run_test 39p "remote directory cached attributes updated after create ========"
5160
5161 test_39r() {
5162         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5163                 skip "no atime update on old OST"
5164         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5165                 skip_env "ldiskfs only test"
5166         fi
5167
5168         local saved_adiff
5169         saved_adiff=$(do_facet ost1 \
5170                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5171         stack_trap "do_facet ost1 \
5172                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5173
5174         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5175
5176         $LFS setstripe -i 0 $DIR/$tfile
5177         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5178                 error "can't write initial file"
5179         cancel_lru_locks osc
5180
5181         # exceed atime_diff and access file
5182         sleep 10
5183         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5184                 error "can't udpate atime"
5185
5186         local atime_cli=$(stat -c %X $DIR/$tfile)
5187         echo "client atime: $atime_cli"
5188         # allow atime update to be written to device
5189         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5190         sleep 5
5191
5192         local ostdev=$(ostdevname 1)
5193         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5194         local seq=${fid[3]#0x}
5195         local oid=${fid[1]}
5196         local oid_hex
5197
5198         if [ $seq == 0 ]; then
5199                 oid_hex=${fid[1]}
5200         else
5201                 oid_hex=${fid[2]#0x}
5202         fi
5203         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5204         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5205
5206         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5207         local atime_ost=$(do_facet ost1 "$cmd" |&
5208                           awk -F'[: ]' '/atime:/ { print $4 }')
5209         (( atime_cli == atime_ost )) ||
5210                 error "atime on client $atime_cli != ost $atime_ost"
5211 }
5212 run_test 39r "lazy atime update on OST"
5213
5214 test_39q() { # LU-8041
5215         local testdir=$DIR/$tdir
5216         mkdir -p $testdir
5217         multiop_bg_pause $testdir D_c || error "multiop failed"
5218         local multipid=$!
5219         cancel_lru_locks mdc
5220         kill -USR1 $multipid
5221         local atime=$(stat -c %X $testdir)
5222         [ "$atime" -ne 0 ] || error "atime is zero"
5223 }
5224 run_test 39q "close won't zero out atime"
5225
5226 test_40() {
5227         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5228         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5229                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5230         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5231                 error "$tfile is not 4096 bytes in size"
5232 }
5233 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5234
5235 test_41() {
5236         # bug 1553
5237         small_write $DIR/f41 18
5238 }
5239 run_test 41 "test small file write + fstat ====================="
5240
5241 count_ost_writes() {
5242         lctl get_param -n ${OSC}.*.stats |
5243                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5244                         END { printf("%0.0f", writes) }'
5245 }
5246
5247 # decent default
5248 WRITEBACK_SAVE=500
5249 DIRTY_RATIO_SAVE=40
5250 MAX_DIRTY_RATIO=50
5251 BG_DIRTY_RATIO_SAVE=10
5252 MAX_BG_DIRTY_RATIO=25
5253
5254 start_writeback() {
5255         trap 0
5256         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5257         # dirty_ratio, dirty_background_ratio
5258         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5259                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5260                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5261                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5262         else
5263                 # if file not here, we are a 2.4 kernel
5264                 kill -CONT `pidof kupdated`
5265         fi
5266 }
5267
5268 stop_writeback() {
5269         # setup the trap first, so someone cannot exit the test at the
5270         # exact wrong time and mess up a machine
5271         trap start_writeback EXIT
5272         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5273         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5274                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5275                 sysctl -w vm.dirty_writeback_centisecs=0
5276                 sysctl -w vm.dirty_writeback_centisecs=0
5277                 # save and increase /proc/sys/vm/dirty_ratio
5278                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5279                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5280                 # save and increase /proc/sys/vm/dirty_background_ratio
5281                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5282                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5283         else
5284                 # if file not here, we are a 2.4 kernel
5285                 kill -STOP `pidof kupdated`
5286         fi
5287 }
5288
5289 # ensure that all stripes have some grant before we test client-side cache
5290 setup_test42() {
5291         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5292                 dd if=/dev/zero of=$i bs=4k count=1
5293                 rm $i
5294         done
5295 }
5296
5297 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5298 # file truncation, and file removal.
5299 test_42a() {
5300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5301
5302         setup_test42
5303         cancel_lru_locks $OSC
5304         stop_writeback
5305         sync; sleep 1; sync # just to be safe
5306         BEFOREWRITES=`count_ost_writes`
5307         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5308         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5309         AFTERWRITES=`count_ost_writes`
5310         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5311                 error "$BEFOREWRITES < $AFTERWRITES"
5312         start_writeback
5313 }
5314 run_test 42a "ensure that we don't flush on close"
5315
5316 test_42b() {
5317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5318
5319         setup_test42
5320         cancel_lru_locks $OSC
5321         stop_writeback
5322         sync
5323         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5324         BEFOREWRITES=$(count_ost_writes)
5325         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5326         AFTERWRITES=$(count_ost_writes)
5327         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5328                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5329         fi
5330         BEFOREWRITES=$(count_ost_writes)
5331         sync || error "sync: $?"
5332         AFTERWRITES=$(count_ost_writes)
5333         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5334                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5335         fi
5336         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5337         start_writeback
5338         return 0
5339 }
5340 run_test 42b "test destroy of file with cached dirty data ======"
5341
5342 # if these tests just want to test the effect of truncation,
5343 # they have to be very careful.  consider:
5344 # - the first open gets a {0,EOF}PR lock
5345 # - the first write conflicts and gets a {0, count-1}PW
5346 # - the rest of the writes are under {count,EOF}PW
5347 # - the open for truncate tries to match a {0,EOF}PR
5348 #   for the filesize and cancels the PWs.
5349 # any number of fixes (don't get {0,EOF} on open, match
5350 # composite locks, do smarter file size management) fix
5351 # this, but for now we want these tests to verify that
5352 # the cancellation with truncate intent works, so we
5353 # start the file with a full-file pw lock to match against
5354 # until the truncate.
5355 trunc_test() {
5356         test=$1
5357         file=$DIR/$test
5358         offset=$2
5359         cancel_lru_locks $OSC
5360         stop_writeback
5361         # prime the file with 0,EOF PW to match
5362         touch $file
5363         $TRUNCATE $file 0
5364         sync; sync
5365         # now the real test..
5366         dd if=/dev/zero of=$file bs=1024 count=100
5367         BEFOREWRITES=`count_ost_writes`
5368         $TRUNCATE $file $offset
5369         cancel_lru_locks $OSC
5370         AFTERWRITES=`count_ost_writes`
5371         start_writeback
5372 }
5373
5374 test_42c() {
5375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5376
5377         trunc_test 42c 1024
5378         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5379                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5380         rm $file
5381 }
5382 run_test 42c "test partial truncate of file with cached dirty data"
5383
5384 test_42d() {
5385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5386
5387         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5388         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5389         $LCTL set_param debug=+cache
5390
5391         trunc_test 42d 0
5392         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5393                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5394         rm $file
5395 }
5396 run_test 42d "test complete truncate of file with cached dirty data"
5397
5398 test_42e() { # bug22074
5399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5400
5401         local TDIR=$DIR/${tdir}e
5402         local pages=16 # hardcoded 16 pages, don't change it.
5403         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5404         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5405         local max_dirty_mb
5406         local warmup_files
5407
5408         test_mkdir $DIR/${tdir}e
5409         $LFS setstripe -c 1 $TDIR
5410         createmany -o $TDIR/f $files
5411
5412         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5413
5414         # we assume that with $OSTCOUNT files, at least one of them will
5415         # be allocated on OST0.
5416         warmup_files=$((OSTCOUNT * max_dirty_mb))
5417         createmany -o $TDIR/w $warmup_files
5418
5419         # write a large amount of data into one file and sync, to get good
5420         # avail_grant number from OST.
5421         for ((i=0; i<$warmup_files; i++)); do
5422                 idx=$($LFS getstripe -i $TDIR/w$i)
5423                 [ $idx -ne 0 ] && continue
5424                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5425                 break
5426         done
5427         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5428         sync
5429         $LCTL get_param $proc_osc0/cur_dirty_bytes
5430         $LCTL get_param $proc_osc0/cur_grant_bytes
5431
5432         # create as much dirty pages as we can while not to trigger the actual
5433         # RPCs directly. but depends on the env, VFS may trigger flush during this
5434         # period, hopefully we are good.
5435         for ((i=0; i<$warmup_files; i++)); do
5436                 idx=$($LFS getstripe -i $TDIR/w$i)
5437                 [ $idx -ne 0 ] && continue
5438                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5439         done
5440         $LCTL get_param $proc_osc0/cur_dirty_bytes
5441         $LCTL get_param $proc_osc0/cur_grant_bytes
5442
5443         # perform the real test
5444         $LCTL set_param $proc_osc0/rpc_stats 0
5445         for ((;i<$files; i++)); do
5446                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5447                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5448         done
5449         sync
5450         $LCTL get_param $proc_osc0/rpc_stats
5451
5452         local percent=0
5453         local have_ppr=false
5454         $LCTL get_param $proc_osc0/rpc_stats |
5455                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5456                         # skip lines until we are at the RPC histogram data
5457                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5458                         $have_ppr || continue
5459
5460                         # we only want the percent stat for < 16 pages
5461                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5462
5463                         percent=$((percent + WPCT))
5464                         if [[ $percent -gt 15 ]]; then
5465                                 error "less than 16-pages write RPCs" \
5466                                       "$percent% > 15%"
5467                                 break
5468                         fi
5469                 done
5470         rm -rf $TDIR
5471 }
5472 run_test 42e "verify sub-RPC writes are not done synchronously"
5473
5474 test_43A() { # was test_43
5475         test_mkdir $DIR/$tdir
5476         cp -p /bin/ls $DIR/$tdir/$tfile
5477         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5478         pid=$!
5479         # give multiop a chance to open
5480         sleep 1
5481
5482         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5483         kill -USR1 $pid
5484         # Wait for multiop to exit
5485         wait $pid
5486 }
5487 run_test 43A "execution of file opened for write should return -ETXTBSY"
5488
5489 test_43a() {
5490         test_mkdir $DIR/$tdir
5491         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5492         $DIR/$tdir/sleep 60 &
5493         SLEEP_PID=$!
5494         # Make sure exec of $tdir/sleep wins race with truncate
5495         sleep 1
5496         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5497         kill $SLEEP_PID
5498 }
5499 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5500
5501 test_43b() {
5502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5503
5504         test_mkdir $DIR/$tdir
5505         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5506         $DIR/$tdir/sleep 60 &
5507         SLEEP_PID=$!
5508         # Make sure exec of $tdir/sleep wins race with truncate
5509         sleep 1
5510         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5511         kill $SLEEP_PID
5512 }
5513 run_test 43b "truncate of file being executed should return -ETXTBSY"
5514
5515 test_43c() {
5516         local testdir="$DIR/$tdir"
5517         test_mkdir $testdir
5518         cp $SHELL $testdir/
5519         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5520                 ( cd $testdir && md5sum -c )
5521 }
5522 run_test 43c "md5sum of copy into lustre"
5523
5524 test_44A() { # was test_44
5525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5526
5527         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5528         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5529 }
5530 run_test 44A "zero length read from a sparse stripe"
5531
5532 test_44a() {
5533         local nstripe=$($LFS getstripe -c -d $DIR)
5534         [ -z "$nstripe" ] && skip "can't get stripe info"
5535         [[ $nstripe -gt $OSTCOUNT ]] &&
5536                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5537
5538         local stride=$($LFS getstripe -S -d $DIR)
5539         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5540                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5541         fi
5542
5543         OFFSETS="0 $((stride/2)) $((stride-1))"
5544         for offset in $OFFSETS; do
5545                 for i in $(seq 0 $((nstripe-1))); do
5546                         local GLOBALOFFSETS=""
5547                         # size in Bytes
5548                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5549                         local myfn=$DIR/d44a-$size
5550                         echo "--------writing $myfn at $size"
5551                         ll_sparseness_write $myfn $size ||
5552                                 error "ll_sparseness_write"
5553                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5554                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5555                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5556
5557                         for j in $(seq 0 $((nstripe-1))); do
5558                                 # size in Bytes
5559                                 size=$((((j + $nstripe )*$stride + $offset)))
5560                                 ll_sparseness_write $myfn $size ||
5561                                         error "ll_sparseness_write"
5562                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5563                         done
5564                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5565                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5566                         rm -f $myfn
5567                 done
5568         done
5569 }
5570 run_test 44a "test sparse pwrite ==============================="
5571
5572 dirty_osc_total() {
5573         tot=0
5574         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5575                 tot=$(($tot + $d))
5576         done
5577         echo $tot
5578 }
5579 do_dirty_record() {
5580         before=`dirty_osc_total`
5581         echo executing "\"$*\""
5582         eval $*
5583         after=`dirty_osc_total`
5584         echo before $before, after $after
5585 }
5586 test_45() {
5587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5588
5589         f="$DIR/f45"
5590         # Obtain grants from OST if it supports it
5591         echo blah > ${f}_grant
5592         stop_writeback
5593         sync
5594         do_dirty_record "echo blah > $f"
5595         [[ $before -eq $after ]] && error "write wasn't cached"
5596         do_dirty_record "> $f"
5597         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5598         do_dirty_record "echo blah > $f"
5599         [[ $before -eq $after ]] && error "write wasn't cached"
5600         do_dirty_record "sync"
5601         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5602         do_dirty_record "echo blah > $f"
5603         [[ $before -eq $after ]] && error "write wasn't cached"
5604         do_dirty_record "cancel_lru_locks osc"
5605         [[ $before -gt $after ]] ||
5606                 error "lock cancellation didn't lower dirty count"
5607         start_writeback
5608 }
5609 run_test 45 "osc io page accounting ============================"
5610
5611 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5612 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5613 # objects offset and an assert hit when an rpc was built with 1023's mapped
5614 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5615 test_46() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617
5618         f="$DIR/f46"
5619         stop_writeback
5620         sync
5621         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5622         sync
5623         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5624         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5625         sync
5626         start_writeback
5627 }
5628 run_test 46 "dirtying a previously written page ================"
5629
5630 # test_47 is removed "Device nodes check" is moved to test_28
5631
5632 test_48a() { # bug 2399
5633         [ "$mds1_FSTYPE" = "zfs" ] &&
5634         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5635                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5636
5637         test_mkdir $DIR/$tdir
5638         cd $DIR/$tdir
5639         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5640         test_mkdir $DIR/$tdir
5641         touch foo || error "'touch foo' failed after recreating cwd"
5642         test_mkdir bar
5643         touch .foo || error "'touch .foo' failed after recreating cwd"
5644         test_mkdir .bar
5645         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5646         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5647         cd . || error "'cd .' failed after recreating cwd"
5648         mkdir . && error "'mkdir .' worked after recreating cwd"
5649         rmdir . && error "'rmdir .' worked after recreating cwd"
5650         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5651         cd .. || error "'cd ..' failed after recreating cwd"
5652 }
5653 run_test 48a "Access renamed working dir (should return errors)="
5654
5655 test_48b() { # bug 2399
5656         rm -rf $DIR/$tdir
5657         test_mkdir $DIR/$tdir
5658         cd $DIR/$tdir
5659         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5660         touch foo && error "'touch foo' worked after removing cwd"
5661         mkdir foo && error "'mkdir foo' worked after removing cwd"
5662         touch .foo && error "'touch .foo' worked after removing cwd"
5663         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5664         ls . > /dev/null && error "'ls .' worked after removing cwd"
5665         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5666         mkdir . && error "'mkdir .' worked after removing cwd"
5667         rmdir . && error "'rmdir .' worked after removing cwd"
5668         ln -s . foo && error "'ln -s .' worked after removing cwd"
5669         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5670 }
5671 run_test 48b "Access removed working dir (should return errors)="
5672
5673 test_48c() { # bug 2350
5674         #lctl set_param debug=-1
5675         #set -vx
5676         rm -rf $DIR/$tdir
5677         test_mkdir -p $DIR/$tdir/dir
5678         cd $DIR/$tdir/dir
5679         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5680         $TRACE touch foo && error "touch foo worked after removing cwd"
5681         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5682         touch .foo && error "touch .foo worked after removing cwd"
5683         mkdir .foo && error "mkdir .foo worked after removing cwd"
5684         $TRACE ls . && error "'ls .' worked after removing cwd"
5685         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5686         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5687         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5688         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5689         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5690 }
5691 run_test 48c "Access removed working subdir (should return errors)"
5692
5693 test_48d() { # bug 2350
5694         #lctl set_param debug=-1
5695         #set -vx
5696         rm -rf $DIR/$tdir
5697         test_mkdir -p $DIR/$tdir/dir
5698         cd $DIR/$tdir/dir
5699         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5700         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5701         $TRACE touch foo && error "'touch foo' worked after removing parent"
5702         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5703         touch .foo && error "'touch .foo' worked after removing parent"
5704         mkdir .foo && error "mkdir .foo worked after removing parent"
5705         $TRACE ls . && error "'ls .' worked after removing parent"
5706         $TRACE ls .. && error "'ls ..' worked after removing parent"
5707         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5708         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5709         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5710         true
5711 }
5712 run_test 48d "Access removed parent subdir (should return errors)"
5713
5714 test_48e() { # bug 4134
5715         #lctl set_param debug=-1
5716         #set -vx
5717         rm -rf $DIR/$tdir
5718         test_mkdir -p $DIR/$tdir/dir
5719         cd $DIR/$tdir/dir
5720         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5721         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5722         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5723         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5724         # On a buggy kernel addition of "touch foo" after cd .. will
5725         # produce kernel oops in lookup_hash_it
5726         touch ../foo && error "'cd ..' worked after recreate parent"
5727         cd $DIR
5728         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5729 }
5730 run_test 48e "Access to recreated parent subdir (should return errors)"
5731
5732 test_48f() {
5733         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5734                 skip "need MDS >= 2.13.55"
5735         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5736         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5737                 skip "needs different host for mdt1 mdt2"
5738         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5739
5740         $LFS mkdir -i0 $DIR/$tdir
5741         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5742
5743         for d in sub1 sub2 sub3; do
5744                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5745                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5746                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5747         done
5748
5749         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5750 }
5751 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5752
5753 test_49() { # LU-1030
5754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5755         remote_ost_nodsh && skip "remote OST with nodsh"
5756
5757         # get ost1 size - $FSNAME-OST0000
5758         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5759                 awk '{ print $4 }')
5760         # write 800M at maximum
5761         [[ $ost1_size -lt 2 ]] && ost1_size=2
5762         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5763
5764         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5765         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5766         local dd_pid=$!
5767
5768         # change max_pages_per_rpc while writing the file
5769         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5770         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5771         # loop until dd process exits
5772         while ps ax -opid | grep -wq $dd_pid; do
5773                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5774                 sleep $((RANDOM % 5 + 1))
5775         done
5776         # restore original max_pages_per_rpc
5777         $LCTL set_param $osc1_mppc=$orig_mppc
5778         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5779 }
5780 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5781
5782 test_50() {
5783         # bug 1485
5784         test_mkdir $DIR/$tdir
5785         cd $DIR/$tdir
5786         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5787 }
5788 run_test 50 "special situations: /proc symlinks  ==============="
5789
5790 test_51a() {    # was test_51
5791         # bug 1516 - create an empty entry right after ".." then split dir
5792         test_mkdir -c1 $DIR/$tdir
5793         touch $DIR/$tdir/foo
5794         $MCREATE $DIR/$tdir/bar
5795         rm $DIR/$tdir/foo
5796         createmany -m $DIR/$tdir/longfile 201
5797         FNUM=202
5798         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5799                 $MCREATE $DIR/$tdir/longfile$FNUM
5800                 FNUM=$(($FNUM + 1))
5801                 echo -n "+"
5802         done
5803         echo
5804         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5805 }
5806 run_test 51a "special situations: split htree with empty entry =="
5807
5808 cleanup_print_lfs_df () {
5809         trap 0
5810         $LFS df
5811         $LFS df -i
5812 }
5813
5814 test_51b() {
5815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5816
5817         local dir=$DIR/$tdir
5818         local nrdirs=$((65536 + 100))
5819
5820         # cleanup the directory
5821         rm -fr $dir
5822
5823         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5824
5825         $LFS df
5826         $LFS df -i
5827         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5828         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5829         [[ $numfree -lt $nrdirs ]] &&
5830                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5831
5832         # need to check free space for the directories as well
5833         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5834         numfree=$(( blkfree / $(fs_inode_ksize) ))
5835         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5836
5837         trap cleanup_print_lfs_df EXIT
5838
5839         # create files
5840         createmany -d $dir/d $nrdirs || {
5841                 unlinkmany $dir/d $nrdirs
5842                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5843         }
5844
5845         # really created :
5846         nrdirs=$(ls -U $dir | wc -l)
5847
5848         # unlink all but 100 subdirectories, then check it still works
5849         local left=100
5850         local delete=$((nrdirs - left))
5851
5852         $LFS df
5853         $LFS df -i
5854
5855         # for ldiskfs the nlink count should be 1, but this is OSD specific
5856         # and so this is listed for informational purposes only
5857         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5858         unlinkmany -d $dir/d $delete ||
5859                 error "unlink of first $delete subdirs failed"
5860
5861         echo "nlink between: $(stat -c %h $dir)"
5862         local found=$(ls -U $dir | wc -l)
5863         [ $found -ne $left ] &&
5864                 error "can't find subdirs: found only $found, expected $left"
5865
5866         unlinkmany -d $dir/d $delete $left ||
5867                 error "unlink of second $left subdirs failed"
5868         # regardless of whether the backing filesystem tracks nlink accurately
5869         # or not, the nlink count shouldn't be more than "." and ".." here
5870         local after=$(stat -c %h $dir)
5871         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5872                 echo "nlink after: $after"
5873
5874         cleanup_print_lfs_df
5875 }
5876 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5877
5878 test_51d_sub() {
5879         local stripecount=$1
5880         local nfiles=$2
5881
5882         log "create files with stripecount=$stripecount"
5883         $LFS setstripe -C $stripecount $DIR/$tdir
5884         createmany -o $DIR/$tdir/t- $nfiles
5885         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5886         for ((n = 0; n < $OSTCOUNT; n++)); do
5887                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5888                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5889                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5890                             '($1 == '$n') { objs += 1 } \
5891                             END { printf("%0.0f", objs) }')
5892                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5893         done
5894         unlinkmany $DIR/$tdir/t- $nfiles
5895         rm  -f $TMP/$tfile
5896
5897         local nlast
5898         local min=4
5899         local max=6 # allow variance of (1 - $min/$max) = 33% by default
5900
5901         # For some combinations of stripecount and OSTCOUNT current code
5902         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
5903         # than others. Rather than skipping this test entirely, check that
5904         # and keep testing to ensure imbalance does not get worse. LU-15282
5905         (( (OSTCOUNT == 6 && stripecount == 4) ||
5906            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
5907            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
5908         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
5909                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5910                         { $LFS df && $LFS df -i &&
5911                         error "stripecount=$stripecount: " \
5912                               "OST $n has fewer objects vs. OST $nlast " \
5913                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
5914                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5915                         { $LFS df && $LFS df -i &&
5916                         error "stripecount=$stripecount: " \
5917                               "OST $n has more objects vs. OST $nlast " \
5918                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
5919
5920                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
5921                         { $LFS df && $LFS df -i &&
5922                         error "stripecount=$stripecount: " \
5923                               "OST $n has fewer #0 objects vs. OST $nlast " \
5924                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
5925                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
5926                         { $LFS df && $LFS df -i &&
5927                         error "stripecount=$stripecount: " \
5928                               "OST $n has more #0 objects vs. OST $nlast " \
5929                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
5930         done
5931 }
5932
5933 test_51d() {
5934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5935         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5936
5937         local stripecount
5938         local per_ost=100
5939         local nfiles=$((per_ost * OSTCOUNT))
5940         local mdts=$(comma_list $(mdts_nodes))
5941         local param="osp.*.create_count"
5942         local qos_old=$(do_facet mds1 \
5943                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5944
5945         do_nodes $mdts \
5946                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5947         stack_trap "do_nodes $mdts \
5948                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5949
5950         test_mkdir $DIR/$tdir
5951         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
5952         (( dirstripes > 0 )) || dirstripes=1
5953
5954         # Ensure enough OST objects precreated for tests to pass without
5955         # running out of objects.  This is an LOV r-r OST algorithm test,
5956         # not an OST object precreation test.
5957         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
5958         (( old >= nfiles )) ||
5959         {
5960                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
5961
5962                 do_nodes $mdts "$LCTL set_param $param=$create_count"
5963                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
5964
5965                 # trigger precreation from all MDTs for all OSTs
5966                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
5967                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
5968                 done
5969         }
5970
5971         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
5972                 sleep 8  # allow object precreation to catch up
5973                 test_51d_sub $stripecount $nfiles
5974         done
5975 }
5976 run_test 51d "check LOV round-robin OST object distribution"
5977
5978 test_51e() {
5979         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5980                 skip_env "ldiskfs only test"
5981         fi
5982
5983         test_mkdir -c1 $DIR/$tdir
5984         test_mkdir -c1 $DIR/$tdir/d0
5985
5986         touch $DIR/$tdir/d0/foo
5987         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5988                 error "file exceed 65000 nlink limit!"
5989         unlinkmany $DIR/$tdir/d0/f- 65001
5990         return 0
5991 }
5992 run_test 51e "check file nlink limit"
5993
5994 test_51f() {
5995         test_mkdir $DIR/$tdir
5996
5997         local max=100000
5998         local ulimit_old=$(ulimit -n)
5999         local spare=20 # number of spare fd's for scripts/libraries, etc.
6000         local mdt=$($LFS getstripe -m $DIR/$tdir)
6001         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6002
6003         echo "MDT$mdt numfree=$numfree, max=$max"
6004         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6005         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6006                 while ! ulimit -n $((numfree + spare)); do
6007                         numfree=$((numfree * 3 / 4))
6008                 done
6009                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6010         else
6011                 echo "left ulimit at $ulimit_old"
6012         fi
6013
6014         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6015                 unlinkmany $DIR/$tdir/f $numfree
6016                 error "create+open $numfree files in $DIR/$tdir failed"
6017         }
6018         ulimit -n $ulimit_old
6019
6020         # if createmany exits at 120s there will be fewer than $numfree files
6021         unlinkmany $DIR/$tdir/f $numfree || true
6022 }
6023 run_test 51f "check many open files limit"
6024
6025 test_52a() {
6026         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6027         test_mkdir $DIR/$tdir
6028         touch $DIR/$tdir/foo
6029         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6030         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6031         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6032         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6033         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6034                                         error "link worked"
6035         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6036         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6037         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6038                                                      error "lsattr"
6039         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6040         cp -r $DIR/$tdir $TMP/
6041         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6042 }
6043 run_test 52a "append-only flag test (should return errors)"
6044
6045 test_52b() {
6046         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6047         test_mkdir $DIR/$tdir
6048         touch $DIR/$tdir/foo
6049         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6050         cat test > $DIR/$tdir/foo && error "cat test worked"
6051         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6052         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6053         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6054                                         error "link worked"
6055         echo foo >> $DIR/$tdir/foo && error "echo worked"
6056         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6057         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6058         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6059         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6060                                                         error "lsattr"
6061         chattr -i $DIR/$tdir/foo || error "chattr failed"
6062
6063         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6064 }
6065 run_test 52b "immutable flag test (should return errors) ======="
6066
6067 test_53() {
6068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6069         remote_mds_nodsh && skip "remote MDS with nodsh"
6070         remote_ost_nodsh && skip "remote OST with nodsh"
6071
6072         local param
6073         local param_seq
6074         local ostname
6075         local mds_last
6076         local mds_last_seq
6077         local ost_last
6078         local ost_last_seq
6079         local ost_last_id
6080         local ostnum
6081         local node
6082         local found=false
6083         local support_last_seq=true
6084
6085         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6086                 support_last_seq=false
6087
6088         # only test MDT0000
6089         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6090         local value
6091         for value in $(do_facet $SINGLEMDS \
6092                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6093                 param=$(echo ${value[0]} | cut -d "=" -f1)
6094                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6095
6096                 if $support_last_seq; then
6097                         param_seq=$(echo $param |
6098                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6099                         mds_last_seq=$(do_facet $SINGLEMDS \
6100                                        $LCTL get_param -n $param_seq)
6101                 fi
6102                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6103
6104                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6105                 node=$(facet_active_host ost$((ostnum+1)))
6106                 param="obdfilter.$ostname.last_id"
6107                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6108                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6109                         ost_last_id=$ost_last
6110
6111                         if $support_last_seq; then
6112                                 ost_last_id=$(echo $ost_last |
6113                                               awk -F':' '{print $2}' |
6114                                               sed -e "s/^0x//g")
6115                                 ost_last_seq=$(echo $ost_last |
6116                                                awk -F':' '{print $1}')
6117                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6118                         fi
6119
6120                         if [[ $ost_last_id != $mds_last ]]; then
6121                                 error "$ost_last_id != $mds_last"
6122                         else
6123                                 found=true
6124                                 break
6125                         fi
6126                 done
6127         done
6128         $found || error "can not match last_seq/last_id for $mdtosc"
6129         return 0
6130 }
6131 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6132
6133 test_54a() {
6134         perl -MSocket -e ';' || skip "no Socket perl module installed"
6135
6136         $SOCKETSERVER $DIR/socket ||
6137                 error "$SOCKETSERVER $DIR/socket failed: $?"
6138         $SOCKETCLIENT $DIR/socket ||
6139                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6140         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6141 }
6142 run_test 54a "unix domain socket test =========================="
6143
6144 test_54b() {
6145         f="$DIR/f54b"
6146         mknod $f c 1 3
6147         chmod 0666 $f
6148         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6149 }
6150 run_test 54b "char device works in lustre ======================"
6151
6152 find_loop_dev() {
6153         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6154         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6155         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6156
6157         for i in $(seq 3 7); do
6158                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6159                 LOOPDEV=$LOOPBASE$i
6160                 LOOPNUM=$i
6161                 break
6162         done
6163 }
6164
6165 cleanup_54c() {
6166         local rc=0
6167         loopdev="$DIR/loop54c"
6168
6169         trap 0
6170         $UMOUNT $DIR/$tdir || rc=$?
6171         losetup -d $loopdev || true
6172         losetup -d $LOOPDEV || true
6173         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6174         return $rc
6175 }
6176
6177 test_54c() {
6178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6179
6180         loopdev="$DIR/loop54c"
6181
6182         find_loop_dev
6183         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6184         trap cleanup_54c EXIT
6185         mknod $loopdev b 7 $LOOPNUM
6186         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6187         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6188         losetup $loopdev $DIR/$tfile ||
6189                 error "can't set up $loopdev for $DIR/$tfile"
6190         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6191         test_mkdir $DIR/$tdir
6192         mount -t ext2 $loopdev $DIR/$tdir ||
6193                 error "error mounting $loopdev on $DIR/$tdir"
6194         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6195                 error "dd write"
6196         df $DIR/$tdir
6197         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6198                 error "dd read"
6199         cleanup_54c
6200 }
6201 run_test 54c "block device works in lustre ====================="
6202
6203 test_54d() {
6204         local pipe="$DIR/$tfile.pipe"
6205         local string="aaaaaa"
6206
6207         mknod $pipe p
6208         echo -n "$string" > $pipe &
6209         local result=$(cat $pipe)
6210         [[ "$result" == "$string" ]] || error "$result != $string"
6211 }
6212 run_test 54d "fifo device works in lustre ======================"
6213
6214 test_54e() {
6215         f="$DIR/f54e"
6216         string="aaaaaa"
6217         cp -aL /dev/console $f
6218         echo $string > $f || error "echo $string to $f failed"
6219 }
6220 run_test 54e "console/tty device works in lustre ======================"
6221
6222 test_56a() {
6223         local numfiles=3
6224         local numdirs=2
6225         local dir=$DIR/$tdir
6226
6227         rm -rf $dir
6228         test_mkdir -p $dir/dir
6229         for i in $(seq $numfiles); do
6230                 touch $dir/file$i
6231                 touch $dir/dir/file$i
6232         done
6233
6234         local numcomp=$($LFS getstripe --component-count $dir)
6235
6236         [[ $numcomp == 0 ]] && numcomp=1
6237
6238         # test lfs getstripe with --recursive
6239         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6240
6241         [[ $filenum -eq $((numfiles * 2)) ]] ||
6242                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6243         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6244         [[ $filenum -eq $numfiles ]] ||
6245                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6246         echo "$LFS getstripe showed obdidx or l_ost_idx"
6247
6248         # test lfs getstripe with file instead of dir
6249         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6250         [[ $filenum -eq 1 ]] ||
6251                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6252         echo "$LFS getstripe file1 passed"
6253
6254         #test lfs getstripe with --verbose
6255         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6256         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6257                 error "$LFS getstripe --verbose $dir: "\
6258                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6259         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6260                 error "$LFS getstripe $dir: showed lmm_magic"
6261
6262         #test lfs getstripe with -v prints lmm_fid
6263         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6264         local countfids=$((numdirs + numfiles * numcomp))
6265         [[ $filenum -eq $countfids ]] ||
6266                 error "$LFS getstripe -v $dir: "\
6267                       "got $filenum want $countfids lmm_fid"
6268         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6269                 error "$LFS getstripe $dir: showed lmm_fid by default"
6270         echo "$LFS getstripe --verbose passed"
6271
6272         #check for FID information
6273         local fid1=$($LFS getstripe --fid $dir/file1)
6274         local fid2=$($LFS getstripe --verbose $dir/file1 |
6275                      awk '/lmm_fid: / { print $2; exit; }')
6276         local fid3=$($LFS path2fid $dir/file1)
6277
6278         [ "$fid1" != "$fid2" ] &&
6279                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6280         [ "$fid1" != "$fid3" ] &&
6281                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6282         echo "$LFS getstripe --fid passed"
6283
6284         #test lfs getstripe with --obd
6285         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6286                 error "$LFS getstripe --obd wrong_uuid: should return error"
6287
6288         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6289
6290         local ostidx=1
6291         local obduuid=$(ostuuid_from_index $ostidx)
6292         local found=$($LFS getstripe -r --obd $obduuid $dir |
6293                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6294
6295         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6296         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6297                 ((filenum--))
6298         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6299                 ((filenum--))
6300
6301         [[ $found -eq $filenum ]] ||
6302                 error "$LFS getstripe --obd: found $found expect $filenum"
6303         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6304                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6305                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6306                 error "$LFS getstripe --obd: should not show file on other obd"
6307         echo "$LFS getstripe --obd passed"
6308 }
6309 run_test 56a "check $LFS getstripe"
6310
6311 test_56b() {
6312         local dir=$DIR/$tdir
6313         local numdirs=3
6314
6315         test_mkdir $dir
6316         for i in $(seq $numdirs); do
6317                 test_mkdir $dir/dir$i
6318         done
6319
6320         # test lfs getdirstripe default mode is non-recursion, which is
6321         # different from lfs getstripe
6322         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6323
6324         [[ $dircnt -eq 1 ]] ||
6325                 error "$LFS getdirstripe: found $dircnt, not 1"
6326         dircnt=$($LFS getdirstripe --recursive $dir |
6327                 grep -c lmv_stripe_count)
6328         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6329                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6330 }
6331 run_test 56b "check $LFS getdirstripe"
6332
6333 test_56c() {
6334         remote_ost_nodsh && skip "remote OST with nodsh"
6335
6336         local ost_idx=0
6337         local ost_name=$(ostname_from_index $ost_idx)
6338         local old_status=$(ost_dev_status $ost_idx)
6339         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6340
6341         [[ -z "$old_status" ]] ||
6342                 skip_env "OST $ost_name is in $old_status status"
6343
6344         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6345         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6346                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6347         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6348                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6349                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6350         fi
6351
6352         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6353                 error "$LFS df -v showing inactive devices"
6354         sleep_maxage
6355
6356         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6357
6358         [[ "$new_status" =~ "D" ]] ||
6359                 error "$ost_name status is '$new_status', missing 'D'"
6360         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6361                 [[ "$new_status" =~ "N" ]] ||
6362                         error "$ost_name status is '$new_status', missing 'N'"
6363         fi
6364         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6365                 [[ "$new_status" =~ "f" ]] ||
6366                         error "$ost_name status is '$new_status', missing 'f'"
6367         fi
6368
6369         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6370         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6371                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6372         [[ -z "$p" ]] && restore_lustre_params < $p || true
6373         sleep_maxage
6374
6375         new_status=$(ost_dev_status $ost_idx)
6376         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6377                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6378         # can't check 'f' as devices may actually be on flash
6379 }
6380 run_test 56c "check 'lfs df' showing device status"
6381
6382 test_56d() {
6383         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6384         local osts=$($LFS df -v $MOUNT | grep -c OST)
6385
6386         $LFS df $MOUNT
6387
6388         (( mdts == MDSCOUNT )) ||
6389                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6390         (( osts == OSTCOUNT )) ||
6391                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6392 }
6393 run_test 56d "'lfs df -v' prints only configured devices"
6394
6395 test_56e() {
6396         err_enoent=2 # No such file or directory
6397         err_eopnotsupp=95 # Operation not supported
6398
6399         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6400         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6401
6402         # Check for handling of path not exists
6403         output=$($LFS df $enoent_mnt 2>&1)
6404         ret=$?
6405
6406         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6407         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6408                 error "expect failure $err_enoent, not $ret"
6409
6410         # Check for handling of non-Lustre FS
6411         output=$($LFS df $notsup_mnt)
6412         ret=$?
6413
6414         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6415         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6416                 error "expect success $err_eopnotsupp, not $ret"
6417
6418         # Check for multiple LustreFS argument
6419         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6420         ret=$?
6421
6422         [[ $output -eq 3 && $ret -eq 0 ]] ||
6423                 error "expect success 3, not $output, rc = $ret"
6424
6425         # Check for correct non-Lustre FS handling among multiple
6426         # LustreFS argument
6427         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6428                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6429         ret=$?
6430
6431         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6432                 error "expect success 2, not $output, rc = $ret"
6433 }
6434 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6435
6436 NUMFILES=3
6437 NUMDIRS=3
6438 setup_56() {
6439         local local_tdir="$1"
6440         local local_numfiles="$2"
6441         local local_numdirs="$3"
6442         local dir_params="$4"
6443         local dir_stripe_params="$5"
6444
6445         if [ ! -d "$local_tdir" ] ; then
6446                 test_mkdir -p $dir_stripe_params $local_tdir
6447                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6448                 for i in $(seq $local_numfiles) ; do
6449                         touch $local_tdir/file$i
6450                 done
6451                 for i in $(seq $local_numdirs) ; do
6452                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6453                         for j in $(seq $local_numfiles) ; do
6454                                 touch $local_tdir/dir$i/file$j
6455                         done
6456                 done
6457         fi
6458 }
6459
6460 setup_56_special() {
6461         local local_tdir=$1
6462         local local_numfiles=$2
6463         local local_numdirs=$3
6464
6465         setup_56 $local_tdir $local_numfiles $local_numdirs
6466
6467         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6468                 for i in $(seq $local_numfiles) ; do
6469                         mknod $local_tdir/loop${i}b b 7 $i
6470                         mknod $local_tdir/null${i}c c 1 3
6471                         ln -s $local_tdir/file1 $local_tdir/link${i}
6472                 done
6473                 for i in $(seq $local_numdirs) ; do
6474                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6475                         mknod $local_tdir/dir$i/null${i}c c 1 3
6476                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6477                 done
6478         fi
6479 }
6480
6481 test_56g() {
6482         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6483         local expected=$(($NUMDIRS + 2))
6484
6485         setup_56 $dir $NUMFILES $NUMDIRS
6486
6487         # test lfs find with -name
6488         for i in $(seq $NUMFILES) ; do
6489                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6490
6491                 [ $nums -eq $expected ] ||
6492                         error "lfs find -name '*$i' $dir wrong: "\
6493                               "found $nums, expected $expected"
6494         done
6495 }
6496 run_test 56g "check lfs find -name"
6497
6498 test_56h() {
6499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6500         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6501
6502         setup_56 $dir $NUMFILES $NUMDIRS
6503
6504         # test lfs find with ! -name
6505         for i in $(seq $NUMFILES) ; do
6506                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6507
6508                 [ $nums -eq $expected ] ||
6509                         error "lfs find ! -name '*$i' $dir wrong: "\
6510                               "found $nums, expected $expected"
6511         done
6512 }
6513 run_test 56h "check lfs find ! -name"
6514
6515 test_56i() {
6516         local dir=$DIR/$tdir
6517
6518         test_mkdir $dir
6519
6520         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6521         local out=$($cmd)
6522
6523         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6524 }
6525 run_test 56i "check 'lfs find -ost UUID' skips directories"
6526
6527 test_56j() {
6528         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6529
6530         setup_56_special $dir $NUMFILES $NUMDIRS
6531
6532         local expected=$((NUMDIRS + 1))
6533         local cmd="$LFS find -type d $dir"
6534         local nums=$($cmd | wc -l)
6535
6536         [ $nums -eq $expected ] ||
6537                 error "'$cmd' wrong: found $nums, expected $expected"
6538 }
6539 run_test 56j "check lfs find -type d"
6540
6541 test_56k() {
6542         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6543
6544         setup_56_special $dir $NUMFILES $NUMDIRS
6545
6546         local expected=$(((NUMDIRS + 1) * NUMFILES))
6547         local cmd="$LFS find -type f $dir"
6548         local nums=$($cmd | wc -l)
6549
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552 }
6553 run_test 56k "check lfs find -type f"
6554
6555 test_56l() {
6556         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6557
6558         setup_56_special $dir $NUMFILES $NUMDIRS
6559
6560         local expected=$((NUMDIRS + NUMFILES))
6561         local cmd="$LFS find -type b $dir"
6562         local nums=$($cmd | wc -l)
6563
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566 }
6567 run_test 56l "check lfs find -type b"
6568
6569 test_56m() {
6570         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6571
6572         setup_56_special $dir $NUMFILES $NUMDIRS
6573
6574         local expected=$((NUMDIRS + NUMFILES))
6575         local cmd="$LFS find -type c $dir"
6576         local nums=$($cmd | wc -l)
6577         [ $nums -eq $expected ] ||
6578                 error "'$cmd' wrong: found $nums, expected $expected"
6579 }
6580 run_test 56m "check lfs find -type c"
6581
6582 test_56n() {
6583         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6584         setup_56_special $dir $NUMFILES $NUMDIRS
6585
6586         local expected=$((NUMDIRS + NUMFILES))
6587         local cmd="$LFS find -type l $dir"
6588         local nums=$($cmd | wc -l)
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592 }
6593 run_test 56n "check lfs find -type l"
6594
6595 test_56o() {
6596         local dir=$DIR/$tdir
6597
6598         setup_56 $dir $NUMFILES $NUMDIRS
6599         utime $dir/file1 > /dev/null || error "utime (1)"
6600         utime $dir/file2 > /dev/null || error "utime (2)"
6601         utime $dir/dir1 > /dev/null || error "utime (3)"
6602         utime $dir/dir2 > /dev/null || error "utime (4)"
6603         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6604         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6605
6606         local expected=4
6607         local nums=$($LFS find -mtime +0 $dir | wc -l)
6608
6609         [ $nums -eq $expected ] ||
6610                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6611
6612         expected=12
6613         cmd="$LFS find -mtime 0 $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617 }
6618 run_test 56o "check lfs find -mtime for old files"
6619
6620 test_56ob() {
6621         local dir=$DIR/$tdir
6622         local expected=1
6623         local count=0
6624
6625         # just to make sure there is something that won't be found
6626         test_mkdir $dir
6627         touch $dir/$tfile.now
6628
6629         for age in year week day hour min; do
6630                 count=$((count + 1))
6631
6632                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6633                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6634                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6635
6636                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6637                 local nums=$($cmd | wc -l)
6638                 [ $nums -eq $expected ] ||
6639                         error "'$cmd' wrong: found $nums, expected $expected"
6640
6641                 cmd="$LFS find $dir -atime $count${age:0:1}"
6642                 nums=$($cmd | wc -l)
6643                 [ $nums -eq $expected ] ||
6644                         error "'$cmd' wrong: found $nums, expected $expected"
6645         done
6646
6647         sleep 2
6648         cmd="$LFS find $dir -ctime +1s -type f"
6649         nums=$($cmd | wc -l)
6650         (( $nums == $count * 2 + 1)) ||
6651                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6652 }
6653 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6654
6655 test_newerXY_base() {
6656         local x=$1
6657         local y=$2
6658         local dir=$DIR/$tdir
6659         local ref
6660         local negref
6661
6662         if [ $y == "t" ]; then
6663                 if [ $x == "b" ]; then
6664                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6665                 else
6666                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6667                 fi
6668         else
6669                 ref=$DIR/$tfile.newer.$x$y
6670                 touch $ref || error "touch $ref failed"
6671         fi
6672
6673         echo "before = $ref"
6674         sleep 2
6675         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6676         sleep 2
6677         if [ $y == "t" ]; then
6678                 if [ $x == "b" ]; then
6679                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6680                 else
6681                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6682                 fi
6683         else
6684                 negref=$DIR/$tfile.negnewer.$x$y
6685                 touch $negref || error "touch $negref failed"
6686         fi
6687
6688         echo "after = $negref"
6689         local cmd="$LFS find $dir -newer$x$y $ref"
6690         local nums=$(eval $cmd | wc -l)
6691         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6692
6693         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6694                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6695
6696         cmd="$LFS find $dir ! -newer$x$y $negref"
6697         nums=$(eval $cmd | wc -l)
6698         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6699                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6700
6701         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6702         nums=$(eval $cmd | wc -l)
6703         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6704                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6705
6706         rm -rf $DIR/*
6707 }
6708
6709 test_56oc() {
6710         test_newerXY_base "a" "a"
6711         test_newerXY_base "a" "m"
6712         test_newerXY_base "a" "c"
6713         test_newerXY_base "m" "a"
6714         test_newerXY_base "m" "m"
6715         test_newerXY_base "m" "c"
6716         test_newerXY_base "c" "a"
6717         test_newerXY_base "c" "m"
6718         test_newerXY_base "c" "c"
6719
6720         test_newerXY_base "a" "t"
6721         test_newerXY_base "m" "t"
6722         test_newerXY_base "c" "t"
6723
6724         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6725            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6726                 ! btime_supported && echo "btime unsupported" && return 0
6727
6728         test_newerXY_base "b" "b"
6729         test_newerXY_base "b" "t"
6730 }
6731 run_test 56oc "check lfs find -newerXY work"
6732
6733 btime_supported() {
6734         local dir=$DIR/$tdir
6735         local rc
6736
6737         mkdir -p $dir
6738         touch $dir/$tfile
6739         $LFS find $dir -btime -1d -type f
6740         rc=$?
6741         rm -rf $dir
6742         return $rc
6743 }
6744
6745 test_56od() {
6746         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6747                 ! btime_supported && skip "btime unsupported on MDS"
6748
6749         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6750                 ! btime_supported && skip "btime unsupported on clients"
6751
6752         local dir=$DIR/$tdir
6753         local ref=$DIR/$tfile.ref
6754         local negref=$DIR/$tfile.negref
6755
6756         mkdir $dir || error "mkdir $dir failed"
6757         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6758         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6759         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6760         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6761         touch $ref || error "touch $ref failed"
6762         # sleep 3 seconds at least
6763         sleep 3
6764
6765         local before=$(do_facet mds1 date +%s)
6766         local skew=$(($(date +%s) - before + 1))
6767
6768         if (( skew < 0 && skew > -5 )); then
6769                 sleep $((0 - skew + 1))
6770                 skew=0
6771         fi
6772
6773         # Set the dir stripe params to limit files all on MDT0,
6774         # otherwise we need to calc the max clock skew between
6775         # the client and MDTs.
6776         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6777         sleep 2
6778         touch $negref || error "touch $negref failed"
6779
6780         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6781         local nums=$($cmd | wc -l)
6782         local expected=$(((NUMFILES + 1) * NUMDIRS))
6783
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6788         nums=$($cmd | wc -l)
6789         expected=$((NUMFILES + 1))
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792
6793         [ $skew -lt 0 ] && return
6794
6795         local after=$(do_facet mds1 date +%s)
6796         local age=$((after - before + 1 + skew))
6797
6798         cmd="$LFS find $dir -btime -${age}s -type f"
6799         nums=$($cmd | wc -l)
6800         expected=$(((NUMFILES + 1) * NUMDIRS))
6801
6802         echo "Clock skew between client and server: $skew, age:$age"
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805
6806         expected=$(($NUMDIRS + 1))
6807         cmd="$LFS find $dir -btime -${age}s -type d"
6808         nums=$($cmd | wc -l)
6809         [ $nums -eq $expected ] ||
6810                 error "'$cmd' wrong: found $nums, expected $expected"
6811         rm -f $ref $negref || error "Failed to remove $ref $negref"
6812 }
6813 run_test 56od "check lfs find -btime with units"
6814
6815 test_56p() {
6816         [ $RUNAS_ID -eq $UID ] &&
6817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6818
6819         local dir=$DIR/$tdir
6820
6821         setup_56 $dir $NUMFILES $NUMDIRS
6822         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6823
6824         local expected=$NUMFILES
6825         local cmd="$LFS find -uid $RUNAS_ID $dir"
6826         local nums=$($cmd | wc -l)
6827
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830
6831         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6832         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6833         nums=$($cmd | wc -l)
6834         [ $nums -eq $expected ] ||
6835                 error "'$cmd' wrong: found $nums, expected $expected"
6836 }
6837 run_test 56p "check lfs find -uid and ! -uid"
6838
6839 test_56q() {
6840         [ $RUNAS_ID -eq $UID ] &&
6841                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6842
6843         local dir=$DIR/$tdir
6844
6845         setup_56 $dir $NUMFILES $NUMDIRS
6846         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6847
6848         local expected=$NUMFILES
6849         local cmd="$LFS find -gid $RUNAS_GID $dir"
6850         local nums=$($cmd | wc -l)
6851
6852         [ $nums -eq $expected ] ||
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854
6855         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6856         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860 }
6861 run_test 56q "check lfs find -gid and ! -gid"
6862
6863 test_56r() {
6864         local dir=$DIR/$tdir
6865
6866         setup_56 $dir $NUMFILES $NUMDIRS
6867
6868         local expected=12
6869         local cmd="$LFS find -size 0 -type f -lazy $dir"
6870         local nums=$($cmd | wc -l)
6871
6872         [ $nums -eq $expected ] ||
6873                 error "'$cmd' wrong: found $nums, expected $expected"
6874         cmd="$LFS find -size 0 -type f $dir"
6875         nums=$($cmd | wc -l)
6876         [ $nums -eq $expected ] ||
6877                 error "'$cmd' wrong: found $nums, expected $expected"
6878
6879         expected=0
6880         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6881         nums=$($cmd | wc -l)
6882         [ $nums -eq $expected ] ||
6883                 error "'$cmd' wrong: found $nums, expected $expected"
6884         cmd="$LFS find ! -size 0 -type f $dir"
6885         nums=$($cmd | wc -l)
6886         [ $nums -eq $expected ] ||
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888
6889         echo "test" > $dir/$tfile
6890         echo "test2" > $dir/$tfile.2 && sync
6891         expected=1
6892         cmd="$LFS find -size 5 -type f -lazy $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896         cmd="$LFS find -size 5 -type f $dir"
6897         nums=$($cmd | wc -l)
6898         [ $nums -eq $expected ] ||
6899                 error "'$cmd' wrong: found $nums, expected $expected"
6900
6901         expected=1
6902         cmd="$LFS find -size +5 -type f -lazy $dir"
6903         nums=$($cmd | wc -l)
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906         cmd="$LFS find -size +5 -type f $dir"
6907         nums=$($cmd | wc -l)
6908         [ $nums -eq $expected ] ||
6909                 error "'$cmd' wrong: found $nums, expected $expected"
6910
6911         expected=2
6912         cmd="$LFS find -size +0 -type f -lazy $dir"
6913         nums=$($cmd | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916         cmd="$LFS find -size +0 -type f $dir"
6917         nums=$($cmd | wc -l)
6918         [ $nums -eq $expected ] ||
6919                 error "'$cmd' wrong: found $nums, expected $expected"
6920
6921         expected=2
6922         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6923         nums=$($cmd | wc -l)
6924         [ $nums -eq $expected ] ||
6925                 error "'$cmd' wrong: found $nums, expected $expected"
6926         cmd="$LFS find ! -size -5 -type f $dir"
6927         nums=$($cmd | wc -l)
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930
6931         expected=12
6932         cmd="$LFS find -size -5 -type f -lazy $dir"
6933         nums=$($cmd | wc -l)
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936         cmd="$LFS find -size -5 -type f $dir"
6937         nums=$($cmd | wc -l)
6938         [ $nums -eq $expected ] ||
6939                 error "'$cmd' wrong: found $nums, expected $expected"
6940 }
6941 run_test 56r "check lfs find -size works"
6942
6943 test_56ra_sub() {
6944         local expected=$1
6945         local glimpses=$2
6946         local cmd="$3"
6947
6948         cancel_lru_locks $OSC
6949
6950         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6951         local nums=$($cmd | wc -l)
6952
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6957
6958         if (( rpcs_before + glimpses != rpcs_after )); then
6959                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6960                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6961
6962                 if [[ $glimpses == 0 ]]; then
6963                         error "'$cmd' should not send glimpse RPCs to OST"
6964                 else
6965                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6966                 fi
6967         fi
6968 }
6969
6970 test_56ra() {
6971         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6972                 skip "MDS < 2.12.58 doesn't return LSOM data"
6973         local dir=$DIR/$tdir
6974         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6975
6976         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6977
6978         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6979         $LCTL set_param -n llite.*.statahead_agl=0
6980         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6981
6982         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6983         # open and close all files to ensure LSOM is updated
6984         cancel_lru_locks $OSC
6985         find $dir -type f | xargs cat > /dev/null
6986
6987         #   expect_found  glimpse_rpcs  command_to_run
6988         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6989         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6990         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6991         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6992
6993         echo "test" > $dir/$tfile
6994         echo "test2" > $dir/$tfile.2 && sync
6995         cancel_lru_locks $OSC
6996         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6997
6998         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6999         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7000         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7001         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7002
7003         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7004         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7005         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7006         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7007         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7008         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7009 }
7010 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7011
7012 test_56rb() {
7013         local dir=$DIR/$tdir
7014         local tmp=$TMP/$tfile.log
7015         local mdt_idx;
7016
7017         test_mkdir -p $dir || error "failed to mkdir $dir"
7018         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7019                 error "failed to setstripe $dir/$tfile"
7020         mdt_idx=$($LFS getdirstripe -i $dir)
7021         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7022
7023         stack_trap "rm -f $tmp" EXIT
7024         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7025         ! grep -q obd_uuid $tmp ||
7026                 error "failed to find --size +100K --ost 0 $dir"
7027         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7028         ! grep -q obd_uuid $tmp ||
7029                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7030 }
7031 run_test 56rb "check lfs find --size --ost/--mdt works"
7032
7033 test_56rc() {
7034         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7035         local dir=$DIR/$tdir
7036         local found
7037
7038         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7039         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7040         (( $MDSCOUNT > 2 )) &&
7041                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7042         mkdir $dir/$tdir-{1..10}
7043         touch $dir/$tfile-{1..10}
7044
7045         found=$($LFS find $dir --mdt-count 2 | wc -l)
7046         expect=11
7047         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7048
7049         found=$($LFS find $dir -T +1 | wc -l)
7050         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7051         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7052
7053         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7054         expect=11
7055         (( $found == $expect )) || error "found $found all_char, expect $expect"
7056
7057         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7058         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7059         (( $found == $expect )) || error "found $found all_char, expect $expect"
7060 }
7061 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7062
7063 test_56s() { # LU-611 #LU-9369
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7065
7066         local dir=$DIR/$tdir
7067         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7068
7069         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7070         for i in $(seq $NUMDIRS); do
7071                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7072         done
7073
7074         local expected=$NUMDIRS
7075         local cmd="$LFS find -c $OSTCOUNT $dir"
7076         local nums=$($cmd | wc -l)
7077
7078         [ $nums -eq $expected ] || {
7079                 $LFS getstripe -R $dir
7080                 error "'$cmd' wrong: found $nums, expected $expected"
7081         }
7082
7083         expected=$((NUMDIRS + onestripe))
7084         cmd="$LFS find -stripe-count +0 -type f $dir"
7085         nums=$($cmd | wc -l)
7086         [ $nums -eq $expected ] || {
7087                 $LFS getstripe -R $dir
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089         }
7090
7091         expected=$onestripe
7092         cmd="$LFS find -stripe-count 1 -type f $dir"
7093         nums=$($cmd | wc -l)
7094         [ $nums -eq $expected ] || {
7095                 $LFS getstripe -R $dir
7096                 error "'$cmd' wrong: found $nums, expected $expected"
7097         }
7098
7099         cmd="$LFS find -stripe-count -2 -type f $dir"
7100         nums=$($cmd | wc -l)
7101         [ $nums -eq $expected ] || {
7102                 $LFS getstripe -R $dir
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104         }
7105
7106         expected=0
7107         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7108         nums=$($cmd | wc -l)
7109         [ $nums -eq $expected ] || {
7110                 $LFS getstripe -R $dir
7111                 error "'$cmd' wrong: found $nums, expected $expected"
7112         }
7113 }
7114 run_test 56s "check lfs find -stripe-count works"
7115
7116 test_56t() { # LU-611 #LU-9369
7117         local dir=$DIR/$tdir
7118
7119         setup_56 $dir 0 $NUMDIRS
7120         for i in $(seq $NUMDIRS); do
7121                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7122         done
7123
7124         local expected=$NUMDIRS
7125         local cmd="$LFS find -S 8M $dir"
7126         local nums=$($cmd | wc -l)
7127
7128         [ $nums -eq $expected ] || {
7129                 $LFS getstripe -R $dir
7130                 error "'$cmd' wrong: found $nums, expected $expected"
7131         }
7132         rm -rf $dir
7133
7134         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7135
7136         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7137
7138         expected=$(((NUMDIRS + 1) * NUMFILES))
7139         cmd="$LFS find -stripe-size 512k -type f $dir"
7140         nums=$($cmd | wc -l)
7141         [ $nums -eq $expected ] ||
7142                 error "'$cmd' wrong: found $nums, expected $expected"
7143
7144         cmd="$LFS find -stripe-size +320k -type f $dir"
7145         nums=$($cmd | wc -l)
7146         [ $nums -eq $expected ] ||
7147                 error "'$cmd' wrong: found $nums, expected $expected"
7148
7149         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7150         cmd="$LFS find -stripe-size +200k -type f $dir"
7151         nums=$($cmd | wc -l)
7152         [ $nums -eq $expected ] ||
7153                 error "'$cmd' wrong: found $nums, expected $expected"
7154
7155         cmd="$LFS find -stripe-size -640k -type f $dir"
7156         nums=$($cmd | wc -l)
7157         [ $nums -eq $expected ] ||
7158                 error "'$cmd' wrong: found $nums, expected $expected"
7159
7160         expected=4
7161         cmd="$LFS find -stripe-size 256k -type f $dir"
7162         nums=$($cmd | wc -l)
7163         [ $nums -eq $expected ] ||
7164                 error "'$cmd' wrong: found $nums, expected $expected"
7165
7166         cmd="$LFS find -stripe-size -320k -type f $dir"
7167         nums=$($cmd | wc -l)
7168         [ $nums -eq $expected ] ||
7169                 error "'$cmd' wrong: found $nums, expected $expected"
7170
7171         expected=0
7172         cmd="$LFS find -stripe-size 1024k -type f $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176 }
7177 run_test 56t "check lfs find -stripe-size works"
7178
7179 test_56u() { # LU-611
7180         local dir=$DIR/$tdir
7181
7182         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7183
7184         if [[ $OSTCOUNT -gt 1 ]]; then
7185                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7186                 onestripe=4
7187         else
7188                 onestripe=0
7189         fi
7190
7191         local expected=$(((NUMDIRS + 1) * NUMFILES))
7192         local cmd="$LFS find -stripe-index 0 -type f $dir"
7193         local nums=$($cmd | wc -l)
7194
7195         [ $nums -eq $expected ] ||
7196                 error "'$cmd' wrong: found $nums, expected $expected"
7197
7198         expected=$onestripe
7199         cmd="$LFS find -stripe-index 1 -type f $dir"
7200         nums=$($cmd | wc -l)
7201         [ $nums -eq $expected ] ||
7202                 error "'$cmd' wrong: found $nums, expected $expected"
7203
7204         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7205         nums=$($cmd | wc -l)
7206         [ $nums -eq $expected ] ||
7207                 error "'$cmd' wrong: found $nums, expected $expected"
7208
7209         expected=0
7210         # This should produce an error and not return any files
7211         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7212         nums=$($cmd 2>/dev/null | wc -l)
7213         [ $nums -eq $expected ] ||
7214                 error "'$cmd' wrong: found $nums, expected $expected"
7215
7216         if [[ $OSTCOUNT -gt 1 ]]; then
7217                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7218                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7219                 nums=$($cmd | wc -l)
7220                 [ $nums -eq $expected ] ||
7221                         error "'$cmd' wrong: found $nums, expected $expected"
7222         fi
7223 }
7224 run_test 56u "check lfs find -stripe-index works"
7225
7226 test_56v() {
7227         local mdt_idx=0
7228         local dir=$DIR/$tdir
7229
7230         setup_56 $dir $NUMFILES $NUMDIRS
7231
7232         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7233         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7234
7235         for file in $($LFS find -m $UUID $dir); do
7236                 file_midx=$($LFS getstripe -m $file)
7237                 [ $file_midx -eq $mdt_idx ] ||
7238                         error "lfs find -m $UUID != getstripe -m $file_midx"
7239         done
7240 }
7241 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7242
7243 test_56wa() {
7244         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7246
7247         local dir=$DIR/$tdir
7248
7249         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7250
7251         local stripe_size=$($LFS getstripe -S -d $dir) ||
7252                 error "$LFS getstripe -S -d $dir failed"
7253         stripe_size=${stripe_size%% *}
7254
7255         local file_size=$((stripe_size * OSTCOUNT))
7256         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7257         local required_space=$((file_num * file_size))
7258         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7259                            head -n1)
7260         (( free_space >= required_space / 1024 )) ||
7261                 skip_env "need $required_space, have $free_space kbytes"
7262
7263         local dd_bs=65536
7264         local dd_count=$((file_size / dd_bs))
7265
7266         # write data into the files
7267         local i
7268         local j
7269         local file
7270
7271         for ((i = 1; i <= NUMFILES; i++ )); do
7272                 file=$dir/file$i
7273                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7274                         error "write data into $file failed"
7275         done
7276         for ((i = 1; i <= NUMDIRS; i++ )); do
7277                 for ((j = 1; j <= NUMFILES; j++ )); do
7278                         file=$dir/dir$i/file$j
7279                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7280                                 error "write data into $file failed"
7281                 done
7282         done
7283
7284         # $LFS_MIGRATE will fail if hard link migration is unsupported
7285         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7286                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7287                         error "creating links to $dir/dir1/file1 failed"
7288         fi
7289
7290         local expected=-1
7291
7292         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7293
7294         # lfs_migrate file
7295         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7296
7297         echo "$cmd"
7298         eval $cmd || error "$cmd failed"
7299
7300         check_stripe_count $dir/file1 $expected
7301
7302         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7303                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7304                 # OST 1 if it is on OST 0. This file is small enough to
7305                 # be on only one stripe.
7306                 file=$dir/migr_1_ost
7307                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7308                         error "write data into $file failed"
7309                 local obdidx=$($LFS getstripe -i $file)
7310                 local oldmd5=$(md5sum $file)
7311                 local newobdidx=0
7312
7313                 (( obdidx != 0 )) || newobdidx=1
7314                 cmd="$LFS migrate -i $newobdidx $file"
7315                 echo $cmd
7316                 eval $cmd || error "$cmd failed"
7317
7318                 local realobdix=$($LFS getstripe -i $file)
7319                 local newmd5=$(md5sum $file)
7320
7321                 (( $newobdidx == $realobdix )) ||
7322                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7323                 [[ "$oldmd5" == "$newmd5" ]] ||
7324                         error "md5sum differ: $oldmd5, $newmd5"
7325         fi
7326
7327         # lfs_migrate dir
7328         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7329         echo "$cmd"
7330         eval $cmd || error "$cmd failed"
7331
7332         for (( j = 1; j <= NUMFILES; j++ )); do
7333                 check_stripe_count $dir/dir1/file$j $expected
7334         done
7335
7336         # lfs_migrate works with lfs find
7337         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7338              $LFS_MIGRATE -y -c $expected"
7339         echo "$cmd"
7340         eval $cmd || error "$cmd failed"
7341
7342         for (( i = 2; i <= NUMFILES; i++ )); do
7343                 check_stripe_count $dir/file$i $expected
7344         done
7345         for (( i = 2; i <= NUMDIRS; i++ )); do
7346                 for (( j = 1; j <= NUMFILES; j++ )); do
7347                         check_stripe_count $dir/dir$i/file$j $expected
7348                 done
7349         done
7350 }
7351 run_test 56wa "check lfs_migrate -c stripe_count works"
7352
7353 test_56wb() {
7354         local file1=$DIR/$tdir/file1
7355         local create_pool=false
7356         local initial_pool=$($LFS getstripe -p $DIR)
7357         local pool_list=()
7358         local pool=""
7359
7360         echo -n "Creating test dir..."
7361         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7362         echo "done."
7363
7364         echo -n "Creating test file..."
7365         touch $file1 || error "cannot create file"
7366         echo "done."
7367
7368         echo -n "Detecting existing pools..."
7369         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7370
7371         if [ ${#pool_list[@]} -gt 0 ]; then
7372                 echo "${pool_list[@]}"
7373                 for thispool in "${pool_list[@]}"; do
7374                         if [[ -z "$initial_pool" ||
7375                               "$initial_pool" != "$thispool" ]]; then
7376                                 pool="$thispool"
7377                                 echo "Using existing pool '$pool'"
7378                                 break
7379                         fi
7380                 done
7381         else
7382                 echo "none detected."
7383         fi
7384         if [ -z "$pool" ]; then
7385                 pool=${POOL:-testpool}
7386                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7387                 echo -n "Creating pool '$pool'..."
7388                 create_pool=true
7389                 pool_add $pool &> /dev/null ||
7390                         error "pool_add failed"
7391                 echo "done."
7392
7393                 echo -n "Adding target to pool..."
7394                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7395                         error "pool_add_targets failed"
7396                 echo "done."
7397         fi
7398
7399         echo -n "Setting pool using -p option..."
7400         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7401                 error "migrate failed rc = $?"
7402         echo "done."
7403
7404         echo -n "Verifying test file is in pool after migrating..."
7405         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7406                 error "file was not migrated to pool $pool"
7407         echo "done."
7408
7409         echo -n "Removing test file from pool '$pool'..."
7410         # "lfs migrate $file" won't remove the file from the pool
7411         # until some striping information is changed.
7412         $LFS migrate -c 1 $file1 &> /dev/null ||
7413                 error "cannot remove from pool"
7414         [ "$($LFS getstripe -p $file1)" ] &&
7415                 error "pool still set"
7416         echo "done."
7417
7418         echo -n "Setting pool using --pool option..."
7419         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7420                 error "migrate failed rc = $?"
7421         echo "done."
7422
7423         # Clean up
7424         rm -f $file1
7425         if $create_pool; then
7426                 destroy_test_pools 2> /dev/null ||
7427                         error "destroy test pools failed"
7428         fi
7429 }
7430 run_test 56wb "check lfs_migrate pool support"
7431
7432 test_56wc() {
7433         local file1="$DIR/$tdir/$tfile"
7434         local md5
7435         local parent_ssize
7436         local parent_scount
7437         local cur_ssize
7438         local cur_scount
7439         local orig_ssize
7440         local new_scount
7441         local cur_comp
7442
7443         echo -n "Creating test dir..."
7444         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7445         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7446                 error "cannot set stripe by '-S 1M -c 1'"
7447         echo "done"
7448
7449         echo -n "Setting initial stripe for test file..."
7450         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7451                 error "cannot set stripe"
7452         cur_ssize=$($LFS getstripe -S "$file1")
7453         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7454         echo "done."
7455
7456         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7457         stack_trap "rm -f $file1"
7458         md5="$(md5sum $file1)"
7459
7460         # File currently set to -S 512K -c 1
7461
7462         # Ensure -c and -S options are rejected when -R is set
7463         echo -n "Verifying incompatible options are detected..."
7464         $LFS_MIGRATE -R -c 1 "$file1" &&
7465                 error "incompatible -R and -c options not detected"
7466         $LFS_MIGRATE -R -S 1M "$file1" &&
7467                 error "incompatible -R and -S options not detected"
7468         $LFS_MIGRATE -R -p pool "$file1" &&
7469                 error "incompatible -R and -p options not detected"
7470         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7471                 error "incompatible -R and -E options not detected"
7472         $LFS_MIGRATE -R -A "$file1" &&
7473                 error "incompatible -R and -A options not detected"
7474         $LFS_MIGRATE -A -c 1 "$file1" &&
7475                 error "incompatible -A and -c options not detected"
7476         $LFS_MIGRATE -A -S 1M "$file1" &&
7477                 error "incompatible -A and -S options not detected"
7478         $LFS_MIGRATE -A -p pool "$file1" &&
7479                 error "incompatible -A and -p options not detected"
7480         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7481                 error "incompatible -A and -E options not detected"
7482         echo "done."
7483
7484         # Ensure unrecognized options are passed through to 'lfs migrate'
7485         echo -n "Verifying -S option is passed through to lfs migrate..."
7486         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7487         cur_ssize=$($LFS getstripe -S "$file1")
7488         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7489         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7490         echo "done."
7491
7492         # File currently set to -S 1M -c 1
7493
7494         # Ensure long options are supported
7495         echo -n "Verifying long options supported..."
7496         $LFS_MIGRATE --non-block "$file1" ||
7497                 error "long option without argument not supported"
7498         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7499                 error "long option with argument not supported"
7500         cur_ssize=$($LFS getstripe -S "$file1")
7501         (( cur_ssize == 524288 )) ||
7502                 error "migrate --stripe-size $cur_ssize != 524288"
7503         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7504         echo "done."
7505
7506         # File currently set to -S 512K -c 1
7507
7508         if (( OSTCOUNT > 1 )); then
7509                 echo -n "Verifying explicit stripe count can be set..."
7510                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7511                 cur_scount=$($LFS getstripe -c "$file1")
7512                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7513                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7514                         error "file data has changed (3)"
7515                 echo "done."
7516         fi
7517
7518         # File currently set to -S 512K -c 1 or -S 512K -c 2
7519
7520         # Ensure parent striping is used if -R is set, and no stripe
7521         # count or size is specified
7522         echo -n "Setting stripe for parent directory..."
7523         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7524                 error "cannot set stripe '-S 2M -c 1'"
7525         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7526         echo "done."
7527
7528         echo -n "Verifying restripe option uses parent stripe settings..."
7529         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7530         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7531         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7532         cur_ssize=$($LFS getstripe -S "$file1")
7533         (( cur_ssize == parent_ssize )) ||
7534                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7535         cur_scount=$($LFS getstripe -c "$file1")
7536         (( cur_scount == parent_scount )) ||
7537                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7538         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7539         echo "done."
7540
7541         # File currently set to -S 1M -c 1
7542
7543         # Ensure striping is preserved if -R is not set, and no stripe
7544         # count or size is specified
7545         echo -n "Verifying striping size preserved when not specified..."
7546         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7547         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7548                 error "cannot set stripe on parent directory"
7549         $LFS_MIGRATE "$file1" || error "migrate failed"
7550         cur_ssize=$($LFS getstripe -S "$file1")
7551         (( cur_ssize == orig_ssize )) ||
7552                 error "migrate by default $cur_ssize != $orig_ssize"
7553         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7554         echo "done."
7555
7556         # Ensure file name properly detected when final option has no argument
7557         echo -n "Verifying file name properly detected..."
7558         $LFS_MIGRATE "$file1" ||
7559                 error "file name interpreted as option argument"
7560         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7561         echo "done."
7562
7563         # Ensure PFL arguments are passed through properly
7564         echo -n "Verifying PFL options passed through..."
7565         new_scount=$(((OSTCOUNT + 1) / 2))
7566         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7567                 error "migrate PFL arguments failed"
7568         cur_comp=$($LFS getstripe --comp-count $file1)
7569         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7570         cur_scount=$($LFS getstripe --stripe-count $file1)
7571         (( cur_scount == new_scount)) ||
7572                 error "PFL stripe count $cur_scount != $new_scount"
7573         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7574         echo "done."
7575 }
7576 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7577
7578 test_56wd() {
7579         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7580
7581         local file1=$DIR/$tdir/$tfile
7582
7583         echo -n "Creating test dir..."
7584         test_mkdir $DIR/$tdir || error "cannot create dir"
7585         echo "done."
7586
7587         echo -n "Creating test file..."
7588         echo "$tfile" > $file1
7589         echo "done."
7590
7591         # Ensure 'lfs migrate' will fail by using a non-existent option,
7592         # and make sure rsync is not called to recover
7593         echo -n "Make sure --no-rsync option works..."
7594         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7595                 grep -q 'refusing to fall back to rsync' ||
7596                 error "rsync was called with --no-rsync set"
7597         echo "done."
7598
7599         # Ensure rsync is called without trying 'lfs migrate' first
7600         echo -n "Make sure --rsync option works..."
7601         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7602                 grep -q 'falling back to rsync' &&
7603                 error "lfs migrate was called with --rsync set"
7604         echo "done."
7605 }
7606 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7607
7608 test_56we() {
7609         local td=$DIR/$tdir
7610         local tf=$td/$tfile
7611
7612         test_mkdir $td || error "cannot create $td"
7613         touch $tf || error "cannot touch $tf"
7614
7615         echo -n "Make sure --non-direct|-D works..."
7616         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7617                 grep -q "lfs migrate --non-direct" ||
7618                 error "--non-direct option cannot work correctly"
7619         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7620                 grep -q "lfs migrate -D" ||
7621                 error "-D option cannot work correctly"
7622         echo "done."
7623 }
7624 run_test 56we "check lfs_migrate --non-direct|-D support"
7625
7626 test_56x() {
7627         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7628         check_swap_layouts_support
7629
7630         local dir=$DIR/$tdir
7631         local ref1=/etc/passwd
7632         local file1=$dir/file1
7633
7634         test_mkdir $dir || error "creating dir $dir"
7635         $LFS setstripe -c 2 $file1
7636         cp $ref1 $file1
7637         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7638         stripe=$($LFS getstripe -c $file1)
7639         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7640         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7641
7642         # clean up
7643         rm -f $file1
7644 }
7645 run_test 56x "lfs migration support"
7646
7647 test_56xa() {
7648         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7649         check_swap_layouts_support
7650
7651         local dir=$DIR/$tdir/$testnum
7652
7653         test_mkdir -p $dir
7654
7655         local ref1=/etc/passwd
7656         local file1=$dir/file1
7657
7658         $LFS setstripe -c 2 $file1
7659         cp $ref1 $file1
7660         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7661
7662         local stripe=$($LFS getstripe -c $file1)
7663
7664         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7665         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7666
7667         # clean up
7668         rm -f $file1
7669 }
7670 run_test 56xa "lfs migration --block support"
7671
7672 check_migrate_links() {
7673         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7674         local dir="$1"
7675         local file1="$dir/file1"
7676         local begin="$2"
7677         local count="$3"
7678         local runas="$4"
7679         local total_count=$(($begin + $count - 1))
7680         local symlink_count=10
7681         local uniq_count=10
7682
7683         if [ ! -f "$file1" ]; then
7684                 echo -n "creating initial file..."
7685                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7686                         error "cannot setstripe initial file"
7687                 echo "done"
7688
7689                 echo -n "creating symlinks..."
7690                 for s in $(seq 1 $symlink_count); do
7691                         ln -s "$file1" "$dir/slink$s" ||
7692                                 error "cannot create symlinks"
7693                 done
7694                 echo "done"
7695
7696                 echo -n "creating nonlinked files..."
7697                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7698                         error "cannot create nonlinked files"
7699                 echo "done"
7700         fi
7701
7702         # create hard links
7703         if [ ! -f "$dir/file$total_count" ]; then
7704                 echo -n "creating hard links $begin:$total_count..."
7705                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7706                         /dev/null || error "cannot create hard links"
7707                 echo "done"
7708         fi
7709
7710         echo -n "checking number of hard links listed in xattrs..."
7711         local fid=$($LFS getstripe -F "$file1")
7712         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7713
7714         echo "${#paths[*]}"
7715         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7716                         skip "hard link list has unexpected size, skipping test"
7717         fi
7718         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7719                         error "link names should exceed xattrs size"
7720         fi
7721
7722         echo -n "migrating files..."
7723         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7724         local rc=$?
7725         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7726         echo "done"
7727
7728         # make sure all links have been properly migrated
7729         echo -n "verifying files..."
7730         fid=$($LFS getstripe -F "$file1") ||
7731                 error "cannot get fid for file $file1"
7732         for i in $(seq 2 $total_count); do
7733                 local fid2=$($LFS getstripe -F $dir/file$i)
7734
7735                 [ "$fid2" == "$fid" ] ||
7736                         error "migrated hard link has mismatched FID"
7737         done
7738
7739         # make sure hard links were properly detected, and migration was
7740         # performed only once for the entire link set; nonlinked files should
7741         # also be migrated
7742         local actual=$(grep -c 'done' <<< "$migrate_out")
7743         local expected=$(($uniq_count + 1))
7744
7745         [ "$actual" -eq  "$expected" ] ||
7746                 error "hard links individually migrated ($actual != $expected)"
7747
7748         # make sure the correct number of hard links are present
7749         local hardlinks=$(stat -c '%h' "$file1")
7750
7751         [ $hardlinks -eq $total_count ] ||
7752                 error "num hard links $hardlinks != $total_count"
7753         echo "done"
7754
7755         return 0
7756 }
7757
7758 test_56xb() {
7759         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7760                 skip "Need MDS version at least 2.10.55"
7761
7762         local dir="$DIR/$tdir"
7763
7764         test_mkdir "$dir" || error "cannot create dir $dir"
7765
7766         echo "testing lfs migrate mode when all links fit within xattrs"
7767         check_migrate_links "$dir" 2 99
7768
7769         echo "testing rsync mode when all links fit within xattrs"
7770         check_migrate_links --rsync "$dir" 2 99
7771
7772         echo "testing lfs migrate mode when all links do not fit within xattrs"
7773         check_migrate_links "$dir" 101 100
7774
7775         echo "testing rsync mode when all links do not fit within xattrs"
7776         check_migrate_links --rsync "$dir" 101 100
7777
7778         chown -R $RUNAS_ID $dir
7779         echo "testing non-root lfs migrate mode when not all links are in xattr"
7780         check_migrate_links "$dir" 101 100 "$RUNAS"
7781
7782         # clean up
7783         rm -rf $dir
7784 }
7785 run_test 56xb "lfs migration hard link support"
7786
7787 test_56xc() {
7788         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7789
7790         local dir="$DIR/$tdir"
7791
7792         test_mkdir "$dir" || error "cannot create dir $dir"
7793
7794         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7795         echo -n "Setting initial stripe for 20MB test file..."
7796         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7797                 error "cannot setstripe 20MB file"
7798         echo "done"
7799         echo -n "Sizing 20MB test file..."
7800         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7801         echo "done"
7802         echo -n "Verifying small file autostripe count is 1..."
7803         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7804                 error "cannot migrate 20MB file"
7805         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7806                 error "cannot get stripe for $dir/20mb"
7807         [ $stripe_count -eq 1 ] ||
7808                 error "unexpected stripe count $stripe_count for 20MB file"
7809         rm -f "$dir/20mb"
7810         echo "done"
7811
7812         # Test 2: File is small enough to fit within the available space on
7813         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7814         # have at least an additional 1KB for each desired stripe for test 3
7815         echo -n "Setting stripe for 1GB test file..."
7816         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7817         echo "done"
7818         echo -n "Sizing 1GB test file..."
7819         # File size is 1GB + 3KB
7820         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7821         echo "done"
7822
7823         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7824         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7825         if (( avail > 524288 * OSTCOUNT )); then
7826                 echo -n "Migrating 1GB file..."
7827                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7828                         error "cannot migrate 1GB file"
7829                 echo "done"
7830                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7831                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7832                         error "cannot getstripe for 1GB file"
7833                 [ $stripe_count -eq 2 ] ||
7834                         error "unexpected stripe count $stripe_count != 2"
7835                 echo "done"
7836         fi
7837
7838         # Test 3: File is too large to fit within the available space on
7839         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7840         if [ $OSTCOUNT -ge 3 ]; then
7841                 # The required available space is calculated as
7842                 # file size (1GB + 3KB) / OST count (3).
7843                 local kb_per_ost=349526
7844
7845                 echo -n "Migrating 1GB file with limit..."
7846                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7847                         error "cannot migrate 1GB file with limit"
7848                 echo "done"
7849
7850                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7851                 echo -n "Verifying 1GB autostripe count with limited space..."
7852                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7853                         error "unexpected stripe count $stripe_count (min 3)"
7854                 echo "done"
7855         fi
7856
7857         # clean up
7858         rm -rf $dir
7859 }
7860 run_test 56xc "lfs migration autostripe"
7861
7862 test_56xd() {
7863         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7864
7865         local dir=$DIR/$tdir
7866         local f_mgrt=$dir/$tfile.mgrt
7867         local f_yaml=$dir/$tfile.yaml
7868         local f_copy=$dir/$tfile.copy
7869         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7870         local layout_copy="-c 2 -S 2M -i 1"
7871         local yamlfile=$dir/yamlfile
7872         local layout_before;
7873         local layout_after;
7874
7875         test_mkdir "$dir" || error "cannot create dir $dir"
7876         $LFS setstripe $layout_yaml $f_yaml ||
7877                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7878         $LFS getstripe --yaml $f_yaml > $yamlfile
7879         $LFS setstripe $layout_copy $f_copy ||
7880                 error "cannot setstripe $f_copy with layout $layout_copy"
7881         touch $f_mgrt
7882         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7883
7884         # 1. test option --yaml
7885         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7886                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7887         layout_before=$(get_layout_param $f_yaml)
7888         layout_after=$(get_layout_param $f_mgrt)
7889         [ "$layout_after" == "$layout_before" ] ||
7890                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7891
7892         # 2. test option --copy
7893         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7894                 error "cannot migrate $f_mgrt with --copy $f_copy"
7895         layout_before=$(get_layout_param $f_copy)
7896         layout_after=$(get_layout_param $f_mgrt)
7897         [ "$layout_after" == "$layout_before" ] ||
7898                 error "lfs_migrate --copy: $layout_after != $layout_before"
7899 }
7900 run_test 56xd "check lfs_migrate --yaml and --copy support"
7901
7902 test_56xe() {
7903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7904
7905         local dir=$DIR/$tdir
7906         local f_comp=$dir/$tfile
7907         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7908         local layout_before=""
7909         local layout_after=""
7910
7911         test_mkdir "$dir" || error "cannot create dir $dir"
7912         $LFS setstripe $layout $f_comp ||
7913                 error "cannot setstripe $f_comp with layout $layout"
7914         layout_before=$(get_layout_param $f_comp)
7915         dd if=/dev/zero of=$f_comp bs=1M count=4
7916
7917         # 1. migrate a comp layout file by lfs_migrate
7918         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7919         layout_after=$(get_layout_param $f_comp)
7920         [ "$layout_before" == "$layout_after" ] ||
7921                 error "lfs_migrate: $layout_before != $layout_after"
7922
7923         # 2. migrate a comp layout file by lfs migrate
7924         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7925         layout_after=$(get_layout_param $f_comp)
7926         [ "$layout_before" == "$layout_after" ] ||
7927                 error "lfs migrate: $layout_before != $layout_after"
7928 }
7929 run_test 56xe "migrate a composite layout file"
7930
7931 test_56xf() {
7932         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7933
7934         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7935                 skip "Need server version at least 2.13.53"
7936
7937         local dir=$DIR/$tdir
7938         local f_comp=$dir/$tfile
7939         local layout="-E 1M -c1 -E -1 -c2"
7940         local fid_before=""
7941         local fid_after=""
7942
7943         test_mkdir "$dir" || error "cannot create dir $dir"
7944         $LFS setstripe $layout $f_comp ||
7945                 error "cannot setstripe $f_comp with layout $layout"
7946         fid_before=$($LFS getstripe --fid $f_comp)
7947         dd if=/dev/zero of=$f_comp bs=1M count=4
7948
7949         # 1. migrate a comp layout file to a comp layout
7950         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7951         fid_after=$($LFS getstripe --fid $f_comp)
7952         [ "$fid_before" == "$fid_after" ] ||
7953                 error "comp-to-comp migrate: $fid_before != $fid_after"
7954
7955         # 2. migrate a comp layout file to a plain layout
7956         $LFS migrate -c2 $f_comp ||
7957                 error "cannot migrate $f_comp by lfs migrate"
7958         fid_after=$($LFS getstripe --fid $f_comp)
7959         [ "$fid_before" == "$fid_after" ] ||
7960                 error "comp-to-plain migrate: $fid_before != $fid_after"
7961
7962         # 3. migrate a plain layout file to a comp layout
7963         $LFS migrate $layout $f_comp ||
7964                 error "cannot migrate $f_comp by lfs migrate"
7965         fid_after=$($LFS getstripe --fid $f_comp)
7966         [ "$fid_before" == "$fid_after" ] ||
7967                 error "plain-to-comp migrate: $fid_before != $fid_after"
7968 }
7969 run_test 56xf "FID is not lost during migration of a composite layout file"
7970
7971 check_file_ost_range() {
7972         local file="$1"
7973         shift
7974         local range="$*"
7975         local -a file_range
7976         local idx
7977
7978         file_range=($($LFS getstripe -y "$file" |
7979                 awk '/l_ost_idx:/ { print $NF }'))
7980
7981         if [[ "${#file_range[@]}" = 0 ]]; then
7982                 echo "No osts found for $file"
7983                 return 1
7984         fi
7985
7986         for idx in "${file_range[@]}"; do
7987                 [[ " $range " =~ " $idx " ]] ||
7988                         return 1
7989         done
7990
7991         return 0
7992 }
7993
7994 sub_test_56xg() {
7995         local stripe_opt="$1"
7996         local pool="$2"
7997         shift 2
7998         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7999
8000         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8001                 error "Fail to migrate $tfile on $pool"
8002         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8003                 error "$tfile is not in pool $pool"
8004         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8005                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8006 }
8007
8008 test_56xg() {
8009         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8010         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8011         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8012                 skip "Need MDS version newer than 2.14.52"
8013
8014         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8015         local -a pool_ranges=("0 0" "1 1" "0 1")
8016
8017         # init pools
8018         for i in "${!pool_names[@]}"; do
8019                 pool_add ${pool_names[$i]} ||
8020                         error "pool_add failed (pool: ${pool_names[$i]})"
8021                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8022                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8023         done
8024
8025         # init the file to migrate
8026         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8027                 error "Unable to create $tfile on OST1"
8028         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8029                 error "Unable to write on $tfile"
8030
8031         echo "1. migrate $tfile on pool ${pool_names[0]}"
8032         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8033
8034         echo "2. migrate $tfile on pool ${pool_names[2]}"
8035         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8036
8037         echo "3. migrate $tfile on pool ${pool_names[1]}"
8038         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8039
8040         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8041         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8042         echo
8043
8044         # Clean pools
8045         destroy_test_pools ||
8046                 error "pool_destroy failed"
8047 }
8048 run_test 56xg "lfs migrate pool support"
8049
8050 test_56xh() {
8051         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8052
8053         local size_mb=25
8054         local file1=$DIR/$tfile
8055         local tmp1=$TMP/$tfile.tmp
8056
8057         $LFS setstripe -c 2 $file1
8058
8059         stack_trap "rm -f $file1 $tmp1"
8060         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8061                         error "error creating $tmp1"
8062         ls -lsh $tmp1
8063         cp $tmp1 $file1
8064
8065         local start=$SECONDS
8066
8067         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8068                 error "migrate failed rc = $?"
8069
8070         local elapsed=$((SECONDS - start))
8071
8072         # with 1MB/s, elapsed should equal size_mb
8073         (( elapsed >= size_mb * 95 / 100 )) ||
8074                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8075
8076         (( elapsed <= size_mb * 120 / 100 )) ||
8077                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8078
8079         (( elapsed <= size_mb * 150 / 100 )) ||
8080                 error "'lfs migrate -W' too slow in VM ($elapsed > 2 * $size_mb 2)"
8081
8082         stripe=$($LFS getstripe -c $file1)
8083         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8084         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8085
8086         # Clean up file (since it is multiple MB)
8087         rm -f $file1 $tmp1
8088 }
8089 run_test 56xh "lfs migrate bandwidth limitation support"
8090
8091 test_56xi() {
8092         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8093         verify_yaml_available || skip_env "YAML verification not installed"
8094
8095         local size_mb=5
8096         local file1=$DIR/$tfile.1
8097         local file2=$DIR/$tfile.2
8098         local file3=$DIR/$tfile.3
8099         local output_file=$DIR/$tfile.out
8100         local tmp1=$TMP/$tfile.tmp
8101
8102         $LFS setstripe -c 2 $file1
8103         $LFS setstripe -c 2 $file2
8104         $LFS setstripe -c 2 $file3
8105
8106         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8107         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8108                         error "error creating $tmp1"
8109         ls -lsh $tmp1
8110         cp $tmp1 $file1
8111         cp $tmp1 $file2
8112         cp $tmp1 $file3
8113
8114         $LFS migrate --stats --stats-interval=1 \
8115                 -c 1 $file1 $file2 $file3 1> $output_file ||
8116                 error "migrate failed rc = $?"
8117
8118         cat $output_file
8119         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8120
8121         # Clean up file (since it is multiple MB)
8122         rm -f $file1 $file2 $file3 $tmp1 $output_file
8123 }
8124 run_test 56xi "lfs migrate stats support"
8125
8126 test_56y() {
8127         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8128                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8129
8130         local res=""
8131         local dir=$DIR/$tdir
8132         local f1=$dir/file1
8133         local f2=$dir/file2
8134
8135         test_mkdir -p $dir || error "creating dir $dir"
8136         touch $f1 || error "creating std file $f1"
8137         $MULTIOP $f2 H2c || error "creating released file $f2"
8138
8139         # a directory can be raid0, so ask only for files
8140         res=$($LFS find $dir -L raid0 -type f | wc -l)
8141         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8142
8143         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8144         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8145
8146         # only files can be released, so no need to force file search
8147         res=$($LFS find $dir -L released)
8148         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8149
8150         res=$($LFS find $dir -type f \! -L released)
8151         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8152 }
8153 run_test 56y "lfs find -L raid0|released"
8154
8155 test_56z() { # LU-4824
8156         # This checks to make sure 'lfs find' continues after errors
8157         # There are two classes of errors that should be caught:
8158         # - If multiple paths are provided, all should be searched even if one
8159         #   errors out
8160         # - If errors are encountered during the search, it should not terminate
8161         #   early
8162         local dir=$DIR/$tdir
8163         local i
8164
8165         test_mkdir $dir
8166         for i in d{0..9}; do
8167                 test_mkdir $dir/$i
8168                 touch $dir/$i/$tfile
8169         done
8170         $LFS find $DIR/non_existent_dir $dir &&
8171                 error "$LFS find did not return an error"
8172         # Make a directory unsearchable. This should NOT be the last entry in
8173         # directory order.  Arbitrarily pick the 6th entry
8174         chmod 700 $($LFS find $dir -type d | sed '6!d')
8175
8176         $RUNAS $LFS find $DIR/non_existent $dir
8177         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8178
8179         # The user should be able to see 10 directories and 9 files
8180         (( count == 19 )) ||
8181                 error "$LFS find found $count != 19 entries after error"
8182 }
8183 run_test 56z "lfs find should continue after an error"
8184
8185 test_56aa() { # LU-5937
8186         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8187
8188         local dir=$DIR/$tdir
8189
8190         mkdir $dir
8191         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8192
8193         createmany -o $dir/striped_dir/${tfile}- 1024
8194         local dirs=$($LFS find --size +8k $dir/)
8195
8196         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8197 }
8198 run_test 56aa "lfs find --size under striped dir"
8199
8200 test_56ab() { # LU-10705
8201         test_mkdir $DIR/$tdir
8202         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8203         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8204         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8205         # Flush writes to ensure valid blocks.  Need to be more thorough for
8206         # ZFS, since blocks are not allocated/returned to client immediately.
8207         sync_all_data
8208         wait_zfs_commit ost1 2
8209         cancel_lru_locks osc
8210         ls -ls $DIR/$tdir
8211
8212         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8213
8214         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8215
8216         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8217         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8218
8219         rm -f $DIR/$tdir/$tfile.[123]
8220 }
8221 run_test 56ab "lfs find --blocks"
8222
8223 # LU-11188
8224 test_56aca() {
8225         local dir="$DIR/$tdir"
8226         local perms=(001 002 003 004 005 006 007
8227                      010 020 030 040 050 060 070
8228                      100 200 300 400 500 600 700
8229                      111 222 333 444 555 666 777)
8230         local perm_minus=(8 8 4 8 4 4 2
8231                           8 8 4 8 4 4 2
8232                           8 8 4 8 4 4 2
8233                           4 4 2 4 2 2 1)
8234         local perm_slash=(8  8 12  8 12 12 14
8235                           8  8 12  8 12 12 14
8236                           8  8 12  8 12 12 14
8237                          16 16 24 16 24 24 28)
8238
8239         test_mkdir "$dir"
8240         for perm in ${perms[*]}; do
8241                 touch "$dir/$tfile.$perm"
8242                 chmod $perm "$dir/$tfile.$perm"
8243         done
8244
8245         for ((i = 0; i < ${#perms[*]}; i++)); do
8246                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8247                 (( $num == 1 )) ||
8248                         error "lfs find -perm ${perms[i]}:"\
8249                               "$num != 1"
8250
8251                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8252                 (( $num == ${perm_minus[i]} )) ||
8253                         error "lfs find -perm -${perms[i]}:"\
8254                               "$num != ${perm_minus[i]}"
8255
8256                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8257                 (( $num == ${perm_slash[i]} )) ||
8258                         error "lfs find -perm /${perms[i]}:"\
8259                               "$num != ${perm_slash[i]}"
8260         done
8261 }
8262 run_test 56aca "check lfs find -perm with octal representation"
8263
8264 test_56acb() {
8265         local dir=$DIR/$tdir
8266         # p is the permission of write and execute for user, group and other
8267         # without the umask. It is used to test +wx.
8268         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8269         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8270         local symbolic=(+t  a+t u+t g+t o+t
8271                         g+s u+s o+s +s o+sr
8272                         o=r,ug+o,u+w
8273                         u+ g+ o+ a+ ugo+
8274                         u- g- o- a- ugo-
8275                         u= g= o= a= ugo=
8276                         o=r,ug+o,u+w u=r,a+u,u+w
8277                         g=r,ugo=g,u+w u+x,+X +X
8278                         u+x,u+X u+X u+x,g+X o+r,+X
8279                         u+x,go+X +wx +rwx)
8280
8281         test_mkdir $dir
8282         for perm in ${perms[*]}; do
8283                 touch "$dir/$tfile.$perm"
8284                 chmod $perm "$dir/$tfile.$perm"
8285         done
8286
8287         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8288                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8289
8290                 (( $num == 1 )) ||
8291                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8292         done
8293 }
8294 run_test 56acb "check lfs find -perm with symbolic representation"
8295
8296 test_56acc() {
8297         local dir=$DIR/$tdir
8298         local tests="17777 787 789 abcd
8299                 ug=uu ug=a ug=gu uo=ou urw
8300                 u+xg+x a=r,u+x,"
8301
8302         test_mkdir $dir
8303         for err in $tests; do
8304                 if $LFS find $dir -perm $err 2>/dev/null; then
8305                         error "lfs find -perm $err: parsing should have failed"
8306                 fi
8307         done
8308 }
8309 run_test 56acc "check parsing error for lfs find -perm"
8310
8311 test_56ba() {
8312         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8313                 skip "Need MDS version at least 2.10.50"
8314
8315         # Create composite files with one component
8316         local dir=$DIR/$tdir
8317
8318         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8319         # Create composite files with three components
8320         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8321         # Create non-composite files
8322         createmany -o $dir/${tfile}- 10
8323
8324         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8325
8326         [[ $nfiles == 10 ]] ||
8327                 error "lfs find -E 1M found $nfiles != 10 files"
8328
8329         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8330         [[ $nfiles == 25 ]] ||
8331                 error "lfs find ! -E 1M found $nfiles != 25 files"
8332
8333         # All files have a component that starts at 0
8334         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8335         [[ $nfiles == 35 ]] ||
8336                 error "lfs find --component-start 0 - $nfiles != 35 files"
8337
8338         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8339         [[ $nfiles == 15 ]] ||
8340                 error "lfs find --component-start 2M - $nfiles != 15 files"
8341
8342         # All files created here have a componenet that does not starts at 2M
8343         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8344         [[ $nfiles == 35 ]] ||
8345                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8346
8347         # Find files with a specified number of components
8348         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8349         [[ $nfiles == 15 ]] ||
8350                 error "lfs find --component-count 3 - $nfiles != 15 files"
8351
8352         # Remember non-composite files have a component count of zero
8353         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8354         [[ $nfiles == 10 ]] ||
8355                 error "lfs find --component-count 0 - $nfiles != 10 files"
8356
8357         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8358         [[ $nfiles == 20 ]] ||
8359                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8360
8361         # All files have a flag called "init"
8362         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8363         [[ $nfiles == 35 ]] ||
8364                 error "lfs find --component-flags init - $nfiles != 35 files"
8365
8366         # Multi-component files will have a component not initialized
8367         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8368         [[ $nfiles == 15 ]] ||
8369                 error "lfs find !--component-flags init - $nfiles != 15 files"
8370
8371         rm -rf $dir
8372
8373 }
8374 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8375
8376 test_56ca() {
8377         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8378                 skip "Need MDS version at least 2.10.57"
8379
8380         local td=$DIR/$tdir
8381         local tf=$td/$tfile
8382         local dir
8383         local nfiles
8384         local cmd
8385         local i
8386         local j
8387
8388         # create mirrored directories and mirrored files
8389         mkdir $td || error "mkdir $td failed"
8390         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8391         createmany -o $tf- 10 || error "create $tf- failed"
8392
8393         for i in $(seq 2); do
8394                 dir=$td/dir$i
8395                 mkdir $dir || error "mkdir $dir failed"
8396                 $LFS mirror create -N$((3 + i)) $dir ||
8397                         error "create mirrored dir $dir failed"
8398                 createmany -o $dir/$tfile- 10 ||
8399                         error "create $dir/$tfile- failed"
8400         done
8401
8402         # change the states of some mirrored files
8403         echo foo > $tf-6
8404         for i in $(seq 2); do
8405                 dir=$td/dir$i
8406                 for j in $(seq 4 9); do
8407                         echo foo > $dir/$tfile-$j
8408                 done
8409         done
8410
8411         # find mirrored files with specific mirror count
8412         cmd="$LFS find --mirror-count 3 --type f $td"
8413         nfiles=$($cmd | wc -l)
8414         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8415
8416         cmd="$LFS find ! --mirror-count 3 --type f $td"
8417         nfiles=$($cmd | wc -l)
8418         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8419
8420         cmd="$LFS find --mirror-count +2 --type f $td"
8421         nfiles=$($cmd | wc -l)
8422         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8423
8424         cmd="$LFS find --mirror-count -6 --type f $td"
8425         nfiles=$($cmd | wc -l)
8426         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8427
8428         # find mirrored files with specific file state
8429         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8430         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8431
8432         cmd="$LFS find --mirror-state=ro --type f $td"
8433         nfiles=$($cmd | wc -l)
8434         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8435
8436         cmd="$LFS find ! --mirror-state=ro --type f $td"
8437         nfiles=$($cmd | wc -l)
8438         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8439
8440         cmd="$LFS find --mirror-state=wp --type f $td"
8441         nfiles=$($cmd | wc -l)
8442         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8443
8444         cmd="$LFS find ! --mirror-state=sp --type f $td"
8445         nfiles=$($cmd | wc -l)
8446         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8447 }
8448 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8449
8450 test_56da() { # LU-14179
8451         local path=$DIR/$tdir
8452
8453         test_mkdir $path
8454         cd $path
8455
8456         local longdir=$(str_repeat 'a' 255)
8457
8458         for i in {1..15}; do
8459                 path=$path/$longdir
8460                 test_mkdir $longdir
8461                 cd $longdir
8462         done
8463
8464         local len=${#path}
8465         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8466
8467         test_mkdir $lastdir
8468         cd $lastdir
8469         # PATH_MAX-1
8470         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8471
8472         # NAME_MAX
8473         touch $(str_repeat 'f' 255)
8474
8475         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8476                 error "lfs find reported an error"
8477
8478         rm -rf $DIR/$tdir
8479 }
8480 run_test 56da "test lfs find with long paths"
8481
8482 test_56ea() { #LU-10378
8483         local path=$DIR/$tdir
8484         local pool=$TESTNAME
8485
8486         # Create ost pool
8487         pool_add $pool || error "pool_add $pool failed"
8488         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8489                 error "adding targets to $pool failed"
8490
8491         # Set default pool on directory before creating file
8492         mkdir $path || error "mkdir $path failed"
8493         $LFS setstripe -p $pool $path ||
8494                 error "set OST pool on $pool failed"
8495         touch $path/$tfile || error "touch $path/$tfile failed"
8496
8497         # Compare basic file attributes from -printf and stat
8498         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8499         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8500
8501         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8502                 error "Attrs from lfs find and stat don't match"
8503
8504         # Compare Lustre attributes from lfs find and lfs getstripe
8505         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8506         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8507         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8508         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8509         local fpool=$($LFS getstripe --pool $path/$tfile)
8510         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8511
8512         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8513                 error "Attrs from lfs find and lfs getstripe don't match"
8514
8515         # Verify behavior for unknown escape/format sequences
8516         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8517
8518         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8519                 error "Escape/format codes don't match"
8520 }
8521 run_test 56ea "test lfs find -printf option"
8522
8523 test_56eb() {
8524         local dir=$DIR/$tdir
8525         local subdir_1=$dir/subdir_1
8526
8527         test_mkdir -p $subdir_1
8528         ln -s subdir_1 $dir/link_1
8529
8530         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8531                 error "symlink is not followed"
8532
8533         $LFS getstripe --no-follow $dir |
8534                 grep "^$dir/link_1 has no stripe info$" ||
8535                 error "symlink should not have stripe info"
8536
8537         touch $dir/testfile
8538         ln -s testfile $dir/file_link_2
8539
8540         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8541                 error "symlink is not followed"
8542
8543         $LFS getstripe --no-follow $dir |
8544                 grep "^$dir/file_link_2 has no stripe info$" ||
8545                 error "symlink should not have stripe info"
8546 }
8547 run_test 56eb "check lfs getstripe on symlink"
8548
8549 test_57a() {
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551         # note test will not do anything if MDS is not local
8552         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8553                 skip_env "ldiskfs only test"
8554         fi
8555         remote_mds_nodsh && skip "remote MDS with nodsh"
8556
8557         local MNTDEV="osd*.*MDT*.mntdev"
8558         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8559         [ -z "$DEV" ] && error "can't access $MNTDEV"
8560         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8561                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8562                         error "can't access $DEV"
8563                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8564                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8565                 rm $TMP/t57a.dump
8566         done
8567 }
8568 run_test 57a "verify MDS filesystem created with large inodes =="
8569
8570 test_57b() {
8571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8572         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8573                 skip_env "ldiskfs only test"
8574         fi
8575         remote_mds_nodsh && skip "remote MDS with nodsh"
8576
8577         local dir=$DIR/$tdir
8578         local filecount=100
8579         local file1=$dir/f1
8580         local fileN=$dir/f$filecount
8581
8582         rm -rf $dir || error "removing $dir"
8583         test_mkdir -c1 $dir
8584         local mdtidx=$($LFS getstripe -m $dir)
8585         local mdtname=MDT$(printf %04x $mdtidx)
8586         local facet=mds$((mdtidx + 1))
8587
8588         echo "mcreating $filecount files"
8589         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8590
8591         # verify that files do not have EAs yet
8592         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8593                 error "$file1 has an EA"
8594         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8595                 error "$fileN has an EA"
8596
8597         sync
8598         sleep 1
8599         df $dir  #make sure we get new statfs data
8600         local mdsfree=$(do_facet $facet \
8601                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8602         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8603         local file
8604
8605         echo "opening files to create objects/EAs"
8606         for file in $(seq -f $dir/f%g 1 $filecount); do
8607                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8608                         error "opening $file"
8609         done
8610
8611         # verify that files have EAs now
8612         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8613         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8614
8615         sleep 1  #make sure we get new statfs data
8616         df $dir
8617         local mdsfree2=$(do_facet $facet \
8618                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8619         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8620
8621         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8622                 if [ "$mdsfree" != "$mdsfree2" ]; then
8623                         error "MDC before $mdcfree != after $mdcfree2"
8624                 else
8625                         echo "MDC before $mdcfree != after $mdcfree2"
8626                         echo "unable to confirm if MDS has large inodes"
8627                 fi
8628         fi
8629         rm -rf $dir
8630 }
8631 run_test 57b "default LOV EAs are stored inside large inodes ==="
8632
8633 test_58() {
8634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8635         [ -z "$(which wiretest 2>/dev/null)" ] &&
8636                         skip_env "could not find wiretest"
8637
8638         wiretest
8639 }
8640 run_test 58 "verify cross-platform wire constants =============="
8641
8642 test_59() {
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644
8645         echo "touch 130 files"
8646         createmany -o $DIR/f59- 130
8647         echo "rm 130 files"
8648         unlinkmany $DIR/f59- 130
8649         sync
8650         # wait for commitment of removal
8651         wait_delete_completed
8652 }
8653 run_test 59 "verify cancellation of llog records async ========="
8654
8655 TEST60_HEAD="test_60 run $RANDOM"
8656 test_60a() {
8657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8658         remote_mgs_nodsh && skip "remote MGS with nodsh"
8659         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8660                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8661                         skip_env "missing subtest run-llog.sh"
8662
8663         log "$TEST60_HEAD - from kernel mode"
8664         do_facet mgs "$LCTL dk > /dev/null"
8665         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8666         do_facet mgs $LCTL dk > $TMP/$tfile
8667
8668         # LU-6388: test llog_reader
8669         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8670         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8671         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8672                         skip_env "missing llog_reader"
8673         local fstype=$(facet_fstype mgs)
8674         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8675                 skip_env "Only for ldiskfs or zfs type mgs"
8676
8677         local mntpt=$(facet_mntpt mgs)
8678         local mgsdev=$(mgsdevname 1)
8679         local fid_list
8680         local fid
8681         local rec_list
8682         local rec
8683         local rec_type
8684         local obj_file
8685         local path
8686         local seq
8687         local oid
8688         local pass=true
8689
8690         #get fid and record list
8691         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8692                 tail -n 4))
8693         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8694                 tail -n 4))
8695         #remount mgs as ldiskfs or zfs type
8696         stop mgs || error "stop mgs failed"
8697         mount_fstype mgs || error "remount mgs failed"
8698         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8699                 fid=${fid_list[i]}
8700                 rec=${rec_list[i]}
8701                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8702                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8703                 oid=$((16#$oid))
8704
8705                 case $fstype in
8706                         ldiskfs )
8707                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8708                         zfs )
8709                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8710                 esac
8711                 echo "obj_file is $obj_file"
8712                 do_facet mgs $llog_reader $obj_file
8713
8714                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8715                         awk '{ print $3 }' | sed -e "s/^type=//g")
8716                 if [ $rec_type != $rec ]; then
8717                         echo "FAILED test_60a wrong record type $rec_type," \
8718                               "should be $rec"
8719                         pass=false
8720                         break
8721                 fi
8722
8723                 #check obj path if record type is LLOG_LOGID_MAGIC
8724                 if [ "$rec" == "1064553b" ]; then
8725                         path=$(do_facet mgs $llog_reader $obj_file |
8726                                 grep "path=" | awk '{ print $NF }' |
8727                                 sed -e "s/^path=//g")
8728                         if [ $obj_file != $mntpt/$path ]; then
8729                                 echo "FAILED test_60a wrong obj path" \
8730                                       "$montpt/$path, should be $obj_file"
8731                                 pass=false
8732                                 break
8733                         fi
8734                 fi
8735         done
8736         rm -f $TMP/$tfile
8737         #restart mgs before "error", otherwise it will block the next test
8738         stop mgs || error "stop mgs failed"
8739         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8740         $pass || error "test failed, see FAILED test_60a messages for specifics"
8741 }
8742 run_test 60a "llog_test run from kernel module and test llog_reader"
8743
8744 test_60b() { # bug 6411
8745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8746
8747         dmesg > $DIR/$tfile
8748         LLOG_COUNT=$(do_facet mgs dmesg |
8749                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8750                           /llog_[a-z]*.c:[0-9]/ {
8751                                 if (marker)
8752                                         from_marker++
8753                                 from_begin++
8754                           }
8755                           END {
8756                                 if (marker)
8757                                         print from_marker
8758                                 else
8759                                         print from_begin
8760                           }")
8761
8762         [[ $LLOG_COUNT -gt 120 ]] &&
8763                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8764 }
8765 run_test 60b "limit repeated messages from CERROR/CWARN"
8766
8767 test_60c() {
8768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8769
8770         echo "create 5000 files"
8771         createmany -o $DIR/f60c- 5000
8772 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8773         lctl set_param fail_loc=0x80000137
8774         unlinkmany $DIR/f60c- 5000
8775         lctl set_param fail_loc=0
8776 }
8777 run_test 60c "unlink file when mds full"
8778
8779 test_60d() {
8780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8781
8782         SAVEPRINTK=$(lctl get_param -n printk)
8783         # verify "lctl mark" is even working"
8784         MESSAGE="test message ID $RANDOM $$"
8785         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8786         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8787
8788         lctl set_param printk=0 || error "set lnet.printk failed"
8789         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8790         MESSAGE="new test message ID $RANDOM $$"
8791         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8792         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8793         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8794
8795         lctl set_param -n printk="$SAVEPRINTK"
8796 }
8797 run_test 60d "test printk console message masking"
8798
8799 test_60e() {
8800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8801         remote_mds_nodsh && skip "remote MDS with nodsh"
8802
8803         touch $DIR/$tfile
8804 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8805         do_facet mds1 lctl set_param fail_loc=0x15b
8806         rm $DIR/$tfile
8807 }
8808 run_test 60e "no space while new llog is being created"
8809
8810 test_60f() {
8811         local old_path=$($LCTL get_param -n debug_path)
8812
8813         stack_trap "$LCTL set_param debug_path=$old_path"
8814         stack_trap "rm -f $TMP/$tfile*"
8815         rm -f $TMP/$tfile* 2> /dev/null
8816         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8817         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8818         test_mkdir $DIR/$tdir
8819         # retry in case the open is cached and not released
8820         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8821                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8822                 sleep 0.1
8823         done
8824         ls $TMP/$tfile*
8825         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8826 }
8827 run_test 60f "change debug_path works"
8828
8829 test_60g() {
8830         local pid
8831         local i
8832
8833         test_mkdir -c $MDSCOUNT $DIR/$tdir
8834
8835         (
8836                 local index=0
8837                 while true; do
8838                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8839                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8840                                 2>/dev/null
8841                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8842                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8843                         index=$((index + 1))
8844                 done
8845         ) &
8846
8847         pid=$!
8848
8849         for i in {0..100}; do
8850                 # define OBD_FAIL_OSD_TXN_START    0x19a
8851                 local index=$((i % MDSCOUNT + 1))
8852
8853                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8854                         > /dev/null
8855                 sleep 0.01
8856         done
8857
8858         kill -9 $pid
8859
8860         for i in $(seq $MDSCOUNT); do
8861                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8862         done
8863
8864         mkdir $DIR/$tdir/new || error "mkdir failed"
8865         rmdir $DIR/$tdir/new || error "rmdir failed"
8866
8867         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8868                 -t namespace
8869         for i in $(seq $MDSCOUNT); do
8870                 wait_update_facet mds$i "$LCTL get_param -n \
8871                         mdd.$(facet_svc mds$i).lfsck_namespace |
8872                         awk '/^status/ { print \\\$2 }'" "completed"
8873         done
8874
8875         ls -R $DIR/$tdir
8876         rm -rf $DIR/$tdir || error "rmdir failed"
8877 }
8878 run_test 60g "transaction abort won't cause MDT hung"
8879
8880 test_60h() {
8881         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8882                 skip "Need MDS version at least 2.12.52"
8883         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8884
8885         local f
8886
8887         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8888         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8889         for fail_loc in 0x80000188 0x80000189; do
8890                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8891                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8892                         error "mkdir $dir-$fail_loc failed"
8893                 for i in {0..10}; do
8894                         # create may fail on missing stripe
8895                         echo $i > $DIR/$tdir-$fail_loc/$i
8896                 done
8897                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8898                         error "getdirstripe $tdir-$fail_loc failed"
8899                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8900                         error "migrate $tdir-$fail_loc failed"
8901                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8902                         error "getdirstripe $tdir-$fail_loc failed"
8903                 pushd $DIR/$tdir-$fail_loc
8904                 for f in *; do
8905                         echo $f | cmp $f - || error "$f data mismatch"
8906                 done
8907                 popd
8908                 rm -rf $DIR/$tdir-$fail_loc
8909         done
8910 }
8911 run_test 60h "striped directory with missing stripes can be accessed"
8912
8913 function t60i_load() {
8914         mkdir $DIR/$tdir
8915         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8916         $LCTL set_param fail_loc=0x131c fail_val=1
8917         for ((i=0; i<5000; i++)); do
8918                 touch $DIR/$tdir/f$i
8919         done
8920 }
8921
8922 test_60i() {
8923         changelog_register || error "changelog_register failed"
8924         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8925         changelog_users $SINGLEMDS | grep -q $cl_user ||
8926                 error "User $cl_user not found in changelog_users"
8927         changelog_chmask "ALL"
8928         t60i_load &
8929         local PID=$!
8930         for((i=0; i<100; i++)); do
8931                 changelog_dump >/dev/null ||
8932                         error "can't read changelog"
8933         done
8934         kill $PID
8935         wait $PID
8936         changelog_deregister || error "changelog_deregister failed"
8937         $LCTL set_param fail_loc=0
8938 }
8939 run_test 60i "llog: new record vs reader race"
8940
8941 test_60j() {
8942         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
8943                 skip "need MDS version at least 2.15.50"
8944         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8945         remote_mds_nodsh && skip "remote MDS with nodsh"
8946         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
8947
8948         changelog_users $SINGLEMDS | grep "^cl" &&
8949                 skip "active changelog user"
8950
8951         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
8952
8953         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
8954                 skip_env "missing llog_reader"
8955
8956         mkdir_on_mdt0 $DIR/$tdir
8957
8958         local f=$DIR/$tdir/$tfile
8959         local mdt_dev
8960         local tmpfile
8961         local plain
8962
8963         changelog_register || error "cannot register changelog user"
8964
8965         # set changelog_mask to ALL
8966         changelog_chmask "ALL"
8967         changelog_clear
8968
8969         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
8970         unlinkmany ${f}- 100 || error "unlinkmany failed"
8971
8972         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
8973         mdt_dev=$(facet_device $SINGLEMDS)
8974
8975         do_facet $SINGLEMDS sync
8976         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
8977                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
8978                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
8979
8980         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
8981
8982         # if $tmpfile is not on EXT3 filesystem for some reason
8983         [[ ${plain:0:1} == 'O' ]] ||
8984                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
8985
8986         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
8987                 $mdt_dev; stat -c %s $tmpfile")
8988         echo "Truncate llog from $size to $((size - size % 8192))"
8989         size=$((size - size % 8192))
8990         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
8991         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
8992                 grep -c 'in bitmap only')
8993         (( $errs > 0 )) || error "llog_reader didn't find lost records"
8994
8995         size=$((size - 9000))
8996         echo "Corrupt llog in the middle at $size"
8997         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
8998                 count=333 conv=notrunc
8999         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9000                 grep -c 'next chunk')
9001         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9002 }
9003 run_test 60j "llog_reader reports corruptions"
9004
9005 test_61a() {
9006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9007
9008         f="$DIR/f61"
9009         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9010         cancel_lru_locks osc
9011         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9012         sync
9013 }
9014 run_test 61a "mmap() writes don't make sync hang ================"
9015
9016 test_61b() {
9017         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9018 }
9019 run_test 61b "mmap() of unstriped file is successful"
9020
9021 # bug 2330 - insufficient obd_match error checking causes LBUG
9022 test_62() {
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024
9025         f="$DIR/f62"
9026         echo foo > $f
9027         cancel_lru_locks osc
9028         lctl set_param fail_loc=0x405
9029         cat $f && error "cat succeeded, expect -EIO"
9030         lctl set_param fail_loc=0
9031 }
9032 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9033 # match every page all of the time.
9034 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9035
9036 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9037 # Though this test is irrelevant anymore, it helped to reveal some
9038 # other grant bugs (LU-4482), let's keep it.
9039 test_63a() {   # was test_63
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041
9042         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9043
9044         for i in `seq 10` ; do
9045                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9046                 sleep 5
9047                 kill $!
9048                 sleep 1
9049         done
9050
9051         rm -f $DIR/f63 || true
9052 }
9053 run_test 63a "Verify oig_wait interruption does not crash ======="
9054
9055 # bug 2248 - async write errors didn't return to application on sync
9056 # bug 3677 - async write errors left page locked
9057 test_63b() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         debugsave
9061         lctl set_param debug=-1
9062
9063         # ensure we have a grant to do async writes
9064         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9065         rm $DIR/$tfile
9066
9067         sync    # sync lest earlier test intercept the fail_loc
9068
9069         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9070         lctl set_param fail_loc=0x80000406
9071         $MULTIOP $DIR/$tfile Owy && \
9072                 error "sync didn't return ENOMEM"
9073         sync; sleep 2; sync     # do a real sync this time to flush page
9074         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9075                 error "locked page left in cache after async error" || true
9076         debugrestore
9077 }
9078 run_test 63b "async write errors should be returned to fsync ==="
9079
9080 test_64a () {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082
9083         lfs df $DIR
9084         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9085 }
9086 run_test 64a "verify filter grant calculations (in kernel) ====="
9087
9088 test_64b () {
9089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9090
9091         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9092 }
9093 run_test 64b "check out-of-space detection on client"
9094
9095 test_64c() {
9096         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9097 }
9098 run_test 64c "verify grant shrink"
9099
9100 import_param() {
9101         local tgt=$1
9102         local param=$2
9103
9104         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9105 }
9106
9107 # this does exactly what osc_request.c:osc_announce_cached() does in
9108 # order to calculate max amount of grants to ask from server
9109 want_grant() {
9110         local tgt=$1
9111
9112         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9113         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9114
9115         ((rpc_in_flight++));
9116         nrpages=$((nrpages * rpc_in_flight))
9117
9118         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9119
9120         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9121
9122         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9123         local undirty=$((nrpages * PAGE_SIZE))
9124
9125         local max_extent_pages
9126         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9127         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9128         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9129         local grant_extent_tax
9130         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9131
9132         undirty=$((undirty + nrextents * grant_extent_tax))
9133
9134         echo $undirty
9135 }
9136
9137 # this is size of unit for grant allocation. It should be equal to
9138 # what tgt_grant.c:tgt_grant_chunk() calculates
9139 grant_chunk() {
9140         local tgt=$1
9141         local max_brw_size
9142         local grant_extent_tax
9143
9144         max_brw_size=$(import_param $tgt max_brw_size)
9145
9146         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9147
9148         echo $(((max_brw_size + grant_extent_tax) * 2))
9149 }
9150
9151 test_64d() {
9152         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9153                 skip "OST < 2.10.55 doesn't limit grants enough"
9154
9155         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9156
9157         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9158                 skip "no grant_param connect flag"
9159
9160         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9161
9162         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9163         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9164
9165
9166         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9167         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9168
9169         $LFS setstripe $DIR/$tfile -i 0 -c 1
9170         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9171         ddpid=$!
9172
9173         while kill -0 $ddpid; do
9174                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9175
9176                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9177                         kill $ddpid
9178                         error "cur_grant $cur_grant > $max_cur_granted"
9179                 fi
9180
9181                 sleep 1
9182         done
9183 }
9184 run_test 64d "check grant limit exceed"
9185
9186 check_grants() {
9187         local tgt=$1
9188         local expected=$2
9189         local msg=$3
9190         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9191
9192         ((cur_grants == expected)) ||
9193                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9194 }
9195
9196 round_up_p2() {
9197         echo $((($1 + $2 - 1) & ~($2 - 1)))
9198 }
9199
9200 test_64e() {
9201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9202         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9203                 skip "Need OSS version at least 2.11.56"
9204
9205         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9206         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9207         $LCTL set_param debug=+cache
9208
9209         # Remount client to reset grant
9210         remount_client $MOUNT || error "failed to remount client"
9211         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9212
9213         local init_grants=$(import_param $osc_tgt initial_grant)
9214
9215         check_grants $osc_tgt $init_grants "init grants"
9216
9217         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9218         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9219         local gbs=$(import_param $osc_tgt grant_block_size)
9220
9221         # write random number of bytes from max_brw_size / 4 to max_brw_size
9222         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9223         # align for direct io
9224         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9225         # round to grant consumption unit
9226         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9227
9228         local grants=$((wb_round_up + extent_tax))
9229
9230         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9231
9232         # define OBD_FAIL_TGT_NO_GRANT 0x725
9233         # make the server not grant more back
9234         do_facet ost1 $LCTL set_param fail_loc=0x725
9235         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9236
9237         do_facet ost1 $LCTL set_param fail_loc=0
9238
9239         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9240
9241         rm -f $DIR/$tfile || error "rm failed"
9242
9243         # Remount client to reset grant
9244         remount_client $MOUNT || error "failed to remount client"
9245         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9246
9247         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9248
9249         # define OBD_FAIL_TGT_NO_GRANT 0x725
9250         # make the server not grant more back
9251         do_facet ost1 $LCTL set_param fail_loc=0x725
9252         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9253         do_facet ost1 $LCTL set_param fail_loc=0
9254
9255         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9256 }
9257 run_test 64e "check grant consumption (no grant allocation)"
9258
9259 test_64f() {
9260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9261
9262         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9263         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9264         $LCTL set_param debug=+cache
9265
9266         # Remount client to reset grant
9267         remount_client $MOUNT || error "failed to remount client"
9268         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9269
9270         local init_grants=$(import_param $osc_tgt initial_grant)
9271         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9272         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9273         local gbs=$(import_param $osc_tgt grant_block_size)
9274         local chunk=$(grant_chunk $osc_tgt)
9275
9276         # write random number of bytes from max_brw_size / 4 to max_brw_size
9277         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9278         # align for direct io
9279         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9280         # round to grant consumption unit
9281         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9282
9283         local grants=$((wb_round_up + extent_tax))
9284
9285         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9286         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9287                 error "error writing to $DIR/$tfile"
9288
9289         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9290                 "direct io with grant allocation"
9291
9292         rm -f $DIR/$tfile || error "rm failed"
9293
9294         # Remount client to reset grant
9295         remount_client $MOUNT || error "failed to remount client"
9296         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9297
9298         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9299
9300         local cmd="oO_WRONLY:w${write_bytes}_yc"
9301
9302         $MULTIOP $DIR/$tfile $cmd &
9303         MULTIPID=$!
9304         sleep 1
9305
9306         check_grants $osc_tgt $((init_grants - grants)) \
9307                 "buffered io, not write rpc"
9308
9309         kill -USR1 $MULTIPID
9310         wait
9311
9312         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9313                 "buffered io, one RPC"
9314 }
9315 run_test 64f "check grant consumption (with grant allocation)"
9316
9317 test_64g() {
9318         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9319                 skip "Need MDS version at least 2.14.56"
9320
9321         local mdts=$(comma_list $(mdts_nodes))
9322
9323         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9324                         tr '\n' ' ')
9325         stack_trap "$LCTL set_param $old"
9326
9327         # generate dirty pages and increase dirty granted on MDT
9328         stack_trap "rm -f $DIR/$tfile-*"
9329         for (( i = 0; i < 10; i++)); do
9330                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9331                         error "can't set stripe"
9332                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9333                         error "can't dd"
9334                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9335                         $LFS getstripe $DIR/$tfile-$i
9336                         error "not DoM file"
9337                 }
9338         done
9339
9340         # flush dirty pages
9341         sync
9342
9343         # wait until grant shrink reset grant dirty on MDTs
9344         for ((i = 0; i < 120; i++)); do
9345                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9346                         awk '{sum=sum+$1} END {print sum}')
9347                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9348                 echo "$grant_dirty grants, $vm_dirty pages"
9349                 (( grant_dirty + vm_dirty == 0 )) && break
9350                 (( i == 3 )) && sync &&
9351                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9352                 sleep 1
9353         done
9354
9355         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9356                 awk '{sum=sum+$1} END {print sum}')
9357         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9358 }
9359 run_test 64g "grant shrink on MDT"
9360
9361 test_64h() {
9362         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9363                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9364
9365         local instance=$($LFS getname -i $DIR)
9366         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9367         local num_exps=$(do_facet ost1 \
9368             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9369         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9370         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9371         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9372
9373         # 10MiB is for file to be written, max_brw_size * 16 *
9374         # num_exps is space reserve so that tgt_grant_shrink() decided
9375         # to not shrink
9376         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9377         (( avail * 1024 < expect )) &&
9378                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9379
9380         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9381         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9382         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9383         $LCTL set_param osc.*OST0000*.grant_shrink=1
9384         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9385
9386         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9387         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9388
9389         # drop cache so that coming read would do rpc
9390         cancel_lru_locks osc
9391
9392         # shrink interval is set to 10, pause for 7 seconds so that
9393         # grant thread did not wake up yet but coming read entered
9394         # shrink mode for rpc (osc_should_shrink_grant())
9395         sleep 7
9396
9397         declare -a cur_grant_bytes
9398         declare -a tot_granted
9399         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9400         tot_granted[0]=$(do_facet ost1 \
9401             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9402
9403         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9404
9405         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9406         tot_granted[1]=$(do_facet ost1 \
9407             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9408
9409         # grant change should be equal on both sides
9410         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9411                 tot_granted[0] - tot_granted[1])) ||
9412                 error "grant change mismatch, "                                \
9413                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9414                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9415 }
9416 run_test 64h "grant shrink on read"
9417
9418 test_64i() {
9419         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9420                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9421
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423         remote_ost_nodsh && skip "remote OSTs with nodsh"
9424
9425         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9426
9427         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9428
9429         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9430         local instance=$($LFS getname -i $DIR)
9431
9432         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9433         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9434
9435         # shrink grants and simulate rpc loss
9436         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9437         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9438         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9439
9440         fail ost1
9441
9442         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9443
9444         local testid=$(echo $TESTNAME | tr '_' ' ')
9445
9446         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9447                 grep "GRANT, real grant" &&
9448                 error "client has more grants then it owns" || true
9449 }
9450 run_test 64i "shrink on reconnect"
9451
9452 # bug 1414 - set/get directories' stripe info
9453 test_65a() {
9454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9455
9456         test_mkdir $DIR/$tdir
9457         touch $DIR/$tdir/f1
9458         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9459 }
9460 run_test 65a "directory with no stripe info"
9461
9462 test_65b() {
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464
9465         test_mkdir $DIR/$tdir
9466         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9467
9468         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9469                                                 error "setstripe"
9470         touch $DIR/$tdir/f2
9471         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9472 }
9473 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9474
9475 test_65c() {
9476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9477         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9478
9479         test_mkdir $DIR/$tdir
9480         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9481
9482         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9483                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9484         touch $DIR/$tdir/f3
9485         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9486 }
9487 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9488
9489 test_65d() {
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491
9492         test_mkdir $DIR/$tdir
9493         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9494         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9495
9496         if [[ $STRIPECOUNT -le 0 ]]; then
9497                 sc=1
9498         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9499                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9500                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9501         else
9502                 sc=$(($STRIPECOUNT - 1))
9503         fi
9504         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9505         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9506         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9507                 error "lverify failed"
9508 }
9509 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9510
9511 test_65e() {
9512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9513
9514         test_mkdir $DIR/$tdir
9515
9516         $LFS setstripe $DIR/$tdir || error "setstripe"
9517         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9518                                         error "no stripe info failed"
9519         touch $DIR/$tdir/f6
9520         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9521 }
9522 run_test 65e "directory setstripe defaults"
9523
9524 test_65f() {
9525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9526
9527         test_mkdir $DIR/${tdir}f
9528         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9529                 error "setstripe succeeded" || true
9530 }
9531 run_test 65f "dir setstripe permission (should return error) ==="
9532
9533 test_65g() {
9534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9535
9536         test_mkdir $DIR/$tdir
9537         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9538
9539         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9540                 error "setstripe -S failed"
9541         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9542         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9543                 error "delete default stripe failed"
9544 }
9545 run_test 65g "directory setstripe -d"
9546
9547 test_65h() {
9548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9549
9550         test_mkdir $DIR/$tdir
9551         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9552
9553         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9554                 error "setstripe -S failed"
9555         test_mkdir $DIR/$tdir/dd1
9556         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9557                 error "stripe info inherit failed"
9558 }
9559 run_test 65h "directory stripe info inherit ===================="
9560
9561 test_65i() {
9562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9563
9564         save_layout_restore_at_exit $MOUNT
9565
9566         # bug6367: set non-default striping on root directory
9567         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9568
9569         # bug12836: getstripe on -1 default directory striping
9570         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9571
9572         # bug12836: getstripe -v on -1 default directory striping
9573         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9574
9575         # bug12836: new find on -1 default directory striping
9576         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9577 }
9578 run_test 65i "various tests to set root directory striping"
9579
9580 test_65j() { # bug6367
9581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9582
9583         sync; sleep 1
9584
9585         # if we aren't already remounting for each test, do so for this test
9586         if [ "$I_MOUNTED" = "yes" ]; then
9587                 cleanup || error "failed to unmount"
9588                 setup
9589         fi
9590
9591         save_layout_restore_at_exit $MOUNT
9592
9593         $LFS setstripe -d $MOUNT || error "setstripe failed"
9594 }
9595 run_test 65j "set default striping on root directory (bug 6367)="
9596
9597 cleanup_65k() {
9598         rm -rf $DIR/$tdir
9599         wait_delete_completed
9600         do_facet $SINGLEMDS "lctl set_param -n \
9601                 osp.$ost*MDT0000.max_create_count=$max_count"
9602         do_facet $SINGLEMDS "lctl set_param -n \
9603                 osp.$ost*MDT0000.create_count=$count"
9604         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9605         echo $INACTIVE_OSC "is Activate"
9606
9607         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9608 }
9609
9610 test_65k() { # bug11679
9611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9612         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9613         remote_mds_nodsh && skip "remote MDS with nodsh"
9614
9615         local disable_precreate=true
9616         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9617                 disable_precreate=false
9618
9619         echo "Check OST status: "
9620         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9621                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9622
9623         for OSC in $MDS_OSCS; do
9624                 echo $OSC "is active"
9625                 do_facet $SINGLEMDS lctl --device %$OSC activate
9626         done
9627
9628         for INACTIVE_OSC in $MDS_OSCS; do
9629                 local ost=$(osc_to_ost $INACTIVE_OSC)
9630                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9631                                lov.*md*.target_obd |
9632                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9633
9634                 mkdir -p $DIR/$tdir
9635                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9636                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9637
9638                 echo "Deactivate: " $INACTIVE_OSC
9639                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9640
9641                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9642                               osp.$ost*MDT0000.create_count")
9643                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9644                                   osp.$ost*MDT0000.max_create_count")
9645                 $disable_precreate &&
9646                         do_facet $SINGLEMDS "lctl set_param -n \
9647                                 osp.$ost*MDT0000.max_create_count=0"
9648
9649                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9650                         [ -f $DIR/$tdir/$idx ] && continue
9651                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9652                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9653                                 { cleanup_65k;
9654                                   error "setstripe $idx should succeed"; }
9655                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9656                 done
9657                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9658                 rmdir $DIR/$tdir
9659
9660                 do_facet $SINGLEMDS "lctl set_param -n \
9661                         osp.$ost*MDT0000.max_create_count=$max_count"
9662                 do_facet $SINGLEMDS "lctl set_param -n \
9663                         osp.$ost*MDT0000.create_count=$count"
9664                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9665                 echo $INACTIVE_OSC "is Activate"
9666
9667                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9668         done
9669 }
9670 run_test 65k "validate manual striping works properly with deactivated OSCs"
9671
9672 test_65l() { # bug 12836
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674
9675         test_mkdir -p $DIR/$tdir/test_dir
9676         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9677         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9678 }
9679 run_test 65l "lfs find on -1 stripe dir ========================"
9680
9681 test_65m() {
9682         local layout=$(save_layout $MOUNT)
9683         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9684                 restore_layout $MOUNT $layout
9685                 error "setstripe should fail by non-root users"
9686         }
9687         true
9688 }
9689 run_test 65m "normal user can't set filesystem default stripe"
9690
9691 test_65n() {
9692         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9693         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9694                 skip "Need MDS version at least 2.12.50"
9695         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9696
9697         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9698         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9699         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9700
9701         save_layout_restore_at_exit $MOUNT
9702
9703         # new subdirectory under root directory should not inherit
9704         # the default layout from root
9705         local dir1=$MOUNT/$tdir-1
9706         mkdir $dir1 || error "mkdir $dir1 failed"
9707         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9708                 error "$dir1 shouldn't have LOV EA"
9709
9710         # delete the default layout on root directory
9711         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9712
9713         local dir2=$MOUNT/$tdir-2
9714         mkdir $dir2 || error "mkdir $dir2 failed"
9715         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9716                 error "$dir2 shouldn't have LOV EA"
9717
9718         # set a new striping pattern on root directory
9719         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9720         local new_def_stripe_size=$((def_stripe_size * 2))
9721         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9722                 error "set stripe size on $MOUNT failed"
9723
9724         # new file created in $dir2 should inherit the new stripe size from
9725         # the filesystem default
9726         local file2=$dir2/$tfile-2
9727         touch $file2 || error "touch $file2 failed"
9728
9729         local file2_stripe_size=$($LFS getstripe -S $file2)
9730         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9731         {
9732                 echo "file2_stripe_size: '$file2_stripe_size'"
9733                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9734                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9735         }
9736
9737         local dir3=$MOUNT/$tdir-3
9738         mkdir $dir3 || error "mkdir $dir3 failed"
9739         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9740         # the root layout, which is the actual default layout that will be used
9741         # when new files are created in $dir3.
9742         local dir3_layout=$(get_layout_param $dir3)
9743         local root_dir_layout=$(get_layout_param $MOUNT)
9744         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9745         {
9746                 echo "dir3_layout: '$dir3_layout'"
9747                 echo "root_dir_layout: '$root_dir_layout'"
9748                 error "$dir3 should show the default layout from $MOUNT"
9749         }
9750
9751         # set OST pool on root directory
9752         local pool=$TESTNAME
9753         pool_add $pool || error "add $pool failed"
9754         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9755                 error "add targets to $pool failed"
9756
9757         $LFS setstripe -p $pool $MOUNT ||
9758                 error "set OST pool on $MOUNT failed"
9759
9760         # new file created in $dir3 should inherit the pool from
9761         # the filesystem default
9762         local file3=$dir3/$tfile-3
9763         touch $file3 || error "touch $file3 failed"
9764
9765         local file3_pool=$($LFS getstripe -p $file3)
9766         [[ "$file3_pool" = "$pool" ]] ||
9767                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9768
9769         local dir4=$MOUNT/$tdir-4
9770         mkdir $dir4 || error "mkdir $dir4 failed"
9771         local dir4_layout=$(get_layout_param $dir4)
9772         root_dir_layout=$(get_layout_param $MOUNT)
9773         echo "$LFS getstripe -d $dir4"
9774         $LFS getstripe -d $dir4
9775         echo "$LFS getstripe -d $MOUNT"
9776         $LFS getstripe -d $MOUNT
9777         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9778         {
9779                 echo "dir4_layout: '$dir4_layout'"
9780                 echo "root_dir_layout: '$root_dir_layout'"
9781                 error "$dir4 should show the default layout from $MOUNT"
9782         }
9783
9784         # new file created in $dir4 should inherit the pool from
9785         # the filesystem default
9786         local file4=$dir4/$tfile-4
9787         touch $file4 || error "touch $file4 failed"
9788
9789         local file4_pool=$($LFS getstripe -p $file4)
9790         [[ "$file4_pool" = "$pool" ]] ||
9791                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9792
9793         # new subdirectory under non-root directory should inherit
9794         # the default layout from its parent directory
9795         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9796                 error "set directory layout on $dir4 failed"
9797
9798         local dir5=$dir4/$tdir-5
9799         mkdir $dir5 || error "mkdir $dir5 failed"
9800
9801         dir4_layout=$(get_layout_param $dir4)
9802         local dir5_layout=$(get_layout_param $dir5)
9803         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9804         {
9805                 echo "dir4_layout: '$dir4_layout'"
9806                 echo "dir5_layout: '$dir5_layout'"
9807                 error "$dir5 should inherit the default layout from $dir4"
9808         }
9809
9810         # though subdir under ROOT doesn't inherit default layout, but
9811         # its sub dir/file should be created with default layout.
9812         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9813         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9814                 skip "Need MDS version at least 2.12.59"
9815
9816         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9817         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9818         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9819
9820         if [ $default_lmv_hash == "none" ]; then
9821                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9822         else
9823                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9824                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9825         fi
9826
9827         $LFS setdirstripe -D -c 2 $MOUNT ||
9828                 error "setdirstripe -D -c 2 failed"
9829         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9830         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9831         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9832
9833         # $dir4 layout includes pool
9834         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
9835         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9836                 error "pool lost on setstripe"
9837         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
9838         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
9839                 error "pool lost on compound layout setstripe"
9840 }
9841 run_test 65n "don't inherit default layout from root for new subdirectories"
9842
9843 test_65o() {
9844         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
9845                 skip "need MDS version at least 2.14.57"
9846
9847         # set OST pool on root directory
9848         local pool=$TESTNAME
9849
9850         pool_add $pool || error "add $pool failed"
9851         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9852                 error "add targets to $pool failed"
9853
9854         local dir1=$MOUNT/$tdir
9855
9856         mkdir $dir1 || error "mkdir $dir1 failed"
9857
9858         # set a new striping pattern on root directory
9859         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9860
9861         $LFS setstripe -p $pool $dir1 ||
9862                 error "set directory layout on $dir1 failed"
9863
9864         # $dir1 layout includes pool
9865         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
9866         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9867                 error "pool lost on setstripe"
9868         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
9869         $LFS getstripe $dir1
9870         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9871                 error "pool lost on compound layout setstripe"
9872
9873         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
9874                 error "setdirstripe failed on sub-dir with inherited pool"
9875         $LFS getstripe $dir1/dir2
9876         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
9877                 error "pool lost on compound layout setdirstripe"
9878
9879         $LFS setstripe -E -1 -c 1 $dir1
9880         $LFS getstripe -d $dir1
9881         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
9882                 error "pool lost on setstripe"
9883 }
9884 run_test 65o "pool inheritance for mdt component"
9885
9886 test_65p () { # LU-16152
9887         local src_dir=$DIR/$tdir/src_dir
9888         local dst_dir=$DIR/$tdir/dst_dir
9889         local yaml_file=$DIR/$tdir/layout.yaml
9890         local border
9891
9892         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
9893                 skip "Need at least version 2.15.51"
9894
9895         test_mkdir -p $src_dir
9896         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
9897                 error "failed to setstripe"
9898         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
9899                 error "failed to getstripe"
9900
9901         test_mkdir -p $dst_dir
9902         $LFS setstripe --yaml $yaml_file $dst_dir ||
9903                 error "failed to setstripe with yaml file"
9904         border=$($LFS getstripe -d $dst_dir |
9905                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
9906                 error "failed to getstripe"
9907
9908         # 2048M is 0x80000000, or 2147483648
9909         (( $border == 2147483648 )) ||
9910                 error "failed to handle huge number in yaml layout"
9911 }
9912 run_test 65p "setstripe with yaml file and huge number"
9913
9914 # bug 2543 - update blocks count on client
9915 test_66() {
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917
9918         local COUNT=${COUNT:-8}
9919         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9920         sync; sync_all_data; sync; sync_all_data
9921         cancel_lru_locks osc
9922         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
9923         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9924 }
9925 run_test 66 "update inode blocks count on client ==============="
9926
9927 meminfo() {
9928         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9929 }
9930
9931 swap_used() {
9932         swapon -s | awk '($1 == "'$1'") { print $4 }'
9933 }
9934
9935 # bug5265, obdfilter oa2dentry return -ENOENT
9936 # #define OBD_FAIL_SRV_ENOENT 0x217
9937 test_69() {
9938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9939         remote_ost_nodsh && skip "remote OST with nodsh"
9940
9941         f="$DIR/$tfile"
9942         $LFS setstripe -c 1 -i 0 $f
9943
9944         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9945
9946         do_facet ost1 lctl set_param fail_loc=0x217
9947         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9948         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9949
9950         do_facet ost1 lctl set_param fail_loc=0
9951         $DIRECTIO write $f 0 2 || error "write error"
9952
9953         cancel_lru_locks osc
9954         $DIRECTIO read $f 0 1 || error "read error"
9955
9956         do_facet ost1 lctl set_param fail_loc=0x217
9957         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9958
9959         do_facet ost1 lctl set_param fail_loc=0
9960         rm -f $f
9961 }
9962 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9963
9964 test_71() {
9965         test_mkdir $DIR/$tdir
9966         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9967         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9968 }
9969 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9970
9971 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9973         [ "$RUNAS_ID" = "$UID" ] &&
9974                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9975         # Check that testing environment is properly set up. Skip if not
9976         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9977                 skip_env "User $RUNAS_ID does not exist - skipping"
9978
9979         touch $DIR/$tfile
9980         chmod 777 $DIR/$tfile
9981         chmod ug+s $DIR/$tfile
9982         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9983                 error "$RUNAS dd $DIR/$tfile failed"
9984         # See if we are still setuid/sgid
9985         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9986                 error "S/gid is not dropped on write"
9987         # Now test that MDS is updated too
9988         cancel_lru_locks mdc
9989         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9990                 error "S/gid is not dropped on MDS"
9991         rm -f $DIR/$tfile
9992 }
9993 run_test 72a "Test that remove suid works properly (bug5695) ===="
9994
9995 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9996         local perm
9997
9998         [ "$RUNAS_ID" = "$UID" ] &&
9999                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10000         [ "$RUNAS_ID" -eq 0 ] &&
10001                 skip_env "RUNAS_ID = 0 -- skipping"
10002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10003         # Check that testing environment is properly set up. Skip if not
10004         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10005                 skip_env "User $RUNAS_ID does not exist - skipping"
10006
10007         touch $DIR/${tfile}-f{g,u}
10008         test_mkdir $DIR/${tfile}-dg
10009         test_mkdir $DIR/${tfile}-du
10010         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10011         chmod g+s $DIR/${tfile}-{f,d}g
10012         chmod u+s $DIR/${tfile}-{f,d}u
10013         for perm in 777 2777 4777; do
10014                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10015                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10016                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10017                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10018         done
10019         true
10020 }
10021 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10022
10023 # bug 3462 - multiple simultaneous MDC requests
10024 test_73() {
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026
10027         test_mkdir $DIR/d73-1
10028         test_mkdir $DIR/d73-2
10029         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10030         pid1=$!
10031
10032         lctl set_param fail_loc=0x80000129
10033         $MULTIOP $DIR/d73-1/f73-2 Oc &
10034         sleep 1
10035         lctl set_param fail_loc=0
10036
10037         $MULTIOP $DIR/d73-2/f73-3 Oc &
10038         pid3=$!
10039
10040         kill -USR1 $pid1
10041         wait $pid1 || return 1
10042
10043         sleep 25
10044
10045         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10046         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10047         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10048
10049         rm -rf $DIR/d73-*
10050 }
10051 run_test 73 "multiple MDC requests (should not deadlock)"
10052
10053 test_74a() { # bug 6149, 6184
10054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10055
10056         touch $DIR/f74a
10057         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10058         #
10059         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10060         # will spin in a tight reconnection loop
10061         $LCTL set_param fail_loc=0x8000030e
10062         # get any lock that won't be difficult - lookup works.
10063         ls $DIR/f74a
10064         $LCTL set_param fail_loc=0
10065         rm -f $DIR/f74a
10066         true
10067 }
10068 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10069
10070 test_74b() { # bug 13310
10071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10072
10073         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10074         #
10075         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10076         # will spin in a tight reconnection loop
10077         $LCTL set_param fail_loc=0x8000030e
10078         # get a "difficult" lock
10079         touch $DIR/f74b
10080         $LCTL set_param fail_loc=0
10081         rm -f $DIR/f74b
10082         true
10083 }
10084 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10085
10086 test_74c() {
10087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10088
10089         #define OBD_FAIL_LDLM_NEW_LOCK
10090         $LCTL set_param fail_loc=0x319
10091         touch $DIR/$tfile && error "touch successful"
10092         $LCTL set_param fail_loc=0
10093         true
10094 }
10095 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10096
10097 slab_lic=/sys/kernel/slab/lustre_inode_cache
10098 num_objects() {
10099         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10100         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10101                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10102 }
10103
10104 test_76a() { # Now for b=20433, added originally in b=1443
10105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10106
10107         cancel_lru_locks osc
10108         # there may be some slab objects cached per core
10109         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10110         local before=$(num_objects)
10111         local count=$((512 * cpus))
10112         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10113         local margin=$((count / 10))
10114         if [[ -f $slab_lic/aliases ]]; then
10115                 local aliases=$(cat $slab_lic/aliases)
10116                 (( aliases > 0 )) && margin=$((margin * aliases))
10117         fi
10118
10119         echo "before slab objects: $before"
10120         for i in $(seq $count); do
10121                 touch $DIR/$tfile
10122                 rm -f $DIR/$tfile
10123         done
10124         cancel_lru_locks osc
10125         local after=$(num_objects)
10126         echo "created: $count, after slab objects: $after"
10127         # shared slab counts are not very accurate, allow significant margin
10128         # the main goal is that the cache growth is not permanently > $count
10129         while (( after > before + margin )); do
10130                 sleep 1
10131                 after=$(num_objects)
10132                 wait=$((wait + 1))
10133                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10134                 if (( wait > 60 )); then
10135                         error "inode slab grew from $before+$margin to $after"
10136                 fi
10137         done
10138 }
10139 run_test 76a "confirm clients recycle inodes properly ===="
10140
10141 test_76b() {
10142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10143         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10144
10145         local count=512
10146         local before=$(num_objects)
10147
10148         for i in $(seq $count); do
10149                 mkdir $DIR/$tdir
10150                 rmdir $DIR/$tdir
10151         done
10152
10153         local after=$(num_objects)
10154         local wait=0
10155
10156         while (( after > before )); do
10157                 sleep 1
10158                 after=$(num_objects)
10159                 wait=$((wait + 1))
10160                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10161                 if (( wait > 60 )); then
10162                         error "inode slab grew from $before to $after"
10163                 fi
10164         done
10165
10166         echo "slab objects before: $before, after: $after"
10167 }
10168 run_test 76b "confirm clients recycle directory inodes properly ===="
10169
10170 export ORIG_CSUM=""
10171 set_checksums()
10172 {
10173         # Note: in sptlrpc modes which enable its own bulk checksum, the
10174         # original crc32_le bulk checksum will be automatically disabled,
10175         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10176         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10177         # In this case set_checksums() will not be no-op, because sptlrpc
10178         # bulk checksum will be enabled all through the test.
10179
10180         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10181         lctl set_param -n osc.*.checksums $1
10182         return 0
10183 }
10184
10185 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10186                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10187 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10188                              tr -d [] | head -n1)}
10189 set_checksum_type()
10190 {
10191         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10192         rc=$?
10193         log "set checksum type to $1, rc = $rc"
10194         return $rc
10195 }
10196
10197 get_osc_checksum_type()
10198 {
10199         # arugment 1: OST name, like OST0000
10200         ost=$1
10201         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10202                         sed 's/.*\[\(.*\)\].*/\1/g')
10203         rc=$?
10204         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10205         echo $checksum_type
10206 }
10207
10208 F77_TMP=$TMP/f77-temp
10209 F77SZ=8
10210 setup_f77() {
10211         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10212                 error "error writing to $F77_TMP"
10213 }
10214
10215 test_77a() { # bug 10889
10216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10217         $GSS && skip_env "could not run with gss"
10218
10219         [ ! -f $F77_TMP ] && setup_f77
10220         set_checksums 1
10221         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10222         set_checksums 0
10223         rm -f $DIR/$tfile
10224 }
10225 run_test 77a "normal checksum read/write operation"
10226
10227 test_77b() { # bug 10889
10228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10229         $GSS && skip_env "could not run with gss"
10230
10231         [ ! -f $F77_TMP ] && setup_f77
10232         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10233         $LCTL set_param fail_loc=0x80000409
10234         set_checksums 1
10235
10236         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10237                 error "dd error: $?"
10238         $LCTL set_param fail_loc=0
10239
10240         for algo in $CKSUM_TYPES; do
10241                 cancel_lru_locks osc
10242                 set_checksum_type $algo
10243                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10244                 $LCTL set_param fail_loc=0x80000408
10245                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10246                 $LCTL set_param fail_loc=0
10247         done
10248         set_checksums 0
10249         set_checksum_type $ORIG_CSUM_TYPE
10250         rm -f $DIR/$tfile
10251 }
10252 run_test 77b "checksum error on client write, read"
10253
10254 cleanup_77c() {
10255         trap 0
10256         set_checksums 0
10257         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10258         $check_ost &&
10259                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10260         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10261         $check_ost && [ -n "$ost_file_prefix" ] &&
10262                 do_facet ost1 rm -f ${ost_file_prefix}\*
10263 }
10264
10265 test_77c() {
10266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10267         $GSS && skip_env "could not run with gss"
10268         remote_ost_nodsh && skip "remote OST with nodsh"
10269
10270         local bad1
10271         local osc_file_prefix
10272         local osc_file
10273         local check_ost=false
10274         local ost_file_prefix
10275         local ost_file
10276         local orig_cksum
10277         local dump_cksum
10278         local fid
10279
10280         # ensure corruption will occur on first OSS/OST
10281         $LFS setstripe -i 0 $DIR/$tfile
10282
10283         [ ! -f $F77_TMP ] && setup_f77
10284         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10285                 error "dd write error: $?"
10286         fid=$($LFS path2fid $DIR/$tfile)
10287
10288         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10289         then
10290                 check_ost=true
10291                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10292                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10293         else
10294                 echo "OSS do not support bulk pages dump upon error"
10295         fi
10296
10297         osc_file_prefix=$($LCTL get_param -n debug_path)
10298         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10299
10300         trap cleanup_77c EXIT
10301
10302         set_checksums 1
10303         # enable bulk pages dump upon error on Client
10304         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10305         # enable bulk pages dump upon error on OSS
10306         $check_ost &&
10307                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10308
10309         # flush Client cache to allow next read to reach OSS
10310         cancel_lru_locks osc
10311
10312         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10313         $LCTL set_param fail_loc=0x80000408
10314         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10315         $LCTL set_param fail_loc=0
10316
10317         rm -f $DIR/$tfile
10318
10319         # check cksum dump on Client
10320         osc_file=$(ls ${osc_file_prefix}*)
10321         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10322         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10323         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10324         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10325         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10326                      cksum)
10327         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10328         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10329                 error "dump content does not match on Client"
10330
10331         $check_ost || skip "No need to check cksum dump on OSS"
10332
10333         # check cksum dump on OSS
10334         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10335         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10336         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10337         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10338         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10339                 error "dump content does not match on OSS"
10340
10341         cleanup_77c
10342 }
10343 run_test 77c "checksum error on client read with debug"
10344
10345 test_77d() { # bug 10889
10346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10347         $GSS && skip_env "could not run with gss"
10348
10349         stack_trap "rm -f $DIR/$tfile"
10350         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10351         $LCTL set_param fail_loc=0x80000409
10352         set_checksums 1
10353         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10354                 error "direct write: rc=$?"
10355         $LCTL set_param fail_loc=0
10356         set_checksums 0
10357
10358         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10359         $LCTL set_param fail_loc=0x80000408
10360         set_checksums 1
10361         cancel_lru_locks osc
10362         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10363                 error "direct read: rc=$?"
10364         $LCTL set_param fail_loc=0
10365         set_checksums 0
10366 }
10367 run_test 77d "checksum error on OST direct write, read"
10368
10369 test_77f() { # bug 10889
10370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10371         $GSS && skip_env "could not run with gss"
10372
10373         set_checksums 1
10374         stack_trap "rm -f $DIR/$tfile"
10375         for algo in $CKSUM_TYPES; do
10376                 cancel_lru_locks osc
10377                 set_checksum_type $algo
10378                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10379                 $LCTL set_param fail_loc=0x409
10380                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10381                         error "direct write succeeded"
10382                 $LCTL set_param fail_loc=0
10383         done
10384         set_checksum_type $ORIG_CSUM_TYPE
10385         set_checksums 0
10386 }
10387 run_test 77f "repeat checksum error on write (expect error)"
10388
10389 test_77g() { # bug 10889
10390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10391         $GSS && skip_env "could not run with gss"
10392         remote_ost_nodsh && skip "remote OST with nodsh"
10393
10394         [ ! -f $F77_TMP ] && setup_f77
10395
10396         local file=$DIR/$tfile
10397         stack_trap "rm -f $file" EXIT
10398
10399         $LFS setstripe -c 1 -i 0 $file
10400         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10401         do_facet ost1 lctl set_param fail_loc=0x8000021a
10402         set_checksums 1
10403         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10404                 error "write error: rc=$?"
10405         do_facet ost1 lctl set_param fail_loc=0
10406         set_checksums 0
10407
10408         cancel_lru_locks osc
10409         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10410         do_facet ost1 lctl set_param fail_loc=0x8000021b
10411         set_checksums 1
10412         cmp $F77_TMP $file || error "file compare failed"
10413         do_facet ost1 lctl set_param fail_loc=0
10414         set_checksums 0
10415 }
10416 run_test 77g "checksum error on OST write, read"
10417
10418 test_77k() { # LU-10906
10419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10420         $GSS && skip_env "could not run with gss"
10421
10422         local cksum_param="osc.$FSNAME*.checksums"
10423         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10424         local checksum
10425         local i
10426
10427         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10428         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10429         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10430
10431         for i in 0 1; do
10432                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10433                         error "failed to set checksum=$i on MGS"
10434                 wait_update $HOSTNAME "$get_checksum" $i
10435                 #remount
10436                 echo "remount client, checksum should be $i"
10437                 remount_client $MOUNT || error "failed to remount client"
10438                 checksum=$(eval $get_checksum)
10439                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10440         done
10441         # remove persistent param to avoid races with checksum mountopt below
10442         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10443                 error "failed to delete checksum on MGS"
10444
10445         for opt in "checksum" "nochecksum"; do
10446                 #remount with mount option
10447                 echo "remount client with option $opt, checksum should be $i"
10448                 umount_client $MOUNT || error "failed to umount client"
10449                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10450                         error "failed to mount client with option '$opt'"
10451                 checksum=$(eval $get_checksum)
10452                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10453                 i=$((i - 1))
10454         done
10455
10456         remount_client $MOUNT || error "failed to remount client"
10457 }
10458 run_test 77k "enable/disable checksum correctly"
10459
10460 test_77l() {
10461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10462         $GSS && skip_env "could not run with gss"
10463
10464         set_checksums 1
10465         stack_trap "set_checksums $ORIG_CSUM" EXIT
10466         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10467
10468         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10469
10470         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10471         for algo in $CKSUM_TYPES; do
10472                 set_checksum_type $algo || error "fail to set checksum type $algo"
10473                 osc_algo=$(get_osc_checksum_type OST0000)
10474                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10475
10476                 # no locks, no reqs to let the connection idle
10477                 cancel_lru_locks osc
10478                 lru_resize_disable osc
10479                 wait_osc_import_state client ost1 IDLE
10480
10481                 # ensure ost1 is connected
10482                 stat $DIR/$tfile >/dev/null || error "can't stat"
10483                 wait_osc_import_state client ost1 FULL
10484
10485                 osc_algo=$(get_osc_checksum_type OST0000)
10486                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10487         done
10488         return 0
10489 }
10490 run_test 77l "preferred checksum type is remembered after reconnected"
10491
10492 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10493 rm -f $F77_TMP
10494 unset F77_TMP
10495
10496 test_77m() {
10497         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10498                 skip "Need at least version 2.14.52"
10499         local param=checksum_speed
10500
10501         $LCTL get_param $param || error "reading $param failed"
10502
10503         csum_speeds=$($LCTL get_param -n $param)
10504
10505         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10506                 error "known checksum types are missing"
10507 }
10508 run_test 77m "Verify checksum_speed is correctly read"
10509
10510 check_filefrag_77n() {
10511         local nr_ext=0
10512         local starts=()
10513         local ends=()
10514
10515         while read extidx a b start end rest; do
10516                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10517                         nr_ext=$(( $nr_ext + 1 ))
10518                         starts+=( ${start%..} )
10519                         ends+=( ${end%:} )
10520                 fi
10521         done < <( filefrag -sv $1 )
10522
10523         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10524         return 1
10525 }
10526
10527 test_77n() {
10528         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10529
10530         touch $DIR/$tfile
10531         $TRUNCATE $DIR/$tfile 0
10532         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10533         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10534         check_filefrag_77n $DIR/$tfile ||
10535                 skip "$tfile blocks not contiguous around hole"
10536
10537         set_checksums 1
10538         stack_trap "set_checksums $ORIG_CSUM" EXIT
10539         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10540         stack_trap "rm -f $DIR/$tfile"
10541
10542         for algo in $CKSUM_TYPES; do
10543                 if [[ "$algo" =~ ^t10 ]]; then
10544                         set_checksum_type $algo ||
10545                                 error "fail to set checksum type $algo"
10546                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10547                                 error "fail to read $tfile with $algo"
10548                 fi
10549         done
10550         rm -f $DIR/$tfile
10551         return 0
10552 }
10553 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10554
10555 test_77o() {
10556         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10557                 skip "Need MDS version at least 2.14.55"
10558         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10559                 skip "Need OST version at least 2.14.55"
10560         local ofd=obdfilter
10561         local mdt=mdt
10562
10563         # print OST checksum_type
10564         echo "$ofd.$FSNAME-*.checksum_type:"
10565         do_nodes $(comma_list $(osts_nodes)) \
10566                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10567
10568         # print MDT checksum_type
10569         echo "$mdt.$FSNAME-*.checksum_type:"
10570         do_nodes $(comma_list $(mdts_nodes)) \
10571                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10572
10573         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10574                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10575
10576         (( $o_count == $OSTCOUNT )) ||
10577                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10578
10579         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10580                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10581
10582         (( $m_count == $MDSCOUNT )) ||
10583                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10584 }
10585 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10586
10587 cleanup_test_78() {
10588         trap 0
10589         rm -f $DIR/$tfile
10590 }
10591
10592 test_78() { # bug 10901
10593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10594         remote_ost || skip_env "local OST"
10595
10596         NSEQ=5
10597         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10598         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10599         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10600         echo "MemTotal: $MEMTOTAL"
10601
10602         # reserve 256MB of memory for the kernel and other running processes,
10603         # and then take 1/2 of the remaining memory for the read/write buffers.
10604         if [ $MEMTOTAL -gt 512 ] ;then
10605                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10606         else
10607                 # for those poor memory-starved high-end clusters...
10608                 MEMTOTAL=$((MEMTOTAL / 2))
10609         fi
10610         echo "Mem to use for directio: $MEMTOTAL"
10611
10612         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10613         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10614         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10615         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10616                 head -n1)
10617         echo "Smallest OST: $SMALLESTOST"
10618         [[ $SMALLESTOST -lt 10240 ]] &&
10619                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10620
10621         trap cleanup_test_78 EXIT
10622
10623         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10624                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10625
10626         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10627         echo "File size: $F78SIZE"
10628         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10629         for i in $(seq 1 $NSEQ); do
10630                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10631                 echo directIO rdwr round $i of $NSEQ
10632                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10633         done
10634
10635         cleanup_test_78
10636 }
10637 run_test 78 "handle large O_DIRECT writes correctly ============"
10638
10639 test_79() { # bug 12743
10640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10641
10642         wait_delete_completed
10643
10644         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10645         BKFREE=$(calc_osc_kbytes kbytesfree)
10646         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10647
10648         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10649         DFTOTAL=`echo $STRING | cut -d, -f1`
10650         DFUSED=`echo $STRING  | cut -d, -f2`
10651         DFAVAIL=`echo $STRING | cut -d, -f3`
10652         DFFREE=$(($DFTOTAL - $DFUSED))
10653
10654         ALLOWANCE=$((64 * $OSTCOUNT))
10655
10656         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10657            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10658                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10659         fi
10660         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10661            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10662                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10663         fi
10664         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10665            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10666                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10667         fi
10668 }
10669 run_test 79 "df report consistency check ======================="
10670
10671 test_80() { # bug 10718
10672         remote_ost_nodsh && skip "remote OST with nodsh"
10673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10674
10675         # relax strong synchronous semantics for slow backends like ZFS
10676         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10677                 local soc="obdfilter.*.sync_lock_cancel"
10678                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10679
10680                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10681                 if [ -z "$save" ]; then
10682                         soc="obdfilter.*.sync_on_lock_cancel"
10683                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10684                 fi
10685
10686                 if [ "$save" != "never" ]; then
10687                         local hosts=$(comma_list $(osts_nodes))
10688
10689                         do_nodes $hosts $LCTL set_param $soc=never
10690                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10691                 fi
10692         fi
10693
10694         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10695         sync; sleep 1; sync
10696         local before=$(date +%s)
10697         cancel_lru_locks osc
10698         local after=$(date +%s)
10699         local diff=$((after - before))
10700         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10701
10702         rm -f $DIR/$tfile
10703 }
10704 run_test 80 "Page eviction is equally fast at high offsets too"
10705
10706 test_81a() { # LU-456
10707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10708         remote_ost_nodsh && skip "remote OST with nodsh"
10709
10710         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10711         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10712         do_facet ost1 lctl set_param fail_loc=0x80000228
10713
10714         # write should trigger a retry and success
10715         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10716         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10717         RC=$?
10718         if [ $RC -ne 0 ] ; then
10719                 error "write should success, but failed for $RC"
10720         fi
10721 }
10722 run_test 81a "OST should retry write when get -ENOSPC ==============="
10723
10724 test_81b() { # LU-456
10725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10726         remote_ost_nodsh && skip "remote OST with nodsh"
10727
10728         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10729         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10730         do_facet ost1 lctl set_param fail_loc=0x228
10731
10732         # write should retry several times and return -ENOSPC finally
10733         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10734         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10735         RC=$?
10736         ENOSPC=28
10737         if [ $RC -ne $ENOSPC ] ; then
10738                 error "dd should fail for -ENOSPC, but succeed."
10739         fi
10740 }
10741 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10742
10743 test_99() {
10744         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10745
10746         test_mkdir $DIR/$tdir.cvsroot
10747         chown $RUNAS_ID $DIR/$tdir.cvsroot
10748
10749         cd $TMP
10750         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10751
10752         cd /etc/init.d
10753         # some versions of cvs import exit(1) when asked to import links or
10754         # files they can't read.  ignore those files.
10755         local toignore=$(find . -type l -printf '-I %f\n' -o \
10756                          ! -perm /4 -printf '-I %f\n')
10757         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10758                 $tdir.reposname vtag rtag
10759
10760         cd $DIR
10761         test_mkdir $DIR/$tdir.reposname
10762         chown $RUNAS_ID $DIR/$tdir.reposname
10763         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10764
10765         cd $DIR/$tdir.reposname
10766         $RUNAS touch foo99
10767         $RUNAS cvs add -m 'addmsg' foo99
10768         $RUNAS cvs update
10769         $RUNAS cvs commit -m 'nomsg' foo99
10770         rm -fr $DIR/$tdir.cvsroot
10771 }
10772 run_test 99 "cvs strange file/directory operations"
10773
10774 test_100() {
10775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10776         [[ "$NETTYPE" =~ tcp ]] ||
10777                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10778         remote_ost_nodsh && skip "remote OST with nodsh"
10779         remote_mds_nodsh && skip "remote MDS with nodsh"
10780         remote_servers ||
10781                 skip "useless for local single node setup"
10782
10783         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10784                 [ "$PROT" != "tcp" ] && continue
10785                 RPORT=$(echo $REMOTE | cut -d: -f2)
10786                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10787
10788                 rc=0
10789                 LPORT=`echo $LOCAL | cut -d: -f2`
10790                 if [ $LPORT -ge 1024 ]; then
10791                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10792                         netstat -tna
10793                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10794                 fi
10795         done
10796         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10797 }
10798 run_test 100 "check local port using privileged port ==========="
10799
10800 function get_named_value()
10801 {
10802     local tag=$1
10803
10804     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10805 }
10806
10807 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10808                    awk '/^max_cached_mb/ { print $2 }')
10809
10810 cleanup_101a() {
10811         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10812         trap 0
10813 }
10814
10815 test_101a() {
10816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10817
10818         local s
10819         local discard
10820         local nreads=10000
10821         local cache_limit=32
10822
10823         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10824         trap cleanup_101a EXIT
10825         $LCTL set_param -n llite.*.read_ahead_stats=0
10826         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10827
10828         #
10829         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10830         #
10831         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10832         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10833
10834         discard=0
10835         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10836                    get_named_value 'read.but.discarded'); do
10837                         discard=$(($discard + $s))
10838         done
10839         cleanup_101a
10840
10841         $LCTL get_param osc.*-osc*.rpc_stats
10842         $LCTL get_param llite.*.read_ahead_stats
10843
10844         # Discard is generally zero, but sometimes a few random reads line up
10845         # and trigger larger readahead, which is wasted & leads to discards.
10846         if [[ $(($discard)) -gt $nreads ]]; then
10847                 error "too many ($discard) discarded pages"
10848         fi
10849         rm -f $DIR/$tfile || true
10850 }
10851 run_test 101a "check read-ahead for random reads"
10852
10853 setup_test101bc() {
10854         test_mkdir $DIR/$tdir
10855         local ssize=$1
10856         local FILE_LENGTH=$2
10857         STRIPE_OFFSET=0
10858
10859         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10860
10861         local list=$(comma_list $(osts_nodes))
10862         set_osd_param $list '' read_cache_enable 0
10863         set_osd_param $list '' writethrough_cache_enable 0
10864
10865         trap cleanup_test101bc EXIT
10866         # prepare the read-ahead file
10867         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10868
10869         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10870                                 count=$FILE_SIZE_MB 2> /dev/null
10871
10872 }
10873
10874 cleanup_test101bc() {
10875         trap 0
10876         rm -rf $DIR/$tdir
10877         rm -f $DIR/$tfile
10878
10879         local list=$(comma_list $(osts_nodes))
10880         set_osd_param $list '' read_cache_enable 1
10881         set_osd_param $list '' writethrough_cache_enable 1
10882 }
10883
10884 calc_total() {
10885         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10886 }
10887
10888 ra_check_101() {
10889         local read_size=$1
10890         local stripe_size=$2
10891         local stride_length=$((stripe_size / read_size))
10892         local stride_width=$((stride_length * OSTCOUNT))
10893         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
10894                                 (stride_width - stride_length) ))
10895         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
10896                   get_named_value 'read.but.discarded' | calc_total)
10897
10898         if [[ $discard -gt $discard_limit ]]; then
10899                 $LCTL get_param llite.*.read_ahead_stats
10900                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
10901         else
10902                 echo "Read-ahead success for size ${read_size}"
10903         fi
10904 }
10905
10906 test_101b() {
10907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10908         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10909
10910         local STRIPE_SIZE=1048576
10911         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10912
10913         if [ $SLOW == "yes" ]; then
10914                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10915         else
10916                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10917         fi
10918
10919         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10920
10921         # prepare the read-ahead file
10922         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10923         cancel_lru_locks osc
10924         for BIDX in 2 4 8 16 32 64 128 256
10925         do
10926                 local BSIZE=$((BIDX*4096))
10927                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10928                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10929                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10930                 $LCTL set_param -n llite.*.read_ahead_stats=0
10931                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10932                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10933                 cancel_lru_locks osc
10934                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10935         done
10936         cleanup_test101bc
10937         true
10938 }
10939 run_test 101b "check stride-io mode read-ahead ================="
10940
10941 test_101c() {
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943
10944         local STRIPE_SIZE=1048576
10945         local FILE_LENGTH=$((STRIPE_SIZE*100))
10946         local nreads=10000
10947         local rsize=65536
10948         local osc_rpc_stats
10949
10950         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10951
10952         cancel_lru_locks osc
10953         $LCTL set_param osc.*.rpc_stats=0
10954         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10955         $LCTL get_param osc.*.rpc_stats
10956         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10957                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10958                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10959                 local size
10960
10961                 if [ $lines -le 20 ]; then
10962                         echo "continue debug"
10963                         continue
10964                 fi
10965                 for size in 1 2 4 8; do
10966                         local rpc=$(echo "$stats" |
10967                                     awk '($1 == "'$size':") {print $2; exit; }')
10968                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10969                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10970                 done
10971                 echo "$osc_rpc_stats check passed!"
10972         done
10973         cleanup_test101bc
10974         true
10975 }
10976 run_test 101c "check stripe_size aligned read-ahead"
10977
10978 test_101d() {
10979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10980
10981         local file=$DIR/$tfile
10982         local sz_MB=${FILESIZE_101d:-80}
10983         local ra_MB=${READAHEAD_MB:-40}
10984
10985         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10986         [ $free_MB -lt $sz_MB ] &&
10987                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10988
10989         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10990         $LFS setstripe -c -1 $file || error "setstripe failed"
10991
10992         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10993         echo Cancel LRU locks on lustre client to flush the client cache
10994         cancel_lru_locks osc
10995
10996         echo Disable read-ahead
10997         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10998         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10999         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11000         $LCTL get_param -n llite.*.max_read_ahead_mb
11001
11002         echo "Reading the test file $file with read-ahead disabled"
11003         local sz_KB=$((sz_MB * 1024 / 4))
11004         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11005         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11006         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11007                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11008
11009         echo "Cancel LRU locks on lustre client to flush the client cache"
11010         cancel_lru_locks osc
11011         echo Enable read-ahead with ${ra_MB}MB
11012         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11013
11014         echo "Reading the test file $file with read-ahead enabled"
11015         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11016                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11017
11018         echo "read-ahead disabled time read $raOFF"
11019         echo "read-ahead enabled time read $raON"
11020
11021         rm -f $file
11022         wait_delete_completed
11023
11024         # use awk for this check instead of bash because it handles decimals
11025         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11026                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11027 }
11028 run_test 101d "file read with and without read-ahead enabled"
11029
11030 test_101e() {
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032
11033         local file=$DIR/$tfile
11034         local size_KB=500  #KB
11035         local count=100
11036         local bsize=1024
11037
11038         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11039         local need_KB=$((count * size_KB))
11040         [[ $free_KB -le $need_KB ]] &&
11041                 skip_env "Need free space $need_KB, have $free_KB"
11042
11043         echo "Creating $count ${size_KB}K test files"
11044         for ((i = 0; i < $count; i++)); do
11045                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11046         done
11047
11048         echo "Cancel LRU locks on lustre client to flush the client cache"
11049         cancel_lru_locks $OSC
11050
11051         echo "Reset readahead stats"
11052         $LCTL set_param -n llite.*.read_ahead_stats=0
11053
11054         for ((i = 0; i < $count; i++)); do
11055                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11056         done
11057
11058         $LCTL get_param llite.*.max_cached_mb
11059         $LCTL get_param llite.*.read_ahead_stats
11060         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11061                      get_named_value 'misses' | calc_total)
11062
11063         for ((i = 0; i < $count; i++)); do
11064                 rm -rf $file.$i 2>/dev/null
11065         done
11066
11067         #10000 means 20% reads are missing in readahead
11068         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11069 }
11070 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11071
11072 test_101f() {
11073         which iozone || skip_env "no iozone installed"
11074
11075         local old_debug=$($LCTL get_param debug)
11076         old_debug=${old_debug#*=}
11077         $LCTL set_param debug="reada mmap"
11078
11079         # create a test file
11080         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11081
11082         echo Cancel LRU locks on lustre client to flush the client cache
11083         cancel_lru_locks osc
11084
11085         echo Reset readahead stats
11086         $LCTL set_param -n llite.*.read_ahead_stats=0
11087
11088         echo mmap read the file with small block size
11089         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11090                 > /dev/null 2>&1
11091
11092         echo checking missing pages
11093         $LCTL get_param llite.*.read_ahead_stats
11094         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11095                         get_named_value 'misses' | calc_total)
11096
11097         $LCTL set_param debug="$old_debug"
11098         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11099         rm -f $DIR/$tfile
11100 }
11101 run_test 101f "check mmap read performance"
11102
11103 test_101g_brw_size_test() {
11104         local mb=$1
11105         local pages=$((mb * 1048576 / PAGE_SIZE))
11106         local file=$DIR/$tfile
11107
11108         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11109                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11110         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11111                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11112                         return 2
11113         done
11114
11115         stack_trap "rm -f $file" EXIT
11116         $LCTL set_param -n osc.*.rpc_stats=0
11117
11118         # 10 RPCs should be enough for the test
11119         local count=10
11120         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11121                 { error "dd write ${mb} MB blocks failed"; return 3; }
11122         cancel_lru_locks osc
11123         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11124                 { error "dd write ${mb} MB blocks failed"; return 4; }
11125
11126         # calculate number of full-sized read and write RPCs
11127         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11128                 sed -n '/pages per rpc/,/^$/p' |
11129                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11130                 END { print reads,writes }'))
11131         # allow one extra full-sized read RPC for async readahead
11132         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11133                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11134         [[ ${rpcs[1]} == $count ]] ||
11135                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11136 }
11137
11138 test_101g() {
11139         remote_ost_nodsh && skip "remote OST with nodsh"
11140
11141         local rpcs
11142         local osts=$(get_facets OST)
11143         local list=$(comma_list $(osts_nodes))
11144         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11145         local brw_size="obdfilter.*.brw_size"
11146
11147         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11148
11149         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11150
11151         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11152                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11153                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11154            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11155                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11156                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11157
11158                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11159                         suffix="M"
11160
11161                 if [[ $orig_mb -lt 16 ]]; then
11162                         save_lustre_params $osts "$brw_size" > $p
11163                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11164                                 error "set 16MB RPC size failed"
11165
11166                         echo "remount client to enable new RPC size"
11167                         remount_client $MOUNT || error "remount_client failed"
11168                 fi
11169
11170                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11171                 # should be able to set brw_size=12, but no rpc_stats for that
11172                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11173         fi
11174
11175         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11176
11177         if [[ $orig_mb -lt 16 ]]; then
11178                 restore_lustre_params < $p
11179                 remount_client $MOUNT || error "remount_client restore failed"
11180         fi
11181
11182         rm -f $p $DIR/$tfile
11183 }
11184 run_test 101g "Big bulk(4/16 MiB) readahead"
11185
11186 test_101h() {
11187         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11188
11189         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11190                 error "dd 70M file failed"
11191         echo Cancel LRU locks on lustre client to flush the client cache
11192         cancel_lru_locks osc
11193
11194         echo "Reset readahead stats"
11195         $LCTL set_param -n llite.*.read_ahead_stats 0
11196
11197         echo "Read 10M of data but cross 64M bundary"
11198         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11199         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11200                      get_named_value 'misses' | calc_total)
11201         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11202         rm -f $p $DIR/$tfile
11203 }
11204 run_test 101h "Readahead should cover current read window"
11205
11206 test_101i() {
11207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11208                 error "dd 10M file failed"
11209
11210         local max_per_file_mb=$($LCTL get_param -n \
11211                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11212         cancel_lru_locks osc
11213         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11214         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11215                 error "set max_read_ahead_per_file_mb to 1 failed"
11216
11217         echo "Reset readahead stats"
11218         $LCTL set_param llite.*.read_ahead_stats=0
11219
11220         dd if=$DIR/$tfile of=/dev/null bs=2M
11221
11222         $LCTL get_param llite.*.read_ahead_stats
11223         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11224                      awk '/misses/ { print $2 }')
11225         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11226         rm -f $DIR/$tfile
11227 }
11228 run_test 101i "allow current readahead to exceed reservation"
11229
11230 test_101j() {
11231         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11232                 error "setstripe $DIR/$tfile failed"
11233         local file_size=$((1048576 * 16))
11234         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11235         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11236
11237         echo Disable read-ahead
11238         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11239
11240         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11241         for blk in $PAGE_SIZE 1048576 $file_size; do
11242                 cancel_lru_locks osc
11243                 echo "Reset readahead stats"
11244                 $LCTL set_param -n llite.*.read_ahead_stats=0
11245                 local count=$(($file_size / $blk))
11246                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11247                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11248                              get_named_value 'failed.to.fast.read' | calc_total)
11249                 $LCTL get_param -n llite.*.read_ahead_stats
11250                 [ $miss -eq $count ] || error "expected $count got $miss"
11251         done
11252
11253         rm -f $p $DIR/$tfile
11254 }
11255 run_test 101j "A complete read block should be submitted when no RA"
11256
11257 test_101k()
11258 {
11259         local file=$DIR/$tfile
11260
11261         check_set_fallocate_or_skip
11262
11263         $LCTL set_param -n llite.*.read_ahead_stats=0
11264         fallocate -l 16K $file || error "failed to fallocate $file"
11265         cancel_lru_locks osc
11266         $MULTIOP $file or1048576c
11267         $LCTL get_param llite.*.read_ahead_stats
11268 }
11269 run_test 101k "read ahead for small file"
11270
11271 setup_test102() {
11272         test_mkdir $DIR/$tdir
11273         chown $RUNAS_ID $DIR/$tdir
11274         STRIPE_SIZE=65536
11275         STRIPE_OFFSET=1
11276         STRIPE_COUNT=$OSTCOUNT
11277         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11278
11279         trap cleanup_test102 EXIT
11280         cd $DIR
11281         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11282         cd $DIR/$tdir
11283         for num in 1 2 3 4; do
11284                 for count in $(seq 1 $STRIPE_COUNT); do
11285                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11286                                 local size=`expr $STRIPE_SIZE \* $num`
11287                                 local file=file"$num-$idx-$count"
11288                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11289                         done
11290                 done
11291         done
11292
11293         cd $DIR
11294         $1 tar cf $TMP/f102.tar $tdir --xattrs
11295 }
11296
11297 cleanup_test102() {
11298         trap 0
11299         rm -f $TMP/f102.tar
11300         rm -rf $DIR/d0.sanity/d102
11301 }
11302
11303 test_102a() {
11304         [ "$UID" != 0 ] && skip "must run as root"
11305         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11306                 skip_env "must have user_xattr"
11307
11308         [ -z "$(which setfattr 2>/dev/null)" ] &&
11309                 skip_env "could not find setfattr"
11310
11311         local testfile=$DIR/$tfile
11312
11313         touch $testfile
11314         echo "set/get xattr..."
11315         setfattr -n trusted.name1 -v value1 $testfile ||
11316                 error "setfattr -n trusted.name1=value1 $testfile failed"
11317         getfattr -n trusted.name1 $testfile 2> /dev/null |
11318           grep "trusted.name1=.value1" ||
11319                 error "$testfile missing trusted.name1=value1"
11320
11321         setfattr -n user.author1 -v author1 $testfile ||
11322                 error "setfattr -n user.author1=author1 $testfile failed"
11323         getfattr -n user.author1 $testfile 2> /dev/null |
11324           grep "user.author1=.author1" ||
11325                 error "$testfile missing trusted.author1=author1"
11326
11327         echo "listxattr..."
11328         setfattr -n trusted.name2 -v value2 $testfile ||
11329                 error "$testfile unable to set trusted.name2"
11330         setfattr -n trusted.name3 -v value3 $testfile ||
11331                 error "$testfile unable to set trusted.name3"
11332         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11333             grep "trusted.name" | wc -l) -eq 3 ] ||
11334                 error "$testfile missing 3 trusted.name xattrs"
11335
11336         setfattr -n user.author2 -v author2 $testfile ||
11337                 error "$testfile unable to set user.author2"
11338         setfattr -n user.author3 -v author3 $testfile ||
11339                 error "$testfile unable to set user.author3"
11340         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11341             grep "user.author" | wc -l) -eq 3 ] ||
11342                 error "$testfile missing 3 user.author xattrs"
11343
11344         echo "remove xattr..."
11345         setfattr -x trusted.name1 $testfile ||
11346                 error "$testfile error deleting trusted.name1"
11347         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11348                 error "$testfile did not delete trusted.name1 xattr"
11349
11350         setfattr -x user.author1 $testfile ||
11351                 error "$testfile error deleting user.author1"
11352         echo "set lustre special xattr ..."
11353         $LFS setstripe -c1 $testfile
11354         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11355                 awk -F "=" '/trusted.lov/ { print $2 }' )
11356         setfattr -n "trusted.lov" -v $lovea $testfile ||
11357                 error "$testfile doesn't ignore setting trusted.lov again"
11358         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11359                 error "$testfile allow setting invalid trusted.lov"
11360         rm -f $testfile
11361 }
11362 run_test 102a "user xattr test =================================="
11363
11364 check_102b_layout() {
11365         local layout="$*"
11366         local testfile=$DIR/$tfile
11367
11368         echo "test layout '$layout'"
11369         $LFS setstripe $layout $testfile || error "setstripe failed"
11370         $LFS getstripe -y $testfile
11371
11372         echo "get/set/list trusted.lov xattr ..." # b=10930
11373         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11374         [[ "$value" =~ "trusted.lov" ]] ||
11375                 error "can't get trusted.lov from $testfile"
11376         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11377                 error "getstripe failed"
11378
11379         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11380
11381         value=$(cut -d= -f2 <<<$value)
11382         # LU-13168: truncated xattr should fail if short lov_user_md header
11383         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11384                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11385         for len in $lens; do
11386                 echo "setfattr $len $testfile.2"
11387                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11388                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11389         done
11390         local stripe_size=$($LFS getstripe -S $testfile.2)
11391         local stripe_count=$($LFS getstripe -c $testfile.2)
11392         [[ $stripe_size -eq 65536 ]] ||
11393                 error "stripe size $stripe_size != 65536"
11394         [[ $stripe_count -eq $stripe_count_orig ]] ||
11395                 error "stripe count $stripe_count != $stripe_count_orig"
11396         rm $testfile $testfile.2
11397 }
11398
11399 test_102b() {
11400         [ -z "$(which setfattr 2>/dev/null)" ] &&
11401                 skip_env "could not find setfattr"
11402         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11403
11404         # check plain layout
11405         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11406
11407         # and also check composite layout
11408         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11409
11410 }
11411 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11412
11413 test_102c() {
11414         [ -z "$(which setfattr 2>/dev/null)" ] &&
11415                 skip_env "could not find setfattr"
11416         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11417
11418         # b10930: get/set/list lustre.lov xattr
11419         echo "get/set/list lustre.lov xattr ..."
11420         test_mkdir $DIR/$tdir
11421         chown $RUNAS_ID $DIR/$tdir
11422         local testfile=$DIR/$tdir/$tfile
11423         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11424                 error "setstripe failed"
11425         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11426                 error "getstripe failed"
11427         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11428         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11429
11430         local testfile2=${testfile}2
11431         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11432                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11433
11434         $RUNAS $MCREATE $testfile2
11435         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11436         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11437         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11438         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11439         [ $stripe_count -eq $STRIPECOUNT ] ||
11440                 error "stripe count $stripe_count != $STRIPECOUNT"
11441 }
11442 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11443
11444 compare_stripe_info1() {
11445         local stripe_index_all_zero=true
11446
11447         for num in 1 2 3 4; do
11448                 for count in $(seq 1 $STRIPE_COUNT); do
11449                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11450                                 local size=$((STRIPE_SIZE * num))
11451                                 local file=file"$num-$offset-$count"
11452                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11453                                 [[ $stripe_size -ne $size ]] &&
11454                                     error "$file: size $stripe_size != $size"
11455                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11456                                 # allow fewer stripes to be created, ORI-601
11457                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11458                                     error "$file: count $stripe_count != $count"
11459                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11460                                 [[ $stripe_index -ne 0 ]] &&
11461                                         stripe_index_all_zero=false
11462                         done
11463                 done
11464         done
11465         $stripe_index_all_zero &&
11466                 error "all files are being extracted starting from OST index 0"
11467         return 0
11468 }
11469
11470 have_xattrs_include() {
11471         tar --help | grep -q xattrs-include &&
11472                 echo --xattrs-include="lustre.*"
11473 }
11474
11475 test_102d() {
11476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11477         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11478
11479         XINC=$(have_xattrs_include)
11480         setup_test102
11481         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11482         cd $DIR/$tdir/$tdir
11483         compare_stripe_info1
11484 }
11485 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11486
11487 test_102f() {
11488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11489         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11490
11491         XINC=$(have_xattrs_include)
11492         setup_test102
11493         test_mkdir $DIR/$tdir.restore
11494         cd $DIR
11495         tar cf - --xattrs $tdir | tar xf - \
11496                 -C $DIR/$tdir.restore --xattrs $XINC
11497         cd $DIR/$tdir.restore/$tdir
11498         compare_stripe_info1
11499 }
11500 run_test 102f "tar copy files, not keep osts"
11501
11502 grow_xattr() {
11503         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11504                 skip "must have user_xattr"
11505         [ -z "$(which setfattr 2>/dev/null)" ] &&
11506                 skip_env "could not find setfattr"
11507         [ -z "$(which getfattr 2>/dev/null)" ] &&
11508                 skip_env "could not find getfattr"
11509
11510         local xsize=${1:-1024}  # in bytes
11511         local file=$DIR/$tfile
11512         local value="$(generate_string $xsize)"
11513         local xbig=trusted.big
11514         local toobig=$2
11515
11516         touch $file
11517         log "save $xbig on $file"
11518         if [ -z "$toobig" ]
11519         then
11520                 setfattr -n $xbig -v $value $file ||
11521                         error "saving $xbig on $file failed"
11522         else
11523                 setfattr -n $xbig -v $value $file &&
11524                         error "saving $xbig on $file succeeded"
11525                 return 0
11526         fi
11527
11528         local orig=$(get_xattr_value $xbig $file)
11529         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11530
11531         local xsml=trusted.sml
11532         log "save $xsml on $file"
11533         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11534
11535         local new=$(get_xattr_value $xbig $file)
11536         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11537
11538         log "grow $xsml on $file"
11539         setfattr -n $xsml -v "$value" $file ||
11540                 error "growing $xsml on $file failed"
11541
11542         new=$(get_xattr_value $xbig $file)
11543         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11544         log "$xbig still valid after growing $xsml"
11545
11546         rm -f $file
11547 }
11548
11549 test_102h() { # bug 15777
11550         grow_xattr 1024
11551 }
11552 run_test 102h "grow xattr from inside inode to external block"
11553
11554 test_102ha() {
11555         large_xattr_enabled || skip_env "ea_inode feature disabled"
11556
11557         echo "setting xattr of max xattr size: $(max_xattr_size)"
11558         grow_xattr $(max_xattr_size)
11559
11560         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11561         echo "This should fail:"
11562         grow_xattr $(($(max_xattr_size) + 10)) 1
11563 }
11564 run_test 102ha "grow xattr from inside inode to external inode"
11565
11566 test_102i() { # bug 17038
11567         [ -z "$(which getfattr 2>/dev/null)" ] &&
11568                 skip "could not find getfattr"
11569
11570         touch $DIR/$tfile
11571         ln -s $DIR/$tfile $DIR/${tfile}link
11572         getfattr -n trusted.lov $DIR/$tfile ||
11573                 error "lgetxattr on $DIR/$tfile failed"
11574         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11575                 grep -i "no such attr" ||
11576                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11577         rm -f $DIR/$tfile $DIR/${tfile}link
11578 }
11579 run_test 102i "lgetxattr test on symbolic link ============"
11580
11581 test_102j() {
11582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11584
11585         XINC=$(have_xattrs_include)
11586         setup_test102 "$RUNAS"
11587         chown $RUNAS_ID $DIR/$tdir
11588         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11589         cd $DIR/$tdir/$tdir
11590         compare_stripe_info1 "$RUNAS"
11591 }
11592 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11593
11594 test_102k() {
11595         [ -z "$(which setfattr 2>/dev/null)" ] &&
11596                 skip "could not find setfattr"
11597
11598         touch $DIR/$tfile
11599         # b22187 just check that does not crash for regular file.
11600         setfattr -n trusted.lov $DIR/$tfile
11601         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11602         local test_kdir=$DIR/$tdir
11603         test_mkdir $test_kdir
11604         local default_size=$($LFS getstripe -S $test_kdir)
11605         local default_count=$($LFS getstripe -c $test_kdir)
11606         local default_offset=$($LFS getstripe -i $test_kdir)
11607         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11608                 error 'dir setstripe failed'
11609         setfattr -n trusted.lov $test_kdir
11610         local stripe_size=$($LFS getstripe -S $test_kdir)
11611         local stripe_count=$($LFS getstripe -c $test_kdir)
11612         local stripe_offset=$($LFS getstripe -i $test_kdir)
11613         [ $stripe_size -eq $default_size ] ||
11614                 error "stripe size $stripe_size != $default_size"
11615         [ $stripe_count -eq $default_count ] ||
11616                 error "stripe count $stripe_count != $default_count"
11617         [ $stripe_offset -eq $default_offset ] ||
11618                 error "stripe offset $stripe_offset != $default_offset"
11619         rm -rf $DIR/$tfile $test_kdir
11620 }
11621 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11622
11623 test_102l() {
11624         [ -z "$(which getfattr 2>/dev/null)" ] &&
11625                 skip "could not find getfattr"
11626
11627         # LU-532 trusted. xattr is invisible to non-root
11628         local testfile=$DIR/$tfile
11629
11630         touch $testfile
11631
11632         echo "listxattr as user..."
11633         chown $RUNAS_ID $testfile
11634         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11635             grep -q "trusted" &&
11636                 error "$testfile trusted xattrs are user visible"
11637
11638         return 0;
11639 }
11640 run_test 102l "listxattr size test =================================="
11641
11642 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11643         local path=$DIR/$tfile
11644         touch $path
11645
11646         listxattr_size_check $path || error "listattr_size_check $path failed"
11647 }
11648 run_test 102m "Ensure listxattr fails on small bufffer ========"
11649
11650 cleanup_test102
11651
11652 getxattr() { # getxattr path name
11653         # Return the base64 encoding of the value of xattr name on path.
11654         local path=$1
11655         local name=$2
11656
11657         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11658         # file: $path
11659         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11660         #
11661         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11662
11663         getfattr --absolute-names --encoding=base64 --name=$name $path |
11664                 awk -F= -v name=$name '$1 == name {
11665                         print substr($0, index($0, "=") + 1);
11666         }'
11667 }
11668
11669 test_102n() { # LU-4101 mdt: protect internal xattrs
11670         [ -z "$(which setfattr 2>/dev/null)" ] &&
11671                 skip "could not find setfattr"
11672         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11673         then
11674                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11675         fi
11676
11677         local file0=$DIR/$tfile.0
11678         local file1=$DIR/$tfile.1
11679         local xattr0=$TMP/$tfile.0
11680         local xattr1=$TMP/$tfile.1
11681         local namelist="lov lma lmv link fid version som hsm"
11682         local name
11683         local value
11684
11685         rm -rf $file0 $file1 $xattr0 $xattr1
11686         touch $file0 $file1
11687
11688         # Get 'before' xattrs of $file1.
11689         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11690
11691         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11692                 namelist+=" lfsck_namespace"
11693         for name in $namelist; do
11694                 # Try to copy xattr from $file0 to $file1.
11695                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11696
11697                 setfattr --name=trusted.$name --value="$value" $file1 ||
11698                         error "setxattr 'trusted.$name' failed"
11699
11700                 # Try to set a garbage xattr.
11701                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11702
11703                 if [[ x$name == "xlov" ]]; then
11704                         setfattr --name=trusted.lov --value="$value" $file1 &&
11705                         error "setxattr invalid 'trusted.lov' success"
11706                 else
11707                         setfattr --name=trusted.$name --value="$value" $file1 ||
11708                                 error "setxattr invalid 'trusted.$name' failed"
11709                 fi
11710
11711                 # Try to remove the xattr from $file1. We don't care if this
11712                 # appears to succeed or fail, we just don't want there to be
11713                 # any changes or crashes.
11714                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11715         done
11716
11717         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11718         then
11719                 name="lfsck_ns"
11720                 # Try to copy xattr from $file0 to $file1.
11721                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11722
11723                 setfattr --name=trusted.$name --value="$value" $file1 ||
11724                         error "setxattr 'trusted.$name' failed"
11725
11726                 # Try to set a garbage xattr.
11727                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11728
11729                 setfattr --name=trusted.$name --value="$value" $file1 ||
11730                         error "setxattr 'trusted.$name' failed"
11731
11732                 # Try to remove the xattr from $file1. We don't care if this
11733                 # appears to succeed or fail, we just don't want there to be
11734                 # any changes or crashes.
11735                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11736         fi
11737
11738         # Get 'after' xattrs of file1.
11739         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11740
11741         if ! diff $xattr0 $xattr1; then
11742                 error "before and after xattrs of '$file1' differ"
11743         fi
11744
11745         rm -rf $file0 $file1 $xattr0 $xattr1
11746
11747         return 0
11748 }
11749 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11750
11751 test_102p() { # LU-4703 setxattr did not check ownership
11752         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11753                 skip "MDS needs to be at least 2.5.56"
11754
11755         local testfile=$DIR/$tfile
11756
11757         touch $testfile
11758
11759         echo "setfacl as user..."
11760         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11761         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11762
11763         echo "setfattr as user..."
11764         setfacl -m "u:$RUNAS_ID:---" $testfile
11765         $RUNAS setfattr -x system.posix_acl_access $testfile
11766         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11767 }
11768 run_test 102p "check setxattr(2) correctly fails without permission"
11769
11770 test_102q() {
11771         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11772                 skip "MDS needs to be at least 2.6.92"
11773
11774         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11775 }
11776 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11777
11778 test_102r() {
11779         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11780                 skip "MDS needs to be at least 2.6.93"
11781
11782         touch $DIR/$tfile || error "touch"
11783         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11784         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11785         rm $DIR/$tfile || error "rm"
11786
11787         #normal directory
11788         mkdir -p $DIR/$tdir || error "mkdir"
11789         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11790         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11791         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11792                 error "$testfile error deleting user.author1"
11793         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11794                 grep "user.$(basename $tdir)" &&
11795                 error "$tdir did not delete user.$(basename $tdir)"
11796         rmdir $DIR/$tdir || error "rmdir"
11797
11798         #striped directory
11799         test_mkdir $DIR/$tdir
11800         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11801         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11802         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11803                 error "$testfile error deleting user.author1"
11804         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11805                 grep "user.$(basename $tdir)" &&
11806                 error "$tdir did not delete user.$(basename $tdir)"
11807         rmdir $DIR/$tdir || error "rm striped dir"
11808 }
11809 run_test 102r "set EAs with empty values"
11810
11811 test_102s() {
11812         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11813                 skip "MDS needs to be at least 2.11.52"
11814
11815         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11816
11817         save_lustre_params client "llite.*.xattr_cache" > $save
11818
11819         for cache in 0 1; do
11820                 lctl set_param llite.*.xattr_cache=$cache
11821
11822                 rm -f $DIR/$tfile
11823                 touch $DIR/$tfile || error "touch"
11824                 for prefix in lustre security system trusted user; do
11825                         # Note getxattr() may fail with 'Operation not
11826                         # supported' or 'No such attribute' depending
11827                         # on prefix and cache.
11828                         getfattr -n $prefix.n102s $DIR/$tfile &&
11829                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11830                 done
11831         done
11832
11833         restore_lustre_params < $save
11834 }
11835 run_test 102s "getting nonexistent xattrs should fail"
11836
11837 test_102t() {
11838         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11839                 skip "MDS needs to be at least 2.11.52"
11840
11841         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11842
11843         save_lustre_params client "llite.*.xattr_cache" > $save
11844
11845         for cache in 0 1; do
11846                 lctl set_param llite.*.xattr_cache=$cache
11847
11848                 for buf_size in 0 256; do
11849                         rm -f $DIR/$tfile
11850                         touch $DIR/$tfile || error "touch"
11851                         setfattr -n user.multiop $DIR/$tfile
11852                         $MULTIOP $DIR/$tfile oa$buf_size ||
11853                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11854                 done
11855         done
11856
11857         restore_lustre_params < $save
11858 }
11859 run_test 102t "zero length xattr values handled correctly"
11860
11861 run_acl_subtest()
11862 {
11863         local test=$LUSTRE/tests/acl/$1.test
11864         local tmp=$(mktemp -t $1-XXXXXX).test
11865         local bin=$2
11866         local dmn=$3
11867         local grp=$4
11868         local nbd=$5
11869         export LANG=C
11870
11871
11872         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
11873         local sedgroups="-e s/:users/:$grp/g"
11874         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
11875
11876         sed $sedusers $sedgroups < $test > $tmp
11877         stack_trap "rm -f $tmp"
11878         [[ -s $tmp ]] || error "sed failed to create test script"
11879
11880         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
11881         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
11882 }
11883
11884 test_103a() {
11885         [ "$UID" != 0 ] && skip "must run as root"
11886         $GSS && skip_env "could not run under gss"
11887         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
11888                 skip_env "must have acl enabled"
11889         which setfacl || skip_env "could not find setfacl"
11890         remote_mds_nodsh && skip "remote MDS with nodsh"
11891
11892         ACLBIN=${ACLBIN:-"bin"}
11893         ACLDMN=${ACLDMN:-"daemon"}
11894         ACLGRP=${ACLGRP:-"users"}
11895         ACLNBD=${ACLNBD:-"nobody"}
11896
11897         if ! id $ACLBIN ||
11898            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
11899                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
11900                 ACLBIN=$USER0
11901                 if ! id $ACLBIN ; then
11902                         cat /etc/passwd
11903                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
11904                 fi
11905         fi
11906         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
11907            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
11908                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
11909                 ACLDMN=$USER1
11910                 if ! id $ACLDMN ; then
11911                         cat /etc/passwd
11912                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
11913                 fi
11914         fi
11915         if ! getent group $ACLGRP; then
11916                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
11917                 ACLGRP="$TSTUSR"
11918                 if ! getent group $ACLGRP; then
11919                         echo "cannot find group '$ACLGRP', adding it"
11920                         cat /etc/group
11921                         add_group 60000 $ACLGRP
11922                 fi
11923         fi
11924
11925         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
11926         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
11927         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11928
11929         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11930                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
11931                 ACLGRP="$TSTUSR"
11932                 if ! getent group $ACLGRP; then
11933                         echo "cannot find group '$ACLGRP', adding it"
11934                         cat /etc/group
11935                         add_group 60000 $ACLGRP
11936                 fi
11937                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
11938                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
11939                         cat /etc/group
11940                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
11941                 fi
11942         fi
11943
11944         gpasswd -a $ACLDMN $ACLBIN ||
11945                 error "setting client group failed"             # LU-5641
11946         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
11947                 error "setting MDS group failed"                # LU-5641
11948
11949         declare -a identity_old
11950
11951         for num in $(seq $MDSCOUNT); do
11952                 switch_identity $num true || identity_old[$num]=$?
11953         done
11954
11955         SAVE_UMASK=$(umask)
11956         umask 0022
11957         mkdir -p $DIR/$tdir
11958         cd $DIR/$tdir
11959
11960         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
11961         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
11962         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
11963         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
11964         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11965         # CentOS7- uses nobody=99, while newer distros use nobody=65534
11966         if ! id -u $ACLNBD ||
11967            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
11968                 ACLNBD="nfsnobody"
11969                 if ! id -u $ACLNBD; then
11970                         ACLNBD=""
11971                 fi
11972         fi
11973         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
11974                 add_group $(id -u $ACLNBD) $ACLNBD
11975                 if ! getent group $ACLNBD; then
11976                         ACLNBD=""
11977                 fi
11978         fi
11979         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
11980            [[ -n "$ACLNBD" ]] && which setfattr; then
11981                 run_acl_subtest permissions_xattr \
11982                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
11983         elif [[ -z "$ACLNBD" ]]; then
11984                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
11985         else
11986                 echo "skip 'permission_xattr' test - missing setfattr command"
11987         fi
11988         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
11989
11990         # inheritance test got from HP
11991         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11992         chmod +x make-tree || error "chmod +x failed"
11993         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
11994         rm -f make-tree
11995
11996         echo "LU-974 ignore umask when acl is enabled..."
11997         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
11998         if [ $MDSCOUNT -ge 2 ]; then
11999                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12000         fi
12001
12002         echo "LU-2561 newly created file is same size as directory..."
12003         if [ "$mds1_FSTYPE" != "zfs" ]; then
12004                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12005         else
12006                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12007         fi
12008
12009         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12010
12011         cd $SAVE_PWD
12012         umask $SAVE_UMASK
12013
12014         for num in $(seq $MDSCOUNT); do
12015                 if [ "${identity_old[$num]}" = 1 ]; then
12016                         switch_identity $num false || identity_old[$num]=$?
12017                 fi
12018         done
12019 }
12020 run_test 103a "acl test"
12021
12022 test_103b() {
12023         declare -a pids
12024         local U
12025
12026         for U in {0..511}; do
12027                 {
12028                 local O=$(printf "%04o" $U)
12029
12030                 umask $(printf "%04o" $((511 ^ $O)))
12031                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12032                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12033
12034                 (( $S == ($O & 0666) )) ||
12035                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12036
12037                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12038                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12039                 (( $S == ($O & 0666) )) ||
12040                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12041
12042                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12043                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12044                 (( $S == ($O & 0666) )) ||
12045                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12046                 rm -f $DIR/$tfile.[smp]$0
12047                 } &
12048                 local pid=$!
12049
12050                 # limit the concurrently running threads to 64. LU-11878
12051                 local idx=$((U % 64))
12052                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12053                 pids[idx]=$pid
12054         done
12055         wait
12056 }
12057 run_test 103b "umask lfs setstripe"
12058
12059 test_103c() {
12060         mkdir -p $DIR/$tdir
12061         cp -rp $DIR/$tdir $DIR/$tdir.bak
12062
12063         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12064                 error "$DIR/$tdir shouldn't contain default ACL"
12065         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12066                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12067         true
12068 }
12069 run_test 103c "'cp -rp' won't set empty acl"
12070
12071 test_103e() {
12072         local numacl
12073         local fileacl
12074         local saved_debug=$($LCTL get_param -n debug)
12075
12076         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12077                 skip "MDS needs to be at least 2.14.52"
12078
12079         large_xattr_enabled || skip_env "ea_inode feature disabled"
12080
12081         mkdir -p $DIR/$tdir
12082         # add big LOV EA to cause reply buffer overflow earlier
12083         $LFS setstripe -C 1000 $DIR/$tdir
12084         lctl set_param mdc.*-mdc*.stats=clear
12085
12086         $LCTL set_param debug=0
12087         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12088         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12089
12090         # add a large number of default ACLs (expect 8000+ for 2.13+)
12091         for U in {2..7000}; do
12092                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12093                         error "Able to add just $U default ACLs"
12094         done
12095         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12096         echo "$numacl default ACLs created"
12097
12098         stat $DIR/$tdir || error "Cannot stat directory"
12099         # check file creation
12100         touch $DIR/$tdir/$tfile ||
12101                 error "failed to create $tfile with $numacl default ACLs"
12102         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12103         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12104         echo "$fileacl ACLs were inherited"
12105         (( $fileacl == $numacl )) ||
12106                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12107         # check that new ACLs creation adds new ACLs to inherited ACLs
12108         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12109                 error "Cannot set new ACL"
12110         numacl=$((numacl + 1))
12111         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12112         (( $fileacl == $numacl )) ||
12113                 error "failed to add new ACL: $fileacl != $numacl as expected"
12114         # adds more ACLs to a file to reach their maximum at 8000+
12115         numacl=0
12116         for U in {20000..25000}; do
12117                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12118                 numacl=$((numacl + 1))
12119         done
12120         echo "Added $numacl more ACLs to the file"
12121         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12122         echo "Total $fileacl ACLs in file"
12123         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12124         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12125         rmdir $DIR/$tdir || error "Cannot remove directory"
12126 }
12127 run_test 103e "inheritance of big amount of default ACLs"
12128
12129 test_103f() {
12130         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12131                 skip "MDS needs to be at least 2.14.51"
12132
12133         large_xattr_enabled || skip_env "ea_inode feature disabled"
12134
12135         # enable changelog to consume more internal MDD buffers
12136         changelog_register
12137
12138         mkdir -p $DIR/$tdir
12139         # add big LOV EA
12140         $LFS setstripe -C 1000 $DIR/$tdir
12141         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12142         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12143         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12144         rmdir $DIR/$tdir || error "Cannot remove directory"
12145 }
12146 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12147
12148 test_104a() {
12149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12150
12151         touch $DIR/$tfile
12152         lfs df || error "lfs df failed"
12153         lfs df -ih || error "lfs df -ih failed"
12154         lfs df -h $DIR || error "lfs df -h $DIR failed"
12155         lfs df -i $DIR || error "lfs df -i $DIR failed"
12156         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12157         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12158
12159         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12160         lctl --device %$OSC deactivate
12161         lfs df || error "lfs df with deactivated OSC failed"
12162         lctl --device %$OSC activate
12163         # wait the osc back to normal
12164         wait_osc_import_ready client ost
12165
12166         lfs df || error "lfs df with reactivated OSC failed"
12167         rm -f $DIR/$tfile
12168 }
12169 run_test 104a "lfs df [-ih] [path] test ========================="
12170
12171 test_104b() {
12172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12173         [ $RUNAS_ID -eq $UID ] &&
12174                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12175
12176         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12177                         grep "Permission denied" | wc -l)))
12178         if [ $denied_cnt -ne 0 ]; then
12179                 error "lfs check servers test failed"
12180         fi
12181 }
12182 run_test 104b "$RUNAS lfs check servers test ===================="
12183
12184 #
12185 # Verify $1 is within range of $2.
12186 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12187 # $1 is <= 2% of $2. Else Fail.
12188 #
12189 value_in_range() {
12190         # Strip all units (M, G, T)
12191         actual=$(echo $1 | tr -d A-Z)
12192         expect=$(echo $2 | tr -d A-Z)
12193
12194         expect_lo=$(($expect * 98 / 100)) # 2% below
12195         expect_hi=$(($expect * 102 / 100)) # 2% above
12196
12197         # permit 2% drift above and below
12198         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12199 }
12200
12201 test_104c() {
12202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12203         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12204
12205         local ost_param="osd-zfs.$FSNAME-OST0000."
12206         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12207         local ofacets=$(get_facets OST)
12208         local mfacets=$(get_facets MDS)
12209         local saved_ost_blocks=
12210         local saved_mdt_blocks=
12211
12212         echo "Before recordsize change"
12213         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12214         df=($(df -h | grep "$MOUNT"$))
12215
12216         # For checking.
12217         echo "lfs output : ${lfs_df[*]}"
12218         echo "df  output : ${df[*]}"
12219
12220         for facet in ${ofacets//,/ }; do
12221                 if [ -z $saved_ost_blocks ]; then
12222                         saved_ost_blocks=$(do_facet $facet \
12223                                 lctl get_param -n $ost_param.blocksize)
12224                         echo "OST Blocksize: $saved_ost_blocks"
12225                 fi
12226                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12227                 do_facet $facet zfs set recordsize=32768 $ost
12228         done
12229
12230         # BS too small. Sufficient for functional testing.
12231         for facet in ${mfacets//,/ }; do
12232                 if [ -z $saved_mdt_blocks ]; then
12233                         saved_mdt_blocks=$(do_facet $facet \
12234                                 lctl get_param -n $mdt_param.blocksize)
12235                         echo "MDT Blocksize: $saved_mdt_blocks"
12236                 fi
12237                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12238                 do_facet $facet zfs set recordsize=32768 $mdt
12239         done
12240
12241         # Give new values chance to reflect change
12242         sleep 2
12243
12244         echo "After recordsize change"
12245         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12246         df_after=($(df -h | grep "$MOUNT"$))
12247
12248         # For checking.
12249         echo "lfs output : ${lfs_df_after[*]}"
12250         echo "df  output : ${df_after[*]}"
12251
12252         # Verify lfs df
12253         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12254                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12255         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12256                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12257         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12258                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12259
12260         # Verify df
12261         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12262                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12263         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12264                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12265         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12266                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12267
12268         # Restore MDT recordize back to original
12269         for facet in ${mfacets//,/ }; do
12270                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12271                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12272         done
12273
12274         # Restore OST recordize back to original
12275         for facet in ${ofacets//,/ }; do
12276                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12277                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12278         done
12279
12280         return 0
12281 }
12282 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12283
12284 test_104d() {
12285         (( $RUNAS_ID != $UID )) ||
12286                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12287
12288         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12289                 skip "lustre version doesn't support lctl dl with non-root"
12290
12291         # debugfs only allows root users to access files, so the
12292         # previous move of the "devices" file to debugfs broke
12293         # "lctl dl" for non-root users. The LU-9680 Netlink
12294         # interface again allows non-root users to list devices.
12295         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12296                 error "lctl dl doesn't work for non root"
12297
12298         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12299         [ "$ost_count" -eq $OSTCOUNT ]  ||
12300                 error "lctl dl reports wrong number of OST devices"
12301
12302         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12303         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12304                 error "lctl dl reports wrong number of MDT devices"
12305 }
12306 run_test 104d "$RUNAS lctl dl test"
12307
12308 test_105a() {
12309         # doesn't work on 2.4 kernels
12310         touch $DIR/$tfile
12311         if $(flock_is_enabled); then
12312                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12313         else
12314                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12315         fi
12316         rm -f $DIR/$tfile
12317 }
12318 run_test 105a "flock when mounted without -o flock test ========"
12319
12320 test_105b() {
12321         touch $DIR/$tfile
12322         if $(flock_is_enabled); then
12323                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12324         else
12325                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12326         fi
12327         rm -f $DIR/$tfile
12328 }
12329 run_test 105b "fcntl when mounted without -o flock test ========"
12330
12331 test_105c() {
12332         touch $DIR/$tfile
12333         if $(flock_is_enabled); then
12334                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12335         else
12336                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12337         fi
12338         rm -f $DIR/$tfile
12339 }
12340 run_test 105c "lockf when mounted without -o flock test"
12341
12342 test_105d() { # bug 15924
12343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12344
12345         test_mkdir $DIR/$tdir
12346         flock_is_enabled || skip_env "mount w/o flock enabled"
12347         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12348         $LCTL set_param fail_loc=0x80000315
12349         flocks_test 2 $DIR/$tdir
12350 }
12351 run_test 105d "flock race (should not freeze) ========"
12352
12353 test_105e() { # bug 22660 && 22040
12354         flock_is_enabled || skip_env "mount w/o flock enabled"
12355
12356         touch $DIR/$tfile
12357         flocks_test 3 $DIR/$tfile
12358 }
12359 run_test 105e "Two conflicting flocks from same process"
12360
12361 test_106() { #bug 10921
12362         test_mkdir $DIR/$tdir
12363         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12364         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12365 }
12366 run_test 106 "attempt exec of dir followed by chown of that dir"
12367
12368 test_107() {
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12370
12371         CDIR=`pwd`
12372         local file=core
12373
12374         cd $DIR
12375         rm -f $file
12376
12377         local save_pattern=$(sysctl -n kernel.core_pattern)
12378         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12379         sysctl -w kernel.core_pattern=$file
12380         sysctl -w kernel.core_uses_pid=0
12381
12382         ulimit -c unlimited
12383         sleep 60 &
12384         SLEEPPID=$!
12385
12386         sleep 1
12387
12388         kill -s 11 $SLEEPPID
12389         wait $SLEEPPID
12390         if [ -e $file ]; then
12391                 size=`stat -c%s $file`
12392                 [ $size -eq 0 ] && error "Fail to create core file $file"
12393         else
12394                 error "Fail to create core file $file"
12395         fi
12396         rm -f $file
12397         sysctl -w kernel.core_pattern=$save_pattern
12398         sysctl -w kernel.core_uses_pid=$save_uses_pid
12399         cd $CDIR
12400 }
12401 run_test 107 "Coredump on SIG"
12402
12403 test_110() {
12404         test_mkdir $DIR/$tdir
12405         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12406         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12407                 error "mkdir with 256 char should fail, but did not"
12408         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12409                 error "create with 255 char failed"
12410         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12411                 error "create with 256 char should fail, but did not"
12412
12413         ls -l $DIR/$tdir
12414         rm -rf $DIR/$tdir
12415 }
12416 run_test 110 "filename length checking"
12417
12418 test_116a() { # was previously test_116()
12419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12420         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12421         remote_mds_nodsh && skip "remote MDS with nodsh"
12422
12423         echo -n "Free space priority "
12424         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12425                 head -n1
12426         declare -a AVAIL
12427         free_min_max
12428
12429         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12430         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12431         stack_trap simple_cleanup_common
12432
12433         # Check if we need to generate uneven OSTs
12434         test_mkdir -p $DIR/$tdir/OST${MINI}
12435         local FILL=$((MINV / 4))
12436         local DIFF=$((MAXV - MINV))
12437         local DIFF2=$((DIFF * 100 / MINV))
12438
12439         local threshold=$(do_facet $SINGLEMDS \
12440                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12441         threshold=${threshold%%%}
12442         echo -n "Check for uneven OSTs: "
12443         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12444
12445         if [[ $DIFF2 -gt $threshold ]]; then
12446                 echo "ok"
12447                 echo "Don't need to fill OST$MINI"
12448         else
12449                 # generate uneven OSTs. Write 2% over the QOS threshold value
12450                 echo "no"
12451                 DIFF=$((threshold - DIFF2 + 2))
12452                 DIFF2=$((MINV * DIFF / 100))
12453                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12454                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12455                         error "setstripe failed"
12456                 DIFF=$((DIFF2 / 2048))
12457                 i=0
12458                 while [ $i -lt $DIFF ]; do
12459                         i=$((i + 1))
12460                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12461                                 bs=2M count=1 2>/dev/null
12462                         echo -n .
12463                 done
12464                 echo .
12465                 sync
12466                 sleep_maxage
12467                 free_min_max
12468         fi
12469
12470         DIFF=$((MAXV - MINV))
12471         DIFF2=$((DIFF * 100 / MINV))
12472         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12473         if [ $DIFF2 -gt $threshold ]; then
12474                 echo "ok"
12475         else
12476                 skip "QOS imbalance criteria not met"
12477         fi
12478
12479         MINI1=$MINI
12480         MINV1=$MINV
12481         MAXI1=$MAXI
12482         MAXV1=$MAXV
12483
12484         # now fill using QOS
12485         $LFS setstripe -c 1 $DIR/$tdir
12486         FILL=$((FILL / 200))
12487         if [ $FILL -gt 600 ]; then
12488                 FILL=600
12489         fi
12490         echo "writing $FILL files to QOS-assigned OSTs"
12491         i=0
12492         while [ $i -lt $FILL ]; do
12493                 i=$((i + 1))
12494                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12495                         count=1 2>/dev/null
12496                 echo -n .
12497         done
12498         echo "wrote $i 200k files"
12499         sync
12500         sleep_maxage
12501
12502         echo "Note: free space may not be updated, so measurements might be off"
12503         free_min_max
12504         DIFF2=$((MAXV - MINV))
12505         echo "free space delta: orig $DIFF final $DIFF2"
12506         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12507         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12508         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12509         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12510         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12511         if [[ $DIFF -gt 0 ]]; then
12512                 FILL=$((DIFF2 * 100 / DIFF - 100))
12513                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12514         fi
12515
12516         # Figure out which files were written where
12517         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12518                awk '/'$MINI1': / {print $2; exit}')
12519         echo $UUID
12520         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12521         echo "$MINC files created on smaller OST $MINI1"
12522         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12523                awk '/'$MAXI1': / {print $2; exit}')
12524         echo $UUID
12525         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12526         echo "$MAXC files created on larger OST $MAXI1"
12527         if [[ $MINC -gt 0 ]]; then
12528                 FILL=$((MAXC * 100 / MINC - 100))
12529                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12530         fi
12531         [[ $MAXC -gt $MINC ]] ||
12532                 error_ignore LU-9 "stripe QOS didn't balance free space"
12533 }
12534 run_test 116a "stripe QOS: free space balance ==================="
12535
12536 test_116b() { # LU-2093
12537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12538         remote_mds_nodsh && skip "remote MDS with nodsh"
12539
12540 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12541         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12542                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12543         [ -z "$old_rr" ] && skip "no QOS"
12544         do_facet $SINGLEMDS lctl set_param \
12545                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12546         mkdir -p $DIR/$tdir
12547         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12548         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12549         do_facet $SINGLEMDS lctl set_param fail_loc=0
12550         rm -rf $DIR/$tdir
12551         do_facet $SINGLEMDS lctl set_param \
12552                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12553 }
12554 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12555
12556 test_117() # bug 10891
12557 {
12558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12559
12560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12561         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12562         lctl set_param fail_loc=0x21e
12563         > $DIR/$tfile || error "truncate failed"
12564         lctl set_param fail_loc=0
12565         echo "Truncate succeeded."
12566         rm -f $DIR/$tfile
12567 }
12568 run_test 117 "verify osd extend =========="
12569
12570 NO_SLOW_RESENDCOUNT=4
12571 export OLD_RESENDCOUNT=""
12572 set_resend_count () {
12573         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12574         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12575         lctl set_param -n $PROC_RESENDCOUNT $1
12576         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12577 }
12578
12579 # for reduce test_118* time (b=14842)
12580 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12581
12582 # Reset async IO behavior after error case
12583 reset_async() {
12584         FILE=$DIR/reset_async
12585
12586         # Ensure all OSCs are cleared
12587         $LFS setstripe -c -1 $FILE
12588         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12589         sync
12590         rm $FILE
12591 }
12592
12593 test_118a() #bug 11710
12594 {
12595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12596
12597         reset_async
12598
12599         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12600         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12601         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12602
12603         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12604                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12605                 return 1;
12606         fi
12607         rm -f $DIR/$tfile
12608 }
12609 run_test 118a "verify O_SYNC works =========="
12610
12611 test_118b()
12612 {
12613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12614         remote_ost_nodsh && skip "remote OST with nodsh"
12615
12616         reset_async
12617
12618         #define OBD_FAIL_SRV_ENOENT 0x217
12619         set_nodes_failloc "$(osts_nodes)" 0x217
12620         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12621         RC=$?
12622         set_nodes_failloc "$(osts_nodes)" 0
12623         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12624         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12625                     grep -c writeback)
12626
12627         if [[ $RC -eq 0 ]]; then
12628                 error "Must return error due to dropped pages, rc=$RC"
12629                 return 1;
12630         fi
12631
12632         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12633                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12634                 return 1;
12635         fi
12636
12637         echo "Dirty pages not leaked on ENOENT"
12638
12639         # Due to the above error the OSC will issue all RPCs syncronously
12640         # until a subsequent RPC completes successfully without error.
12641         $MULTIOP $DIR/$tfile Ow4096yc
12642         rm -f $DIR/$tfile
12643
12644         return 0
12645 }
12646 run_test 118b "Reclaim dirty pages on fatal error =========="
12647
12648 test_118c()
12649 {
12650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12651
12652         # for 118c, restore the original resend count, LU-1940
12653         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12654                                 set_resend_count $OLD_RESENDCOUNT
12655         remote_ost_nodsh && skip "remote OST with nodsh"
12656
12657         reset_async
12658
12659         #define OBD_FAIL_OST_EROFS               0x216
12660         set_nodes_failloc "$(osts_nodes)" 0x216
12661
12662         # multiop should block due to fsync until pages are written
12663         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12664         MULTIPID=$!
12665         sleep 1
12666
12667         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12668                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12669         fi
12670
12671         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12672                     grep -c writeback)
12673         if [[ $WRITEBACK -eq 0 ]]; then
12674                 error "No page in writeback, writeback=$WRITEBACK"
12675         fi
12676
12677         set_nodes_failloc "$(osts_nodes)" 0
12678         wait $MULTIPID
12679         RC=$?
12680         if [[ $RC -ne 0 ]]; then
12681                 error "Multiop fsync failed, rc=$RC"
12682         fi
12683
12684         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12685         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12686                     grep -c writeback)
12687         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12688                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12689         fi
12690
12691         rm -f $DIR/$tfile
12692         echo "Dirty pages flushed via fsync on EROFS"
12693         return 0
12694 }
12695 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12696
12697 # continue to use small resend count to reduce test_118* time (b=14842)
12698 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12699
12700 test_118d()
12701 {
12702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12703         remote_ost_nodsh && skip "remote OST with nodsh"
12704
12705         reset_async
12706
12707         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12708         set_nodes_failloc "$(osts_nodes)" 0x214
12709         # multiop should block due to fsync until pages are written
12710         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12711         MULTIPID=$!
12712         sleep 1
12713
12714         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12715                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12716         fi
12717
12718         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12719                     grep -c writeback)
12720         if [[ $WRITEBACK -eq 0 ]]; then
12721                 error "No page in writeback, writeback=$WRITEBACK"
12722         fi
12723
12724         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12725         set_nodes_failloc "$(osts_nodes)" 0
12726
12727         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12728         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12729                     grep -c writeback)
12730         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12731                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12732         fi
12733
12734         rm -f $DIR/$tfile
12735         echo "Dirty pages gaurenteed flushed via fsync"
12736         return 0
12737 }
12738 run_test 118d "Fsync validation inject a delay of the bulk =========="
12739
12740 test_118f() {
12741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12742
12743         reset_async
12744
12745         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12746         lctl set_param fail_loc=0x8000040a
12747
12748         # Should simulate EINVAL error which is fatal
12749         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12750         RC=$?
12751         if [[ $RC -eq 0 ]]; then
12752                 error "Must return error due to dropped pages, rc=$RC"
12753         fi
12754
12755         lctl set_param fail_loc=0x0
12756
12757         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12758         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12759         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12760                     grep -c writeback)
12761         if [[ $LOCKED -ne 0 ]]; then
12762                 error "Locked pages remain in cache, locked=$LOCKED"
12763         fi
12764
12765         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12766                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12767         fi
12768
12769         rm -f $DIR/$tfile
12770         echo "No pages locked after fsync"
12771
12772         reset_async
12773         return 0
12774 }
12775 run_test 118f "Simulate unrecoverable OSC side error =========="
12776
12777 test_118g() {
12778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12779
12780         reset_async
12781
12782         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12783         lctl set_param fail_loc=0x406
12784
12785         # simulate local -ENOMEM
12786         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12787         RC=$?
12788
12789         lctl set_param fail_loc=0
12790         if [[ $RC -eq 0 ]]; then
12791                 error "Must return error due to dropped pages, rc=$RC"
12792         fi
12793
12794         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12795         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12796         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12797                         grep -c writeback)
12798         if [[ $LOCKED -ne 0 ]]; then
12799                 error "Locked pages remain in cache, locked=$LOCKED"
12800         fi
12801
12802         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12803                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12804         fi
12805
12806         rm -f $DIR/$tfile
12807         echo "No pages locked after fsync"
12808
12809         reset_async
12810         return 0
12811 }
12812 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12813
12814 test_118h() {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816         remote_ost_nodsh && skip "remote OST with nodsh"
12817
12818         reset_async
12819
12820         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12821         set_nodes_failloc "$(osts_nodes)" 0x20e
12822         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12823         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12824         RC=$?
12825
12826         set_nodes_failloc "$(osts_nodes)" 0
12827         if [[ $RC -eq 0 ]]; then
12828                 error "Must return error due to dropped pages, rc=$RC"
12829         fi
12830
12831         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12832         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12833         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12834                     grep -c writeback)
12835         if [[ $LOCKED -ne 0 ]]; then
12836                 error "Locked pages remain in cache, locked=$LOCKED"
12837         fi
12838
12839         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12840                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12841         fi
12842
12843         rm -f $DIR/$tfile
12844         echo "No pages locked after fsync"
12845
12846         return 0
12847 }
12848 run_test 118h "Verify timeout in handling recoverables errors  =========="
12849
12850 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12851
12852 test_118i() {
12853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12854         remote_ost_nodsh && skip "remote OST with nodsh"
12855
12856         reset_async
12857
12858         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12859         set_nodes_failloc "$(osts_nodes)" 0x20e
12860
12861         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12862         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12863         PID=$!
12864         sleep 5
12865         set_nodes_failloc "$(osts_nodes)" 0
12866
12867         wait $PID
12868         RC=$?
12869         if [[ $RC -ne 0 ]]; then
12870                 error "got error, but should be not, rc=$RC"
12871         fi
12872
12873         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12874         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12875         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12876         if [[ $LOCKED -ne 0 ]]; then
12877                 error "Locked pages remain in cache, locked=$LOCKED"
12878         fi
12879
12880         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12881                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12882         fi
12883
12884         rm -f $DIR/$tfile
12885         echo "No pages locked after fsync"
12886
12887         return 0
12888 }
12889 run_test 118i "Fix error before timeout in recoverable error  =========="
12890
12891 [ "$SLOW" = "no" ] && set_resend_count 4
12892
12893 test_118j() {
12894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12895         remote_ost_nodsh && skip "remote OST with nodsh"
12896
12897         reset_async
12898
12899         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12900         set_nodes_failloc "$(osts_nodes)" 0x220
12901
12902         # return -EIO from OST
12903         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12904         RC=$?
12905         set_nodes_failloc "$(osts_nodes)" 0x0
12906         if [[ $RC -eq 0 ]]; then
12907                 error "Must return error due to dropped pages, rc=$RC"
12908         fi
12909
12910         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12911         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12912         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12913         if [[ $LOCKED -ne 0 ]]; then
12914                 error "Locked pages remain in cache, locked=$LOCKED"
12915         fi
12916
12917         # in recoverable error on OST we want resend and stay until it finished
12918         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12919                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12920         fi
12921
12922         rm -f $DIR/$tfile
12923         echo "No pages locked after fsync"
12924
12925         return 0
12926 }
12927 run_test 118j "Simulate unrecoverable OST side error =========="
12928
12929 test_118k()
12930 {
12931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12932         remote_ost_nodsh && skip "remote OSTs with nodsh"
12933
12934         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12935         set_nodes_failloc "$(osts_nodes)" 0x20e
12936         test_mkdir $DIR/$tdir
12937
12938         for ((i=0;i<10;i++)); do
12939                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12940                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12941                 SLEEPPID=$!
12942                 sleep 0.500s
12943                 kill $SLEEPPID
12944                 wait $SLEEPPID
12945         done
12946
12947         set_nodes_failloc "$(osts_nodes)" 0
12948         rm -rf $DIR/$tdir
12949 }
12950 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12951
12952 test_118l() # LU-646
12953 {
12954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12955
12956         test_mkdir $DIR/$tdir
12957         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12958         rm -rf $DIR/$tdir
12959 }
12960 run_test 118l "fsync dir"
12961
12962 test_118m() # LU-3066
12963 {
12964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12965
12966         test_mkdir $DIR/$tdir
12967         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12968         rm -rf $DIR/$tdir
12969 }
12970 run_test 118m "fdatasync dir ========="
12971
12972 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12973
12974 test_118n()
12975 {
12976         local begin
12977         local end
12978
12979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12980         remote_ost_nodsh && skip "remote OSTs with nodsh"
12981
12982         # Sleep to avoid a cached response.
12983         #define OBD_STATFS_CACHE_SECONDS 1
12984         sleep 2
12985
12986         # Inject a 10 second delay in the OST_STATFS handler.
12987         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12988         set_nodes_failloc "$(osts_nodes)" 0x242
12989
12990         begin=$SECONDS
12991         stat --file-system $MOUNT > /dev/null
12992         end=$SECONDS
12993
12994         set_nodes_failloc "$(osts_nodes)" 0
12995
12996         if ((end - begin > 20)); then
12997             error "statfs took $((end - begin)) seconds, expected 10"
12998         fi
12999 }
13000 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13001
13002 test_119a() # bug 11737
13003 {
13004         BSIZE=$((512 * 1024))
13005         directio write $DIR/$tfile 0 1 $BSIZE
13006         # We ask to read two blocks, which is more than a file size.
13007         # directio will indicate an error when requested and actual
13008         # sizes aren't equeal (a normal situation in this case) and
13009         # print actual read amount.
13010         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13011         if [ "$NOB" != "$BSIZE" ]; then
13012                 error "read $NOB bytes instead of $BSIZE"
13013         fi
13014         rm -f $DIR/$tfile
13015 }
13016 run_test 119a "Short directIO read must return actual read amount"
13017
13018 test_119b() # bug 11737
13019 {
13020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13021
13022         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13023         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13024         sync
13025         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13026                 error "direct read failed"
13027         rm -f $DIR/$tfile
13028 }
13029 run_test 119b "Sparse directIO read must return actual read amount"
13030
13031 test_119c() # bug 13099
13032 {
13033         BSIZE=1048576
13034         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13035         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13036         rm -f $DIR/$tfile
13037 }
13038 run_test 119c "Testing for direct read hitting hole"
13039
13040 test_119d() # bug 15950
13041 {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043
13044         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13045         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13046         BSIZE=1048576
13047         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13048         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13049         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13050         lctl set_param fail_loc=0x40d
13051         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13052         pid_dio=$!
13053         sleep 1
13054         cat $DIR/$tfile > /dev/null &
13055         lctl set_param fail_loc=0
13056         pid_reads=$!
13057         wait $pid_dio
13058         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13059         sleep 2
13060         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13061         error "the read rpcs have not completed in 2s"
13062         rm -f $DIR/$tfile
13063         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13064 }
13065 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13066
13067 test_120a() {
13068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13069         remote_mds_nodsh && skip "remote MDS with nodsh"
13070         test_mkdir -i0 -c1 $DIR/$tdir
13071         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13072                 skip_env "no early lock cancel on server"
13073
13074         lru_resize_disable mdc
13075         lru_resize_disable osc
13076         cancel_lru_locks mdc
13077         # asynchronous object destroy at MDT could cause bl ast to client
13078         cancel_lru_locks osc
13079
13080         stat $DIR/$tdir > /dev/null
13081         can1=$(do_facet mds1 \
13082                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13083                awk '/ldlm_cancel/ {print $2}')
13084         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13085                awk '/ldlm_bl_callback/ {print $2}')
13086         test_mkdir -i0 -c1 $DIR/$tdir/d1
13087         can2=$(do_facet mds1 \
13088                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13089                awk '/ldlm_cancel/ {print $2}')
13090         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13091                awk '/ldlm_bl_callback/ {print $2}')
13092         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13093         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13094         lru_resize_enable mdc
13095         lru_resize_enable osc
13096 }
13097 run_test 120a "Early Lock Cancel: mkdir test"
13098
13099 test_120b() {
13100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13101         remote_mds_nodsh && skip "remote MDS with nodsh"
13102         test_mkdir $DIR/$tdir
13103         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13104                 skip_env "no early lock cancel on server"
13105
13106         lru_resize_disable mdc
13107         lru_resize_disable osc
13108         cancel_lru_locks mdc
13109         stat $DIR/$tdir > /dev/null
13110         can1=$(do_facet $SINGLEMDS \
13111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13112                awk '/ldlm_cancel/ {print $2}')
13113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13114                awk '/ldlm_bl_callback/ {print $2}')
13115         touch $DIR/$tdir/f1
13116         can2=$(do_facet $SINGLEMDS \
13117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13118                awk '/ldlm_cancel/ {print $2}')
13119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13120                awk '/ldlm_bl_callback/ {print $2}')
13121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13123         lru_resize_enable mdc
13124         lru_resize_enable osc
13125 }
13126 run_test 120b "Early Lock Cancel: create test"
13127
13128 test_120c() {
13129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13130         remote_mds_nodsh && skip "remote MDS with nodsh"
13131         test_mkdir -i0 -c1 $DIR/$tdir
13132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13133                 skip "no early lock cancel on server"
13134
13135         lru_resize_disable mdc
13136         lru_resize_disable osc
13137         test_mkdir -i0 -c1 $DIR/$tdir/d1
13138         test_mkdir -i0 -c1 $DIR/$tdir/d2
13139         touch $DIR/$tdir/d1/f1
13140         cancel_lru_locks mdc
13141         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13142         can1=$(do_facet mds1 \
13143                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13144                awk '/ldlm_cancel/ {print $2}')
13145         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13146                awk '/ldlm_bl_callback/ {print $2}')
13147         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13148         can2=$(do_facet mds1 \
13149                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13150                awk '/ldlm_cancel/ {print $2}')
13151         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13152                awk '/ldlm_bl_callback/ {print $2}')
13153         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13154         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13155         lru_resize_enable mdc
13156         lru_resize_enable osc
13157 }
13158 run_test 120c "Early Lock Cancel: link test"
13159
13160 test_120d() {
13161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13162         remote_mds_nodsh && skip "remote MDS with nodsh"
13163         test_mkdir -i0 -c1 $DIR/$tdir
13164         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13165                 skip_env "no early lock cancel on server"
13166
13167         lru_resize_disable mdc
13168         lru_resize_disable osc
13169         touch $DIR/$tdir
13170         cancel_lru_locks mdc
13171         stat $DIR/$tdir > /dev/null
13172         can1=$(do_facet mds1 \
13173                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13174                awk '/ldlm_cancel/ {print $2}')
13175         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13176                awk '/ldlm_bl_callback/ {print $2}')
13177         chmod a+x $DIR/$tdir
13178         can2=$(do_facet mds1 \
13179                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13180                awk '/ldlm_cancel/ {print $2}')
13181         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13182                awk '/ldlm_bl_callback/ {print $2}')
13183         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13184         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13185         lru_resize_enable mdc
13186         lru_resize_enable osc
13187 }
13188 run_test 120d "Early Lock Cancel: setattr test"
13189
13190 test_120e() {
13191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13192         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13193                 skip_env "no early lock cancel on server"
13194         remote_mds_nodsh && skip "remote MDS with nodsh"
13195
13196         local dlmtrace_set=false
13197
13198         test_mkdir -i0 -c1 $DIR/$tdir
13199         lru_resize_disable mdc
13200         lru_resize_disable osc
13201         ! $LCTL get_param debug | grep -q dlmtrace &&
13202                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13203         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13204         cancel_lru_locks mdc
13205         cancel_lru_locks osc
13206         dd if=$DIR/$tdir/f1 of=/dev/null
13207         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13208         # XXX client can not do early lock cancel of OST lock
13209         # during unlink (LU-4206), so cancel osc lock now.
13210         sleep 2
13211         cancel_lru_locks osc
13212         can1=$(do_facet mds1 \
13213                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13214                awk '/ldlm_cancel/ {print $2}')
13215         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13216                awk '/ldlm_bl_callback/ {print $2}')
13217         unlink $DIR/$tdir/f1
13218         sleep 5
13219         can2=$(do_facet mds1 \
13220                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13221                awk '/ldlm_cancel/ {print $2}')
13222         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13223                awk '/ldlm_bl_callback/ {print $2}')
13224         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13225                 $LCTL dk $TMP/cancel.debug.txt
13226         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13227                 $LCTL dk $TMP/blocking.debug.txt
13228         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13229         lru_resize_enable mdc
13230         lru_resize_enable osc
13231 }
13232 run_test 120e "Early Lock Cancel: unlink test"
13233
13234 test_120f() {
13235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13236         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13237                 skip_env "no early lock cancel on server"
13238         remote_mds_nodsh && skip "remote MDS with nodsh"
13239
13240         test_mkdir -i0 -c1 $DIR/$tdir
13241         lru_resize_disable mdc
13242         lru_resize_disable osc
13243         test_mkdir -i0 -c1 $DIR/$tdir/d1
13244         test_mkdir -i0 -c1 $DIR/$tdir/d2
13245         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13246         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13247         cancel_lru_locks mdc
13248         cancel_lru_locks osc
13249         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13250         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13251         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13252         # XXX client can not do early lock cancel of OST lock
13253         # during rename (LU-4206), so cancel osc lock now.
13254         sleep 2
13255         cancel_lru_locks osc
13256         can1=$(do_facet mds1 \
13257                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13258                awk '/ldlm_cancel/ {print $2}')
13259         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13260                awk '/ldlm_bl_callback/ {print $2}')
13261         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13262         sleep 5
13263         can2=$(do_facet mds1 \
13264                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13265                awk '/ldlm_cancel/ {print $2}')
13266         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13267                awk '/ldlm_bl_callback/ {print $2}')
13268         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13269         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13270         lru_resize_enable mdc
13271         lru_resize_enable osc
13272 }
13273 run_test 120f "Early Lock Cancel: rename test"
13274
13275 test_120g() {
13276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13277         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13278                 skip_env "no early lock cancel on server"
13279         remote_mds_nodsh && skip "remote MDS with nodsh"
13280
13281         lru_resize_disable mdc
13282         lru_resize_disable osc
13283         count=10000
13284         echo create $count files
13285         test_mkdir $DIR/$tdir
13286         cancel_lru_locks mdc
13287         cancel_lru_locks osc
13288         t0=$(date +%s)
13289
13290         can0=$(do_facet $SINGLEMDS \
13291                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13292                awk '/ldlm_cancel/ {print $2}')
13293         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13294                awk '/ldlm_bl_callback/ {print $2}')
13295         createmany -o $DIR/$tdir/f $count
13296         sync
13297         can1=$(do_facet $SINGLEMDS \
13298                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13299                awk '/ldlm_cancel/ {print $2}')
13300         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13301                awk '/ldlm_bl_callback/ {print $2}')
13302         t1=$(date +%s)
13303         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13304         echo rm $count files
13305         rm -r $DIR/$tdir
13306         sync
13307         can2=$(do_facet $SINGLEMDS \
13308                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13309                awk '/ldlm_cancel/ {print $2}')
13310         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13311                awk '/ldlm_bl_callback/ {print $2}')
13312         t2=$(date +%s)
13313         echo total: $count removes in $((t2-t1))
13314         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13315         sleep 2
13316         # wait for commitment of removal
13317         lru_resize_enable mdc
13318         lru_resize_enable osc
13319 }
13320 run_test 120g "Early Lock Cancel: performance test"
13321
13322 test_121() { #bug #10589
13323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13324
13325         rm -rf $DIR/$tfile
13326         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13327 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13328         lctl set_param fail_loc=0x310
13329         cancel_lru_locks osc > /dev/null
13330         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13331         lctl set_param fail_loc=0
13332         [[ $reads -eq $writes ]] ||
13333                 error "read $reads blocks, must be $writes blocks"
13334 }
13335 run_test 121 "read cancel race ========="
13336
13337 test_123a_base() { # was test 123, statahead(bug 11401)
13338         local lsx="$1"
13339
13340         SLOWOK=0
13341         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13342                 log "testing UP system. Performance may be lower than expected."
13343                 SLOWOK=1
13344         fi
13345         running_in_vm && SLOWOK=1
13346
13347         rm -rf $DIR/$tdir
13348         test_mkdir $DIR/$tdir
13349         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13350         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13351         MULT=10
13352         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13353                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13354
13355                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13356                 lctl set_param -n llite.*.statahead_max 0
13357                 lctl get_param llite.*.statahead_max
13358                 cancel_lru_locks mdc
13359                 cancel_lru_locks osc
13360                 stime=$(date +%s)
13361                 time $lsx $DIR/$tdir | wc -l
13362                 etime=$(date +%s)
13363                 delta=$((etime - stime))
13364                 log "$lsx $i files without statahead: $delta sec"
13365                 lctl set_param llite.*.statahead_max=$max
13366
13367                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13368                          awk '/statahead.wrong:/ { print $NF }')
13369                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13370                 cancel_lru_locks mdc
13371                 cancel_lru_locks osc
13372                 stime=$(date +%s)
13373                 time $lsx $DIR/$tdir | wc -l
13374                 etime=$(date +%s)
13375                 delta_sa=$((etime - stime))
13376                 log "$lsx $i files with statahead: $delta_sa sec"
13377                 lctl get_param -n llite.*.statahead_stats
13378                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13379                          awk '/statahead.wrong:/ { print $NF }')
13380
13381                 [[ $swrong -lt $ewrong ]] &&
13382                         log "statahead was stopped, maybe too many locks held!"
13383                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13384
13385                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13386                         max=$(lctl get_param -n llite.*.statahead_max |
13387                                 head -n 1)
13388                         lctl set_param -n llite.*.statahead_max 0
13389                         lctl get_param llite.*.statahead_max
13390                         cancel_lru_locks mdc
13391                         cancel_lru_locks osc
13392                         stime=$(date +%s)
13393                         time $lsx $DIR/$tdir | wc -l
13394                         etime=$(date +%s)
13395                         delta=$((etime - stime))
13396                         log "$lsx $i files again without statahead: $delta sec"
13397                         lctl set_param llite.*.statahead_max=$max
13398                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13399                                 if [ $SLOWOK -eq 0 ]; then
13400                                         error "$lsx $i files is slower with statahead!"
13401                                 else
13402                                         log "$lsx $i files is slower with statahead!"
13403                                 fi
13404                                 break
13405                         fi
13406                 fi
13407
13408                 [ $delta -gt 20 ] && break
13409                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13410                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13411         done
13412         log "$lsx done"
13413
13414         stime=$(date +%s)
13415         rm -r $DIR/$tdir
13416         sync
13417         etime=$(date +%s)
13418         delta=$((etime - stime))
13419         log "rm -r $DIR/$tdir/: $delta seconds"
13420         log "rm done"
13421         lctl get_param -n llite.*.statahead_stats
13422 }
13423
13424 test_123aa() {
13425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13426
13427         test_123a_base "ls -l"
13428 }
13429 run_test 123aa "verify statahead work"
13430
13431 test_123ab() {
13432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13433
13434         statx_supported || skip_env "Test must be statx() syscall supported"
13435
13436         test_123a_base "$STATX -l"
13437 }
13438 run_test 123ab "verify statahead work by using statx"
13439
13440 test_123ac() {
13441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13442
13443         statx_supported || skip_env "Test must be statx() syscall supported"
13444
13445         local rpcs_before
13446         local rpcs_after
13447         local agl_before
13448         local agl_after
13449
13450         cancel_lru_locks $OSC
13451         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13452         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13453                      awk '/agl.total:/ { print $NF }')
13454         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13455         test_123a_base "$STATX --cached=always -D"
13456         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13457                     awk '/agl.total:/ { print $NF }')
13458         [ $agl_before -eq $agl_after ] ||
13459                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13460         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13461         [ $rpcs_after -eq $rpcs_before ] ||
13462                 error "$STATX should not send glimpse RPCs to $OSC"
13463 }
13464 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13465
13466 test_123b () { # statahead(bug 15027)
13467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13468
13469         test_mkdir $DIR/$tdir
13470         createmany -o $DIR/$tdir/$tfile-%d 1000
13471
13472         cancel_lru_locks mdc
13473         cancel_lru_locks osc
13474
13475 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13476         lctl set_param fail_loc=0x80000803
13477         ls -lR $DIR/$tdir > /dev/null
13478         log "ls done"
13479         lctl set_param fail_loc=0x0
13480         lctl get_param -n llite.*.statahead_stats
13481         rm -r $DIR/$tdir
13482         sync
13483
13484 }
13485 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13486
13487 test_123c() {
13488         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13489
13490         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13491         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13492         touch $DIR/$tdir.1/{1..3}
13493         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13494
13495         remount_client $MOUNT
13496
13497         $MULTIOP $DIR/$tdir.0 Q
13498
13499         # let statahead to complete
13500         ls -l $DIR/$tdir.0 > /dev/null
13501
13502         testid=$(echo $TESTNAME | tr '_' ' ')
13503         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13504                 error "statahead warning" || true
13505 }
13506 run_test 123c "Can not initialize inode warning on DNE statahead"
13507
13508 test_123d() {
13509         local num=100
13510         local swrong
13511         local ewrong
13512
13513         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13514         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13515                 error "setdirstripe $DIR/$tdir failed"
13516         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13517         remount_client $MOUNT
13518         $LCTL get_param llite.*.statahead_max
13519         $LCTL set_param llite.*.statahead_stats=0 ||
13520                 error "clear statahead_stats failed"
13521         swrong=$(lctl get_param -n llite.*.statahead_stats |
13522                  awk '/statahead.wrong:/ { print $NF }')
13523         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13524         # wait for statahead thread finished to update hit/miss stats.
13525         sleep 1
13526         $LCTL get_param -n llite.*.statahead_stats
13527         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13528                  awk '/statahead.wrong:/ { print $NF }')
13529         (( $swrong == $ewrong )) ||
13530                 log "statahead was stopped, maybe too many locks held!"
13531 }
13532 run_test 123d "Statahead on striped directories works correctly"
13533
13534 test_124a() {
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13537                 skip_env "no lru resize on server"
13538
13539         local NR=2000
13540
13541         test_mkdir $DIR/$tdir
13542
13543         log "create $NR files at $DIR/$tdir"
13544         createmany -o $DIR/$tdir/f $NR ||
13545                 error "failed to create $NR files in $DIR/$tdir"
13546
13547         cancel_lru_locks mdc
13548         ls -l $DIR/$tdir > /dev/null
13549
13550         local NSDIR=""
13551         local LRU_SIZE=0
13552         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13553                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13554                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13555                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13556                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13557                         log "NSDIR=$NSDIR"
13558                         log "NS=$(basename $NSDIR)"
13559                         break
13560                 fi
13561         done
13562
13563         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13564                 skip "Not enough cached locks created!"
13565         fi
13566         log "LRU=$LRU_SIZE"
13567
13568         local SLEEP=30
13569
13570         # We know that lru resize allows one client to hold $LIMIT locks
13571         # for 10h. After that locks begin to be killed by client.
13572         local MAX_HRS=10
13573         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13574         log "LIMIT=$LIMIT"
13575         if [ $LIMIT -lt $LRU_SIZE ]; then
13576                 skip "Limit is too small $LIMIT"
13577         fi
13578
13579         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13580         # killing locks. Some time was spent for creating locks. This means
13581         # that up to the moment of sleep finish we must have killed some of
13582         # them (10-100 locks). This depends on how fast ther were created.
13583         # Many of them were touched in almost the same moment and thus will
13584         # be killed in groups.
13585         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13586
13587         # Use $LRU_SIZE_B here to take into account real number of locks
13588         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13589         local LRU_SIZE_B=$LRU_SIZE
13590         log "LVF=$LVF"
13591         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13592         log "OLD_LVF=$OLD_LVF"
13593         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13594
13595         # Let's make sure that we really have some margin. Client checks
13596         # cached locks every 10 sec.
13597         SLEEP=$((SLEEP+20))
13598         log "Sleep ${SLEEP} sec"
13599         local SEC=0
13600         while ((SEC<$SLEEP)); do
13601                 echo -n "..."
13602                 sleep 5
13603                 SEC=$((SEC+5))
13604                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13605                 echo -n "$LRU_SIZE"
13606         done
13607         echo ""
13608         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13609         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13610
13611         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13612                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13613                 unlinkmany $DIR/$tdir/f $NR
13614                 return
13615         }
13616
13617         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13618         log "unlink $NR files at $DIR/$tdir"
13619         unlinkmany $DIR/$tdir/f $NR
13620 }
13621 run_test 124a "lru resize ======================================="
13622
13623 get_max_pool_limit()
13624 {
13625         local limit=$($LCTL get_param \
13626                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13627         local max=0
13628         for l in $limit; do
13629                 if [[ $l -gt $max ]]; then
13630                         max=$l
13631                 fi
13632         done
13633         echo $max
13634 }
13635
13636 test_124b() {
13637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13638         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13639                 skip_env "no lru resize on server"
13640
13641         LIMIT=$(get_max_pool_limit)
13642
13643         NR=$(($(default_lru_size)*20))
13644         if [[ $NR -gt $LIMIT ]]; then
13645                 log "Limit lock number by $LIMIT locks"
13646                 NR=$LIMIT
13647         fi
13648
13649         IFree=$(mdsrate_inodes_available)
13650         if [ $IFree -lt $NR ]; then
13651                 log "Limit lock number by $IFree inodes"
13652                 NR=$IFree
13653         fi
13654
13655         lru_resize_disable mdc
13656         test_mkdir -p $DIR/$tdir/disable_lru_resize
13657
13658         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13659         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13660         cancel_lru_locks mdc
13661         stime=`date +%s`
13662         PID=""
13663         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13664         PID="$PID $!"
13665         sleep 2
13666         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13667         PID="$PID $!"
13668         sleep 2
13669         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13670         PID="$PID $!"
13671         wait $PID
13672         etime=`date +%s`
13673         nolruresize_delta=$((etime-stime))
13674         log "ls -la time: $nolruresize_delta seconds"
13675         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13676         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13677
13678         lru_resize_enable mdc
13679         test_mkdir -p $DIR/$tdir/enable_lru_resize
13680
13681         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13682         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13683         cancel_lru_locks mdc
13684         stime=`date +%s`
13685         PID=""
13686         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13687         PID="$PID $!"
13688         sleep 2
13689         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13690         PID="$PID $!"
13691         sleep 2
13692         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13693         PID="$PID $!"
13694         wait $PID
13695         etime=`date +%s`
13696         lruresize_delta=$((etime-stime))
13697         log "ls -la time: $lruresize_delta seconds"
13698         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13699
13700         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13701                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13702         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13703                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13704         else
13705                 log "lru resize performs the same with no lru resize"
13706         fi
13707         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13708 }
13709 run_test 124b "lru resize (performance test) ======================="
13710
13711 test_124c() {
13712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13713         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13714                 skip_env "no lru resize on server"
13715
13716         # cache ununsed locks on client
13717         local nr=100
13718         cancel_lru_locks mdc
13719         test_mkdir $DIR/$tdir
13720         createmany -o $DIR/$tdir/f $nr ||
13721                 error "failed to create $nr files in $DIR/$tdir"
13722         ls -l $DIR/$tdir > /dev/null
13723
13724         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13725         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13726         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13727         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13728         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13729
13730         # set lru_max_age to 1 sec
13731         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13732         echo "sleep $((recalc_p * 2)) seconds..."
13733         sleep $((recalc_p * 2))
13734
13735         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13736         # restore lru_max_age
13737         $LCTL set_param -n $nsdir.lru_max_age $max_age
13738         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13739         unlinkmany $DIR/$tdir/f $nr
13740 }
13741 run_test 124c "LRUR cancel very aged locks"
13742
13743 test_124d() {
13744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13745         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13746                 skip_env "no lru resize on server"
13747
13748         # cache ununsed locks on client
13749         local nr=100
13750
13751         lru_resize_disable mdc
13752         stack_trap "lru_resize_enable mdc" EXIT
13753
13754         cancel_lru_locks mdc
13755
13756         # asynchronous object destroy at MDT could cause bl ast to client
13757         test_mkdir $DIR/$tdir
13758         createmany -o $DIR/$tdir/f $nr ||
13759                 error "failed to create $nr files in $DIR/$tdir"
13760         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13761
13762         ls -l $DIR/$tdir > /dev/null
13763
13764         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13765         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13766         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13767         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13768
13769         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13770
13771         # set lru_max_age to 1 sec
13772         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13773         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13774
13775         echo "sleep $((recalc_p * 2)) seconds..."
13776         sleep $((recalc_p * 2))
13777
13778         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13779
13780         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13781 }
13782 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13783
13784 test_125() { # 13358
13785         $LCTL get_param -n llite.*.client_type | grep -q local ||
13786                 skip "must run as local client"
13787         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13788                 skip_env "must have acl enabled"
13789         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13790
13791         test_mkdir $DIR/$tdir
13792         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13793         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
13794                 error "setfacl $DIR/$tdir failed"
13795         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13796 }
13797 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13798
13799 test_126() { # bug 12829/13455
13800         $GSS && skip_env "must run as gss disabled"
13801         $LCTL get_param -n llite.*.client_type | grep -q local ||
13802                 skip "must run as local client"
13803         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13804
13805         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13806         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13807         rm -f $DIR/$tfile
13808         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13809 }
13810 run_test 126 "check that the fsgid provided by the client is taken into account"
13811
13812 test_127a() { # bug 15521
13813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13814         local name count samp unit min max sum sumsq
13815         local tmpfile=$TMP/$tfile.tmp
13816
13817         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13818         echo "stats before reset"
13819         stack_trap "rm -f $tmpfile"
13820         local now=$(date +%s)
13821
13822         $LCTL get_param osc.*.stats | tee $tmpfile
13823
13824         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13825         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13826         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13827         local uptime=$(awk '{ print $1 }' /proc/uptime)
13828
13829         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13830         (( ${snapshot_time%\.*} >= $now - 5 &&
13831            ${snapshot_time%\.*} <= $now + 5 )) ||
13832                 error "snapshot_time=$snapshot_time != now=$now"
13833         # elapsed _should_ be from mount, but at least less than uptime
13834         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
13835                 error "elapsed=$elapsed > uptime=$uptime"
13836         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13837            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13838                 error "elapsed=$elapsed != $snapshot_time - $start_time"
13839
13840         $LCTL set_param osc.*.stats=0
13841         local reset=$(date +%s)
13842         local fsize=$((2048 * 1024))
13843
13844         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13845         cancel_lru_locks osc
13846         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13847
13848         now=$(date +%s)
13849         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
13850         while read name count samp unit min max sum sumsq; do
13851                 [[ "$samp" == "samples" ]] || continue
13852
13853                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13854                 [ ! $min ] && error "Missing min value for $name proc entry"
13855                 eval $name=$count || error "Wrong proc format"
13856
13857                 case $name in
13858                 read_bytes|write_bytes)
13859                         [[ "$unit" =~ "bytes" ]] ||
13860                                 error "unit is not 'bytes': $unit"
13861                         (( $min >= 4096 )) || error "min is too small: $min"
13862                         (( $min <= $fsize )) || error "min is too big: $min"
13863                         (( $max >= 4096 )) || error "max is too small: $max"
13864                         (( $max <= $fsize )) || error "max is too big: $max"
13865                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13866                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13867                                 error "sumsquare is too small: $sumsq"
13868                         (( $sumsq <= $fsize * $fsize )) ||
13869                                 error "sumsquare is too big: $sumsq"
13870                         ;;
13871                 ost_read|ost_write)
13872                         [[ "$unit" =~ "usec" ]] ||
13873                                 error "unit is not 'usec': $unit"
13874                         ;;
13875                 *)      ;;
13876                 esac
13877         done < $tmpfile
13878
13879         #check that we actually got some stats
13880         [ "$read_bytes" ] || error "Missing read_bytes stats"
13881         [ "$write_bytes" ] || error "Missing write_bytes stats"
13882         [ "$read_bytes" != 0 ] || error "no read done"
13883         [ "$write_bytes" != 0 ] || error "no write done"
13884
13885         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
13886         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
13887         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
13888
13889         # snapshot_time should match POSIX epoch time, allow some delta for VMs
13890         (( ${snapshot_time%\.*} >= $now - 5 &&
13891            ${snapshot_time%\.*} <= $now + 5 )) ||
13892                 error "reset snapshot_time=$snapshot_time != now=$now"
13893         # elapsed should be from time of stats reset
13894         (( ${elapsed%\.*} >= $now - $reset - 2 &&
13895            ${elapsed%\.*} <= $now - $reset + 2 )) ||
13896                 error "reset elapsed=$elapsed > $now - $reset"
13897         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
13898            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
13899                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
13900 }
13901 run_test 127a "verify the client stats are sane"
13902
13903 test_127b() { # bug LU-333
13904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13905         local name count samp unit min max sum sumsq
13906
13907         echo "stats before reset"
13908         $LCTL get_param llite.*.stats
13909         $LCTL set_param llite.*.stats=0
13910
13911         # perform 2 reads and writes so MAX is different from SUM.
13912         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13913         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13914         cancel_lru_locks osc
13915         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13916         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13917
13918         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13919         stack_trap "rm -f $TMP/$tfile.tmp"
13920         while read name count samp unit min max sum sumsq; do
13921                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13922                 eval $name=$count || error "Wrong proc format"
13923
13924                 case $name in
13925                 read_bytes|write_bytes)
13926                         [[ "$unit" =~ "bytes" ]] ||
13927                                 error "unit is not 'bytes': $unit"
13928                         (( $count == 2 )) || error "count is not 2: $count"
13929                         (( $min == $PAGE_SIZE )) ||
13930                                 error "min is not $PAGE_SIZE: $min"
13931                         (( $max == $PAGE_SIZE )) ||
13932                                 error "max is not $PAGE_SIZE: $max"
13933                         (( $sum == $PAGE_SIZE * 2 )) ||
13934                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13935                         ;;
13936                 read|write)
13937                         [[ "$unit" =~ "usec" ]] ||
13938                                 error "unit is not 'usec': $unit"
13939                         ;;
13940                 *)      ;;
13941                 esac
13942         done < $TMP/$tfile.tmp
13943
13944         #check that we actually got some stats
13945         [ "$read_bytes" ] || error "Missing read_bytes stats"
13946         [ "$write_bytes" ] || error "Missing write_bytes stats"
13947         [ "$read_bytes" != 0 ] || error "no read done"
13948         [ "$write_bytes" != 0 ] || error "no write done"
13949 }
13950 run_test 127b "verify the llite client stats are sane"
13951
13952 test_127c() { # LU-12394
13953         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13954         local size
13955         local bsize
13956         local reads
13957         local writes
13958         local count
13959
13960         $LCTL set_param llite.*.extents_stats=1
13961         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13962
13963         # Use two stripes so there is enough space in default config
13964         $LFS setstripe -c 2 $DIR/$tfile
13965
13966         # Extent stats start at 0-4K and go in power of two buckets
13967         # LL_HIST_START = 12 --> 2^12 = 4K
13968         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13969         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13970         # small configs
13971         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13972                 do
13973                 # Write and read, 2x each, second time at a non-zero offset
13974                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13975                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13976                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13977                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13978                 rm -f $DIR/$tfile
13979         done
13980
13981         $LCTL get_param llite.*.extents_stats
13982
13983         count=2
13984         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13985                 do
13986                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13987                                 grep -m 1 $bsize)
13988                 reads=$(echo $bucket | awk '{print $5}')
13989                 writes=$(echo $bucket | awk '{print $9}')
13990                 [ "$reads" -eq $count ] ||
13991                         error "$reads reads in < $bsize bucket, expect $count"
13992                 [ "$writes" -eq $count ] ||
13993                         error "$writes writes in < $bsize bucket, expect $count"
13994         done
13995
13996         # Test mmap write and read
13997         $LCTL set_param llite.*.extents_stats=c
13998         size=512
13999         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14000         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14001         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14002
14003         $LCTL get_param llite.*.extents_stats
14004
14005         count=$(((size*1024) / PAGE_SIZE))
14006
14007         bsize=$((2 * PAGE_SIZE / 1024))K
14008
14009         bucket=$($LCTL get_param -n llite.*.extents_stats |
14010                         grep -m 1 $bsize)
14011         reads=$(echo $bucket | awk '{print $5}')
14012         writes=$(echo $bucket | awk '{print $9}')
14013         # mmap writes fault in the page first, creating an additonal read
14014         [ "$reads" -eq $((2 * count)) ] ||
14015                 error "$reads reads in < $bsize bucket, expect $count"
14016         [ "$writes" -eq $count ] ||
14017                 error "$writes writes in < $bsize bucket, expect $count"
14018 }
14019 run_test 127c "test llite extent stats with regular & mmap i/o"
14020
14021 test_128() { # bug 15212
14022         touch $DIR/$tfile
14023         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14024                 find $DIR/$tfile
14025                 find $DIR/$tfile
14026         EOF
14027
14028         result=$(grep error $TMP/$tfile.log)
14029         rm -f $DIR/$tfile $TMP/$tfile.log
14030         [ -z "$result" ] ||
14031                 error "consecutive find's under interactive lfs failed"
14032 }
14033 run_test 128 "interactive lfs for 2 consecutive find's"
14034
14035 set_dir_limits () {
14036         local mntdev
14037         local canondev
14038         local node
14039
14040         local ldproc=/proc/fs/ldiskfs
14041         local facets=$(get_facets MDS)
14042
14043         for facet in ${facets//,/ }; do
14044                 canondev=$(ldiskfs_canon \
14045                            *.$(convert_facet2label $facet).mntdev $facet)
14046                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14047                         ldproc=/sys/fs/ldiskfs
14048                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14049                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14050         done
14051 }
14052
14053 check_mds_dmesg() {
14054         local facets=$(get_facets MDS)
14055         for facet in ${facets//,/ }; do
14056                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14057         done
14058         return 1
14059 }
14060
14061 test_129() {
14062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14063         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14064                 skip "Need MDS version with at least 2.5.56"
14065         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14066                 skip_env "ldiskfs only test"
14067         fi
14068         remote_mds_nodsh && skip "remote MDS with nodsh"
14069
14070         local ENOSPC=28
14071         local has_warning=false
14072
14073         rm -rf $DIR/$tdir
14074         mkdir -p $DIR/$tdir
14075
14076         # block size of mds1
14077         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14078         set_dir_limits $maxsize $((maxsize * 6 / 8))
14079         stack_trap "set_dir_limits 0 0"
14080         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14081         local dirsize=$(stat -c%s "$DIR/$tdir")
14082         local nfiles=0
14083         while (( $dirsize <= $maxsize )); do
14084                 $MCREATE $DIR/$tdir/file_base_$nfiles
14085                 rc=$?
14086                 # check two errors:
14087                 # ENOSPC for ext4 max_dir_size, which has been used since
14088                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14089                 if (( rc == ENOSPC )); then
14090                         set_dir_limits 0 0
14091                         echo "rc=$rc returned as expected after $nfiles files"
14092
14093                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14094                                 error "create failed w/o dir size limit"
14095
14096                         # messages may be rate limited if test is run repeatedly
14097                         check_mds_dmesg '"is approaching max"' ||
14098                                 echo "warning message should be output"
14099                         check_mds_dmesg '"has reached max"' ||
14100                                 echo "reached message should be output"
14101
14102                         dirsize=$(stat -c%s "$DIR/$tdir")
14103
14104                         [[ $dirsize -ge $maxsize ]] && return 0
14105                         error "dirsize $dirsize < $maxsize after $nfiles files"
14106                 elif (( rc != 0 )); then
14107                         break
14108                 fi
14109                 nfiles=$((nfiles + 1))
14110                 dirsize=$(stat -c%s "$DIR/$tdir")
14111         done
14112
14113         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14114 }
14115 run_test 129 "test directory size limit ========================"
14116
14117 OLDIFS="$IFS"
14118 cleanup_130() {
14119         trap 0
14120         IFS="$OLDIFS"
14121 }
14122
14123 test_130a() {
14124         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14125         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14126
14127         trap cleanup_130 EXIT RETURN
14128
14129         local fm_file=$DIR/$tfile
14130         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14131         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14132                 error "dd failed for $fm_file"
14133
14134         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14135         filefrag -ves $fm_file
14136         local rc=$?
14137         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14138                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14139         (( $rc == 0 )) || error "filefrag $fm_file failed"
14140
14141         filefrag_op=$(filefrag -ve -k $fm_file |
14142                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14143         local lun=$($LFS getstripe -i $fm_file)
14144
14145         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14146         IFS=$'\n'
14147         local tot_len=0
14148         for line in $filefrag_op; do
14149                 local frag_lun=$(echo $line | cut -d: -f5)
14150                 local ext_len=$(echo $line | cut -d: -f4)
14151
14152                 if (( $frag_lun != $lun )); then
14153                         error "FIEMAP on 1-stripe file($fm_file) failed"
14154                         return
14155                 fi
14156                 (( tot_len += ext_len ))
14157         done
14158
14159         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14160                 error "FIEMAP on 1-stripe file($fm_file) failed"
14161                 return
14162         fi
14163
14164         echo "FIEMAP on single striped file succeeded"
14165 }
14166 run_test 130a "FIEMAP (1-stripe file)"
14167
14168 test_130b() {
14169         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14170
14171         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14172         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14173         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14174                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14175
14176         trap cleanup_130 EXIT RETURN
14177
14178         local fm_file=$DIR/$tfile
14179         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14180                 error "setstripe on $fm_file"
14181
14182         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14183                 error "dd failed on $fm_file"
14184
14185         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14186         filefrag_op=$(filefrag -ve -k $fm_file |
14187                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14188
14189         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14190                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14191
14192         IFS=$'\n'
14193         local tot_len=0
14194         local num_luns=1
14195
14196         for line in $filefrag_op; do
14197                 local frag_lun=$(echo $line | cut -d: -f5 |
14198                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14199                 local ext_len=$(echo $line | cut -d: -f4)
14200                 if (( $frag_lun != $last_lun )); then
14201                         if (( tot_len != 1024 )); then
14202                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14203                                 return
14204                         else
14205                                 (( num_luns += 1 ))
14206                                 tot_len=0
14207                         fi
14208                 fi
14209                 (( tot_len += ext_len ))
14210                 last_lun=$frag_lun
14211         done
14212         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14213                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14214                 return
14215         fi
14216
14217         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14218 }
14219 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14220
14221 test_130c() {
14222         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14223
14224         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14225         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14226         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14227                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14228
14229         trap cleanup_130 EXIT RETURN
14230
14231         local fm_file=$DIR/$tfile
14232         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14233
14234         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14235                 error "dd failed on $fm_file"
14236
14237         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14238         filefrag_op=$(filefrag -ve -k $fm_file |
14239                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14240
14241         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14242                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14243
14244         IFS=$'\n'
14245         local tot_len=0
14246         local num_luns=1
14247         for line in $filefrag_op; do
14248                 local frag_lun=$(echo $line | cut -d: -f5 |
14249                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14250                 local ext_len=$(echo $line | cut -d: -f4)
14251                 if (( $frag_lun != $last_lun )); then
14252                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14253                         if (( logical != 512 )); then
14254                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14255                                 return
14256                         fi
14257                         if (( tot_len != 512 )); then
14258                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14259                                 return
14260                         else
14261                                 (( num_luns += 1 ))
14262                                 tot_len=0
14263                         fi
14264                 fi
14265                 (( tot_len += ext_len ))
14266                 last_lun=$frag_lun
14267         done
14268         if (( num_luns != 2 || tot_len != 512 )); then
14269                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14270                 return
14271         fi
14272
14273         echo "FIEMAP on 2-stripe file with hole succeeded"
14274 }
14275 run_test 130c "FIEMAP (2-stripe file with hole)"
14276
14277 test_130d() {
14278         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14279
14280         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14281         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14282         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14283                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14284
14285         trap cleanup_130 EXIT RETURN
14286
14287         local fm_file=$DIR/$tfile
14288         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14289                         error "setstripe on $fm_file"
14290
14291         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14292         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14293                 error "dd failed on $fm_file"
14294
14295         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14296         filefrag_op=$(filefrag -ve -k $fm_file |
14297                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14298
14299         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14300                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14301
14302         IFS=$'\n'
14303         local tot_len=0
14304         local num_luns=1
14305         for line in $filefrag_op; do
14306                 local frag_lun=$(echo $line | cut -d: -f5 |
14307                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14308                 local ext_len=$(echo $line | cut -d: -f4)
14309                 if (( $frag_lun != $last_lun )); then
14310                         if (( tot_len != 1024 )); then
14311                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14312                                 return
14313                         else
14314                                 (( num_luns += 1 ))
14315                                 local tot_len=0
14316                         fi
14317                 fi
14318                 (( tot_len += ext_len ))
14319                 last_lun=$frag_lun
14320         done
14321         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14322                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14323                 return
14324         fi
14325
14326         echo "FIEMAP on N-stripe file succeeded"
14327 }
14328 run_test 130d "FIEMAP (N-stripe file)"
14329
14330 test_130e() {
14331         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14332
14333         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14334         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14335         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14336                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14337
14338         trap cleanup_130 EXIT RETURN
14339
14340         local fm_file=$DIR/$tfile
14341         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14342
14343         local num_blks=512
14344         local expected_len=$(( (num_blks / 2) * 64 ))
14345         for ((i = 0; i < $num_blks; i++)); do
14346                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14347                         conv=notrunc > /dev/null 2>&1
14348         done
14349
14350         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14351         filefrag_op=$(filefrag -ve -k $fm_file |
14352                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14353
14354         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14355
14356         IFS=$'\n'
14357         local tot_len=0
14358         local num_luns=1
14359         for line in $filefrag_op; do
14360                 local frag_lun=$(echo $line | cut -d: -f5)
14361                 local ext_len=$(echo $line | cut -d: -f4)
14362                 if (( $frag_lun != $last_lun )); then
14363                         if (( tot_len != $expected_len )); then
14364                                 error "OST$last_lun $tot_len != $expected_len"
14365                         else
14366                                 (( num_luns += 1 ))
14367                                 tot_len=0
14368                         fi
14369                 fi
14370                 (( tot_len += ext_len ))
14371                 last_lun=$frag_lun
14372         done
14373         if (( num_luns != 2 || tot_len != $expected_len )); then
14374                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14375         fi
14376
14377         echo "FIEMAP with continuation calls succeeded"
14378 }
14379 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14380
14381 test_130f() {
14382         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14383         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14384         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14385                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14386
14387         local fm_file=$DIR/$tfile
14388         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14389                 error "multiop create with lov_delay_create on $fm_file"
14390
14391         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14392         filefrag_extents=$(filefrag -vek $fm_file |
14393                            awk '/extents? found/ { print $2 }')
14394         if (( $filefrag_extents != 0 )); then
14395                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14396         fi
14397
14398         rm -f $fm_file
14399 }
14400 run_test 130f "FIEMAP (unstriped file)"
14401
14402 test_130g() {
14403         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14404                 skip "Need MDS version with at least 2.12.53 for overstriping"
14405         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14406         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14407         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14408                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14409
14410         local file=$DIR/$tfile
14411         local nr=$((OSTCOUNT * 100))
14412
14413         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14414
14415         stack_trap "rm -f $file"
14416         dd if=/dev/zero of=$file count=$nr bs=1M
14417         sync
14418         nr=$($LFS getstripe -c $file)
14419
14420         local extents=$(filefrag -v $file |
14421                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14422
14423         echo "filefrag list $extents extents in file with stripecount $nr"
14424         if (( extents < nr )); then
14425                 $LFS getstripe $file
14426                 filefrag -v $file
14427                 error "filefrag printed $extents < $nr extents"
14428         fi
14429 }
14430 run_test 130g "FIEMAP (overstripe file)"
14431
14432 # Test for writev/readv
14433 test_131a() {
14434         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14435                 error "writev test failed"
14436         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14437                 error "readv failed"
14438         rm -f $DIR/$tfile
14439 }
14440 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14441
14442 test_131b() {
14443         local fsize=$((524288 + 1048576 + 1572864))
14444         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14445                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14446                         error "append writev test failed"
14447
14448         ((fsize += 1572864 + 1048576))
14449         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14450                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14451                         error "append writev test failed"
14452         rm -f $DIR/$tfile
14453 }
14454 run_test 131b "test append writev"
14455
14456 test_131c() {
14457         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14458         error "NOT PASS"
14459 }
14460 run_test 131c "test read/write on file w/o objects"
14461
14462 test_131d() {
14463         rwv -f $DIR/$tfile -w -n 1 1572864
14464         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14465         if [ "$NOB" != 1572864 ]; then
14466                 error "Short read filed: read $NOB bytes instead of 1572864"
14467         fi
14468         rm -f $DIR/$tfile
14469 }
14470 run_test 131d "test short read"
14471
14472 test_131e() {
14473         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14474         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14475         error "read hitting hole failed"
14476         rm -f $DIR/$tfile
14477 }
14478 run_test 131e "test read hitting hole"
14479
14480 check_stats() {
14481         local facet=$1
14482         local op=$2
14483         local want=${3:-0}
14484         local res
14485
14486         # open             11 samples [usecs] 468 4793 13658 35791898
14487         case $facet in
14488         mds*) res=($(do_facet $facet \
14489                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14490                  ;;
14491         ost*) res=($(do_facet $facet \
14492                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14493                  ;;
14494         *) error "Wrong facet '$facet'" ;;
14495         esac
14496         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14497         # if $want is zero, it means any stat increment is ok.
14498         if (( $want > 0 )); then
14499                 local count=${res[1]}
14500
14501                 if (( $count != $want )); then
14502                         if [[ $facet =~ "mds" ]]; then
14503                                 do_nodes $(comma_list $(mdts_nodes)) \
14504                                         $LCTL get_param mdt.*.md_stats
14505                         else
14506                                 do_nodes $(comma_list $(osts-nodes)) \
14507                                         $LCTL get_param obdfilter.*.stats
14508                         fi
14509                         error "The $op counter on $facet is $count, not $want"
14510                 fi
14511         fi
14512 }
14513
14514 test_133a() {
14515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14516         remote_ost_nodsh && skip "remote OST with nodsh"
14517         remote_mds_nodsh && skip "remote MDS with nodsh"
14518         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14519                 skip_env "MDS doesn't support rename stats"
14520
14521         local testdir=$DIR/${tdir}/stats_testdir
14522
14523         mkdir -p $DIR/${tdir}
14524
14525         # clear stats.
14526         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14527         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14528
14529         # verify mdt stats first.
14530         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14531         check_stats $SINGLEMDS "mkdir" 1
14532
14533         # clear "open" from "lfs mkdir" above
14534         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14535         touch ${testdir}/${tfile} || error "touch failed"
14536         check_stats $SINGLEMDS "open" 1
14537         check_stats $SINGLEMDS "close" 1
14538         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14539                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14540                 check_stats $SINGLEMDS "mknod" 2
14541         }
14542         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14543         check_stats $SINGLEMDS "unlink" 1
14544         rm -f ${testdir}/${tfile} || error "file remove failed"
14545         check_stats $SINGLEMDS "unlink" 2
14546
14547         # remove working dir and check mdt stats again.
14548         rmdir ${testdir} || error "rmdir failed"
14549         check_stats $SINGLEMDS "rmdir" 1
14550
14551         local testdir1=$DIR/${tdir}/stats_testdir1
14552         mkdir_on_mdt0 -p ${testdir}
14553         mkdir_on_mdt0 -p ${testdir1}
14554         touch ${testdir1}/test1
14555         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14556         check_stats $SINGLEMDS "crossdir_rename" 1
14557
14558         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14559         check_stats $SINGLEMDS "samedir_rename" 1
14560
14561         rm -rf $DIR/${tdir}
14562 }
14563 run_test 133a "Verifying MDT stats ========================================"
14564
14565 test_133b() {
14566         local res
14567
14568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14569         remote_ost_nodsh && skip "remote OST with nodsh"
14570         remote_mds_nodsh && skip "remote MDS with nodsh"
14571
14572         local testdir=$DIR/${tdir}/stats_testdir
14573
14574         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14575         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14576         touch ${testdir}/${tfile} || error "touch failed"
14577         cancel_lru_locks mdc
14578
14579         # clear stats.
14580         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14581         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14582
14583         # extra mdt stats verification.
14584         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14585         check_stats $SINGLEMDS "setattr" 1
14586         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14587         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14588         then            # LU-1740
14589                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14590                 check_stats $SINGLEMDS "getattr" 1
14591         fi
14592         rm -rf $DIR/${tdir}
14593
14594         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14595         # so the check below is not reliable
14596         [ $MDSCOUNT -eq 1 ] || return 0
14597
14598         # Sleep to avoid a cached response.
14599         #define OBD_STATFS_CACHE_SECONDS 1
14600         sleep 2
14601         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14602         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14603         $LFS df || error "lfs failed"
14604         check_stats $SINGLEMDS "statfs" 1
14605
14606         # check aggregated statfs (LU-10018)
14607         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14608                 return 0
14609         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14610                 return 0
14611         sleep 2
14612         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14613         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14614         df $DIR
14615         check_stats $SINGLEMDS "statfs" 1
14616
14617         # We want to check that the client didn't send OST_STATFS to
14618         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14619         # extra care is needed here.
14620         if remote_mds; then
14621                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14622                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14623
14624                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14625                 [ "$res" ] && error "OST got STATFS"
14626         fi
14627
14628         return 0
14629 }
14630 run_test 133b "Verifying extra MDT stats =================================="
14631
14632 test_133c() {
14633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14634         remote_ost_nodsh && skip "remote OST with nodsh"
14635         remote_mds_nodsh && skip "remote MDS with nodsh"
14636
14637         local testdir=$DIR/$tdir/stats_testdir
14638
14639         test_mkdir -p $testdir
14640
14641         # verify obdfilter stats.
14642         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14643         sync
14644         cancel_lru_locks osc
14645         wait_delete_completed
14646
14647         # clear stats.
14648         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14649         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14650
14651         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14652                 error "dd failed"
14653         sync
14654         cancel_lru_locks osc
14655         check_stats ost1 "write" 1
14656
14657         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14658         check_stats ost1 "read" 1
14659
14660         > $testdir/$tfile || error "truncate failed"
14661         check_stats ost1 "punch" 1
14662
14663         rm -f $testdir/$tfile || error "file remove failed"
14664         wait_delete_completed
14665         check_stats ost1 "destroy" 1
14666
14667         rm -rf $DIR/$tdir
14668 }
14669 run_test 133c "Verifying OST stats ========================================"
14670
14671 order_2() {
14672         local value=$1
14673         local orig=$value
14674         local order=1
14675
14676         while [ $value -ge 2 ]; do
14677                 order=$((order*2))
14678                 value=$((value/2))
14679         done
14680
14681         if [ $orig -gt $order ]; then
14682                 order=$((order*2))
14683         fi
14684         echo $order
14685 }
14686
14687 size_in_KMGT() {
14688     local value=$1
14689     local size=('K' 'M' 'G' 'T');
14690     local i=0
14691     local size_string=$value
14692
14693     while [ $value -ge 1024 ]; do
14694         if [ $i -gt 3 ]; then
14695             #T is the biggest unit we get here, if that is bigger,
14696             #just return XXXT
14697             size_string=${value}T
14698             break
14699         fi
14700         value=$((value >> 10))
14701         if [ $value -lt 1024 ]; then
14702             size_string=${value}${size[$i]}
14703             break
14704         fi
14705         i=$((i + 1))
14706     done
14707
14708     echo $size_string
14709 }
14710
14711 get_rename_size() {
14712         local size=$1
14713         local context=${2:-.}
14714         local sample=$(do_facet $SINGLEMDS $LCTL \
14715                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14716                 grep -A1 $context |
14717                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14718         echo $sample
14719 }
14720
14721 test_133d() {
14722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14723         remote_ost_nodsh && skip "remote OST with nodsh"
14724         remote_mds_nodsh && skip "remote MDS with nodsh"
14725         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14726                 skip_env "MDS doesn't support rename stats"
14727
14728         local testdir1=$DIR/${tdir}/stats_testdir1
14729         local testdir2=$DIR/${tdir}/stats_testdir2
14730         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14731
14732         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14733
14734         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14735         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14736
14737         createmany -o $testdir1/test 512 || error "createmany failed"
14738
14739         # check samedir rename size
14740         mv ${testdir1}/test0 ${testdir1}/test_0
14741
14742         local testdir1_size=$(ls -l $DIR/${tdir} |
14743                 awk '/stats_testdir1/ {print $5}')
14744         local testdir2_size=$(ls -l $DIR/${tdir} |
14745                 awk '/stats_testdir2/ {print $5}')
14746
14747         testdir1_size=$(order_2 $testdir1_size)
14748         testdir2_size=$(order_2 $testdir2_size)
14749
14750         testdir1_size=$(size_in_KMGT $testdir1_size)
14751         testdir2_size=$(size_in_KMGT $testdir2_size)
14752
14753         echo "source rename dir size: ${testdir1_size}"
14754         echo "target rename dir size: ${testdir2_size}"
14755
14756         local cmd="do_facet $SINGLEMDS $LCTL "
14757         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14758
14759         eval $cmd || error "$cmd failed"
14760         local samedir=$($cmd | grep 'same_dir')
14761         local same_sample=$(get_rename_size $testdir1_size)
14762         [ -z "$samedir" ] && error "samedir_rename_size count error"
14763         [[ $same_sample -eq 1 ]] ||
14764                 error "samedir_rename_size error $same_sample"
14765         echo "Check same dir rename stats success"
14766
14767         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14768
14769         # check crossdir rename size
14770         mv ${testdir1}/test_0 ${testdir2}/test_0
14771
14772         testdir1_size=$(ls -l $DIR/${tdir} |
14773                 awk '/stats_testdir1/ {print $5}')
14774         testdir2_size=$(ls -l $DIR/${tdir} |
14775                 awk '/stats_testdir2/ {print $5}')
14776
14777         testdir1_size=$(order_2 $testdir1_size)
14778         testdir2_size=$(order_2 $testdir2_size)
14779
14780         testdir1_size=$(size_in_KMGT $testdir1_size)
14781         testdir2_size=$(size_in_KMGT $testdir2_size)
14782
14783         echo "source rename dir size: ${testdir1_size}"
14784         echo "target rename dir size: ${testdir2_size}"
14785
14786         eval $cmd || error "$cmd failed"
14787         local crossdir=$($cmd | grep 'crossdir')
14788         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14789         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14790         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14791         [[ $src_sample -eq 1 ]] ||
14792                 error "crossdir_rename_size error $src_sample"
14793         [[ $tgt_sample -eq 1 ]] ||
14794                 error "crossdir_rename_size error $tgt_sample"
14795         echo "Check cross dir rename stats success"
14796         rm -rf $DIR/${tdir}
14797 }
14798 run_test 133d "Verifying rename_stats ========================================"
14799
14800 test_133e() {
14801         remote_mds_nodsh && skip "remote MDS with nodsh"
14802         remote_ost_nodsh && skip "remote OST with nodsh"
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804
14805         local testdir=$DIR/${tdir}/stats_testdir
14806         local ctr f0 f1 bs=32768 count=42 sum
14807
14808         mkdir -p ${testdir} || error "mkdir failed"
14809
14810         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14811
14812         for ctr in {write,read}_bytes; do
14813                 sync
14814                 cancel_lru_locks osc
14815
14816                 do_facet ost1 $LCTL set_param -n \
14817                         "obdfilter.*.exports.clear=clear"
14818
14819                 if [ $ctr = write_bytes ]; then
14820                         f0=/dev/zero
14821                         f1=${testdir}/${tfile}
14822                 else
14823                         f0=${testdir}/${tfile}
14824                         f1=/dev/null
14825                 fi
14826
14827                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14828                         error "dd failed"
14829                 sync
14830                 cancel_lru_locks osc
14831
14832                 sum=$(do_facet ost1 $LCTL get_param \
14833                         "obdfilter.*.exports.*.stats" |
14834                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14835                                 $1 == ctr { sum += $7 }
14836                                 END { printf("%0.0f", sum) }')
14837
14838                 if ((sum != bs * count)); then
14839                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14840                 fi
14841         done
14842
14843         rm -rf $DIR/${tdir}
14844 }
14845 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14846
14847 test_133f() {
14848         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14849                 skip "too old lustre for get_param -R ($facet_ver)"
14850
14851         # verifying readability.
14852         $LCTL get_param -R '*' &> /dev/null
14853
14854         # Verifing writability with badarea_io.
14855         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14856         local skipped_params='force_lbug|changelog_mask|daemon_file'
14857         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14858                 egrep -v "$skipped_params" |
14859                 xargs -n 1 find $proc_dirs -name |
14860                 xargs -n 1 badarea_io ||
14861                 error "client badarea_io failed"
14862
14863         # remount the FS in case writes/reads /proc break the FS
14864         cleanup || error "failed to unmount"
14865         setup || error "failed to setup"
14866 }
14867 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14868
14869 test_133g() {
14870         remote_mds_nodsh && skip "remote MDS with nodsh"
14871         remote_ost_nodsh && skip "remote OST with nodsh"
14872
14873         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14874         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14875         local facet
14876         for facet in mds1 ost1; do
14877                 local facet_ver=$(lustre_version_code $facet)
14878                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14879                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14880                 else
14881                         log "$facet: too old lustre for get_param -R"
14882                 fi
14883                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14884                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14885                                 tr -d = | egrep -v $skipped_params |
14886                                 xargs -n 1 find $proc_dirs -name |
14887                                 xargs -n 1 badarea_io" ||
14888                                         error "$facet badarea_io failed"
14889                 else
14890                         skip_noexit "$facet: too old lustre for get_param -R"
14891                 fi
14892         done
14893
14894         # remount the FS in case writes/reads /proc break the FS
14895         cleanup || error "failed to unmount"
14896         setup || error "failed to setup"
14897 }
14898 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14899
14900 test_133h() {
14901         remote_mds_nodsh && skip "remote MDS with nodsh"
14902         remote_ost_nodsh && skip "remote OST with nodsh"
14903         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14904                 skip "Need MDS version at least 2.9.54"
14905
14906         local facet
14907         for facet in client mds1 ost1; do
14908                 # Get the list of files that are missing the terminating newline
14909                 local plist=$(do_facet $facet
14910                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14911                 local ent
14912                 for ent in $plist; do
14913                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14914                                 awk -v FS='\v' -v RS='\v\v' \
14915                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14916                                         print FILENAME}'" 2>/dev/null)
14917                         [ -z $missing ] || {
14918                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14919                                 error "file does not end with newline: $facet-$ent"
14920                         }
14921                 done
14922         done
14923 }
14924 run_test 133h "Proc files should end with newlines"
14925
14926 test_134a() {
14927         remote_mds_nodsh && skip "remote MDS with nodsh"
14928         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14929                 skip "Need MDS version at least 2.7.54"
14930
14931         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14932         cancel_lru_locks mdc
14933
14934         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14935         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14936         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14937
14938         local nr=1000
14939         createmany -o $DIR/$tdir/f $nr ||
14940                 error "failed to create $nr files in $DIR/$tdir"
14941         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14942
14943         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14944         do_facet mds1 $LCTL set_param fail_loc=0x327
14945         do_facet mds1 $LCTL set_param fail_val=500
14946         touch $DIR/$tdir/m
14947
14948         echo "sleep 10 seconds ..."
14949         sleep 10
14950         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14951
14952         do_facet mds1 $LCTL set_param fail_loc=0
14953         do_facet mds1 $LCTL set_param fail_val=0
14954         [ $lck_cnt -lt $unused ] ||
14955                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14956
14957         rm $DIR/$tdir/m
14958         unlinkmany $DIR/$tdir/f $nr
14959 }
14960 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14961
14962 test_134b() {
14963         remote_mds_nodsh && skip "remote MDS with nodsh"
14964         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14965                 skip "Need MDS version at least 2.7.54"
14966
14967         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14968         cancel_lru_locks mdc
14969
14970         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14971                         ldlm.lock_reclaim_threshold_mb)
14972         # disable reclaim temporarily
14973         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14974
14975         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14976         do_facet mds1 $LCTL set_param fail_loc=0x328
14977         do_facet mds1 $LCTL set_param fail_val=500
14978
14979         $LCTL set_param debug=+trace
14980
14981         local nr=600
14982         createmany -o $DIR/$tdir/f $nr &
14983         local create_pid=$!
14984
14985         echo "Sleep $TIMEOUT seconds ..."
14986         sleep $TIMEOUT
14987         if ! ps -p $create_pid  > /dev/null 2>&1; then
14988                 do_facet mds1 $LCTL set_param fail_loc=0
14989                 do_facet mds1 $LCTL set_param fail_val=0
14990                 do_facet mds1 $LCTL set_param \
14991                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14992                 error "createmany finished incorrectly!"
14993         fi
14994         do_facet mds1 $LCTL set_param fail_loc=0
14995         do_facet mds1 $LCTL set_param fail_val=0
14996         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14997         wait $create_pid || return 1
14998
14999         unlinkmany $DIR/$tdir/f $nr
15000 }
15001 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15002
15003 test_135() {
15004         remote_mds_nodsh && skip "remote MDS with nodsh"
15005         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15006                 skip "Need MDS version at least 2.13.50"
15007         local fname
15008
15009         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15010
15011 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15012         #set only one record at plain llog
15013         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15014
15015         #fill already existed plain llog each 64767
15016         #wrapping whole catalog
15017         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15018
15019         createmany -o $DIR/$tdir/$tfile_ 64700
15020         for (( i = 0; i < 64700; i = i + 2 ))
15021         do
15022                 rm $DIR/$tdir/$tfile_$i &
15023                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15024                 local pid=$!
15025                 wait $pid
15026         done
15027
15028         #waiting osp synchronization
15029         wait_delete_completed
15030 }
15031 run_test 135 "Race catalog processing"
15032
15033 test_136() {
15034         remote_mds_nodsh && skip "remote MDS with nodsh"
15035         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15036                 skip "Need MDS version at least 2.13.50"
15037         local fname
15038
15039         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15040         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15041         #set only one record at plain llog
15042 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15043         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15044
15045         #fill already existed 2 plain llogs each 64767
15046         #wrapping whole catalog
15047         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15048         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15049         wait_delete_completed
15050
15051         createmany -o $DIR/$tdir/$tfile_ 10
15052         sleep 25
15053
15054         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15055         for (( i = 0; i < 10; i = i + 3 ))
15056         do
15057                 rm $DIR/$tdir/$tfile_$i &
15058                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15059                 local pid=$!
15060                 wait $pid
15061                 sleep 7
15062                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15063         done
15064
15065         #waiting osp synchronization
15066         wait_delete_completed
15067 }
15068 run_test 136 "Race catalog processing 2"
15069
15070 test_140() { #bug-17379
15071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15072
15073         test_mkdir $DIR/$tdir
15074         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15075         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15076
15077         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15078         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15079         local i=0
15080         while i=$((i + 1)); do
15081                 test_mkdir $i
15082                 cd $i || error "Changing to $i"
15083                 ln -s ../stat stat || error "Creating stat symlink"
15084                 # Read the symlink until ELOOP present,
15085                 # not LBUGing the system is considered success,
15086                 # we didn't overrun the stack.
15087                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15088                 if [ $ret -ne 0 ]; then
15089                         if [ $ret -eq 40 ]; then
15090                                 break  # -ELOOP
15091                         else
15092                                 error "Open stat symlink"
15093                                         return
15094                         fi
15095                 fi
15096         done
15097         i=$((i - 1))
15098         echo "The symlink depth = $i"
15099         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15100                 error "Invalid symlink depth"
15101
15102         # Test recursive symlink
15103         ln -s symlink_self symlink_self
15104         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15105         echo "open symlink_self returns $ret"
15106         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15107 }
15108 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15109
15110 test_150a() {
15111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15112
15113         local TF="$TMP/$tfile"
15114
15115         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15116         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15117         cp $TF $DIR/$tfile
15118         cancel_lru_locks $OSC
15119         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15120         remount_client $MOUNT
15121         df -P $MOUNT
15122         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15123
15124         $TRUNCATE $TF 6000
15125         $TRUNCATE $DIR/$tfile 6000
15126         cancel_lru_locks $OSC
15127         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15128
15129         echo "12345" >>$TF
15130         echo "12345" >>$DIR/$tfile
15131         cancel_lru_locks $OSC
15132         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15133
15134         echo "12345" >>$TF
15135         echo "12345" >>$DIR/$tfile
15136         cancel_lru_locks $OSC
15137         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15138 }
15139 run_test 150a "truncate/append tests"
15140
15141 test_150b() {
15142         check_set_fallocate_or_skip
15143         local out
15144
15145         touch $DIR/$tfile
15146         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15147         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15148                 skip_eopnotsupp "$out|check_fallocate failed"
15149 }
15150 run_test 150b "Verify fallocate (prealloc) functionality"
15151
15152 test_150bb() {
15153         check_set_fallocate_or_skip
15154
15155         touch $DIR/$tfile
15156         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15157         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15158         > $DIR/$tfile
15159         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15160         # precomputed md5sum for 20MB of zeroes
15161         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15162         local sum=($(md5sum $DIR/$tfile))
15163
15164         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15165
15166         check_set_fallocate 1
15167
15168         > $DIR/$tfile
15169         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15170         sum=($(md5sum $DIR/$tfile))
15171
15172         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15173 }
15174 run_test 150bb "Verify fallocate modes both zero space"
15175
15176 test_150c() {
15177         check_set_fallocate_or_skip
15178         local striping="-c2"
15179
15180         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15181         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15182         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15183         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15184         local want=$((OSTCOUNT * 1048576))
15185
15186         # Must allocate all requested space, not more than 5% extra
15187         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15188                 error "bytes $bytes is not $want"
15189
15190         rm -f $DIR/$tfile
15191
15192         echo "verify fallocate on PFL file"
15193
15194         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15195
15196         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15197                 error "Create $DIR/$tfile failed"
15198         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15199         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15200         want=$((512 * 1048576))
15201
15202         # Must allocate all requested space, not more than 5% extra
15203         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15204                 error "bytes $bytes is not $want"
15205 }
15206 run_test 150c "Verify fallocate Size and Blocks"
15207
15208 test_150d() {
15209         check_set_fallocate_or_skip
15210         local striping="-c2"
15211
15212         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15213
15214         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15215         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15216                 error "setstripe failed"
15217         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15218         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15219         local want=$((OSTCOUNT * 1048576))
15220
15221         # Must allocate all requested space, not more than 5% extra
15222         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15223                 error "bytes $bytes is not $want"
15224 }
15225 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15226
15227 test_150e() {
15228         check_set_fallocate_or_skip
15229
15230         echo "df before:"
15231         $LFS df
15232         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15233         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15234                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15235
15236         # Find OST with Minimum Size
15237         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15238                        sort -un | head -1)
15239
15240         # Get 100MB per OST of the available space to reduce run time
15241         # else 60% of the available space if we are running SLOW tests
15242         if [ $SLOW == "no" ]; then
15243                 local space=$((1024 * 100 * OSTCOUNT))
15244         else
15245                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15246         fi
15247
15248         fallocate -l${space}k $DIR/$tfile ||
15249                 error "fallocate ${space}k $DIR/$tfile failed"
15250         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15251
15252         # get size immediately after fallocate. This should be correctly
15253         # updated
15254         local size=$(stat -c '%s' $DIR/$tfile)
15255         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15256
15257         # Sleep for a while for statfs to get updated. And not pull from cache.
15258         sleep 2
15259
15260         echo "df after fallocate:"
15261         $LFS df
15262
15263         (( size / 1024 == space )) || error "size $size != requested $space"
15264         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15265                 error "used $used < space $space"
15266
15267         rm $DIR/$tfile || error "rm failed"
15268         sync
15269         wait_delete_completed
15270
15271         echo "df after unlink:"
15272         $LFS df
15273 }
15274 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15275
15276 test_150f() {
15277         local size
15278         local blocks
15279         local want_size_before=20480 # in bytes
15280         local want_blocks_before=40 # 512 sized blocks
15281         local want_blocks_after=24  # 512 sized blocks
15282         local length=$(((want_blocks_before - want_blocks_after) * 512))
15283
15284         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15285                 skip "need at least 2.14.0 for fallocate punch"
15286
15287         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15288                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15289         fi
15290
15291         check_set_fallocate_or_skip
15292         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15293
15294         [[ "x$DOM" == "xyes" ]] &&
15295                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15296
15297         echo "Verify fallocate punch: Range within the file range"
15298         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15299                 error "dd failed for bs 4096 and count 5"
15300
15301         # Call fallocate with punch range which is within the file range
15302         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15303                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15304         # client must see changes immediately after fallocate
15305         size=$(stat -c '%s' $DIR/$tfile)
15306         blocks=$(stat -c '%b' $DIR/$tfile)
15307
15308         # Verify punch worked.
15309         (( blocks == want_blocks_after )) ||
15310                 error "punch failed: blocks $blocks != $want_blocks_after"
15311
15312         (( size == want_size_before )) ||
15313                 error "punch failed: size $size != $want_size_before"
15314
15315         # Verify there is hole in file
15316         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15317         # precomputed md5sum
15318         local expect="4a9a834a2db02452929c0a348273b4aa"
15319
15320         cksum=($(md5sum $DIR/$tfile))
15321         [[ "${cksum[0]}" == "$expect" ]] ||
15322                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15323
15324         # Start second sub-case for fallocate punch.
15325         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15326         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15327                 error "dd failed for bs 4096 and count 5"
15328
15329         # Punch range less than block size will have no change in block count
15330         want_blocks_after=40  # 512 sized blocks
15331
15332         # Punch overlaps two blocks and less than blocksize
15333         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15334                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15335         size=$(stat -c '%s' $DIR/$tfile)
15336         blocks=$(stat -c '%b' $DIR/$tfile)
15337
15338         # Verify punch worked.
15339         (( blocks == want_blocks_after )) ||
15340                 error "punch failed: blocks $blocks != $want_blocks_after"
15341
15342         (( size == want_size_before )) ||
15343                 error "punch failed: size $size != $want_size_before"
15344
15345         # Verify if range is really zero'ed out. We expect Zeros.
15346         # precomputed md5sum
15347         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15348         cksum=($(md5sum $DIR/$tfile))
15349         [[ "${cksum[0]}" == "$expect" ]] ||
15350                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15351 }
15352 run_test 150f "Verify fallocate punch functionality"
15353
15354 test_150g() {
15355         local space
15356         local size
15357         local blocks
15358         local blocks_after
15359         local size_after
15360         local BS=4096 # Block size in bytes
15361
15362         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15363                 skip "need at least 2.14.0 for fallocate punch"
15364
15365         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15366                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15367         fi
15368
15369         check_set_fallocate_or_skip
15370         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15371
15372         if [[ "x$DOM" == "xyes" ]]; then
15373                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15374                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15375         else
15376                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15377                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15378         fi
15379
15380         # Get 100MB per OST of the available space to reduce run time
15381         # else 60% of the available space if we are running SLOW tests
15382         if [ $SLOW == "no" ]; then
15383                 space=$((1024 * 100 * OSTCOUNT))
15384         else
15385                 # Find OST with Minimum Size
15386                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15387                         sort -un | head -1)
15388                 echo "min size OST: $space"
15389                 space=$(((space * 60)/100 * OSTCOUNT))
15390         fi
15391         # space in 1k units, round to 4k blocks
15392         local blkcount=$((space * 1024 / $BS))
15393
15394         echo "Verify fallocate punch: Very large Range"
15395         fallocate -l${space}k $DIR/$tfile ||
15396                 error "fallocate ${space}k $DIR/$tfile failed"
15397         # write 1M at the end, start and in the middle
15398         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15399                 error "dd failed: bs $BS count 256"
15400         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15401                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15402         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15403                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15404
15405         # Gather stats.
15406         size=$(stat -c '%s' $DIR/$tfile)
15407
15408         # gather punch length.
15409         local punch_size=$((size - (BS * 2)))
15410
15411         echo "punch_size = $punch_size"
15412         echo "size - punch_size: $((size - punch_size))"
15413         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15414
15415         # Call fallocate to punch all except 2 blocks. We leave the
15416         # first and the last block
15417         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15418         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15419                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15420
15421         size_after=$(stat -c '%s' $DIR/$tfile)
15422         blocks_after=$(stat -c '%b' $DIR/$tfile)
15423
15424         # Verify punch worked.
15425         # Size should be kept
15426         (( size == size_after )) ||
15427                 error "punch failed: size $size != $size_after"
15428
15429         # two 4k data blocks to remain plus possible 1 extra extent block
15430         (( blocks_after <= ((BS / 512) * 3) )) ||
15431                 error "too many blocks remains: $blocks_after"
15432
15433         # Verify that file has hole between the first and the last blocks
15434         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15435         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15436
15437         echo "Hole at [$hole_start, $hole_end)"
15438         (( hole_start == BS )) ||
15439                 error "no hole at offset $BS after punch"
15440
15441         (( hole_end == BS + punch_size )) ||
15442                 error "data at offset $hole_end < $((BS + punch_size))"
15443 }
15444 run_test 150g "Verify fallocate punch on large range"
15445
15446 test_150h() {
15447         local file=$DIR/$tfile
15448         local size
15449
15450         check_set_fallocate_or_skip
15451         statx_supported || skip_env "Test must be statx() syscall supported"
15452
15453         # fallocate() does not update the size information on the MDT
15454         fallocate -l 16K $file || error "failed to fallocate $file"
15455         cancel_lru_locks $OSC
15456         # STATX with cached-always mode will not send glimpse RPCs to OST,
15457         # it uses the caching attrs on the client side as much as possible.
15458         size=$($STATX --cached=always -c %s $file)
15459         [ $size == 16384 ] ||
15460                 error "size after fallocate() is $size, expected 16384"
15461 }
15462 run_test 150h "Verify extend fallocate updates the file size"
15463
15464 #LU-2902 roc_hit was not able to read all values from lproc
15465 function roc_hit_init() {
15466         local list=$(comma_list $(osts_nodes))
15467         local dir=$DIR/$tdir-check
15468         local file=$dir/$tfile
15469         local BEFORE
15470         local AFTER
15471         local idx
15472
15473         test_mkdir $dir
15474         #use setstripe to do a write to every ost
15475         for i in $(seq 0 $((OSTCOUNT-1))); do
15476                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15477                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15478                 idx=$(printf %04x $i)
15479                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15480                         awk '$1 == "cache_access" {sum += $7}
15481                                 END { printf("%0.0f", sum) }')
15482
15483                 cancel_lru_locks osc
15484                 cat $file >/dev/null
15485
15486                 AFTER=$(get_osd_param $list *OST*$idx stats |
15487                         awk '$1 == "cache_access" {sum += $7}
15488                                 END { printf("%0.0f", sum) }')
15489
15490                 echo BEFORE:$BEFORE AFTER:$AFTER
15491                 if ! let "AFTER - BEFORE == 4"; then
15492                         rm -rf $dir
15493                         error "roc_hit is not safe to use"
15494                 fi
15495                 rm $file
15496         done
15497
15498         rm -rf $dir
15499 }
15500
15501 function roc_hit() {
15502         local list=$(comma_list $(osts_nodes))
15503         echo $(get_osd_param $list '' stats |
15504                 awk '$1 == "cache_hit" {sum += $7}
15505                         END { printf("%0.0f", sum) }')
15506 }
15507
15508 function set_cache() {
15509         local on=1
15510
15511         if [ "$2" == "off" ]; then
15512                 on=0;
15513         fi
15514         local list=$(comma_list $(osts_nodes))
15515         set_osd_param $list '' $1_cache_enable $on
15516
15517         cancel_lru_locks osc
15518 }
15519
15520 test_151() {
15521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15522         remote_ost_nodsh && skip "remote OST with nodsh"
15523
15524         local CPAGES=3
15525         local list=$(comma_list $(osts_nodes))
15526
15527         # check whether obdfilter is cache capable at all
15528         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15529                 skip "not cache-capable obdfilter"
15530         fi
15531
15532         # check cache is enabled on all obdfilters
15533         if get_osd_param $list '' read_cache_enable | grep 0; then
15534                 skip "oss cache is disabled"
15535         fi
15536
15537         set_osd_param $list '' writethrough_cache_enable 1
15538
15539         # check write cache is enabled on all obdfilters
15540         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15541                 skip "oss write cache is NOT enabled"
15542         fi
15543
15544         roc_hit_init
15545
15546         #define OBD_FAIL_OBD_NO_LRU  0x609
15547         do_nodes $list $LCTL set_param fail_loc=0x609
15548
15549         # pages should be in the case right after write
15550         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15551                 error "dd failed"
15552
15553         local BEFORE=$(roc_hit)
15554         cancel_lru_locks osc
15555         cat $DIR/$tfile >/dev/null
15556         local AFTER=$(roc_hit)
15557
15558         do_nodes $list $LCTL set_param fail_loc=0
15559
15560         if ! let "AFTER - BEFORE == CPAGES"; then
15561                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15562         fi
15563
15564         cancel_lru_locks osc
15565         # invalidates OST cache
15566         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15567         set_osd_param $list '' read_cache_enable 0
15568         cat $DIR/$tfile >/dev/null
15569
15570         # now data shouldn't be found in the cache
15571         BEFORE=$(roc_hit)
15572         cancel_lru_locks osc
15573         cat $DIR/$tfile >/dev/null
15574         AFTER=$(roc_hit)
15575         if let "AFTER - BEFORE != 0"; then
15576                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15577         fi
15578
15579         set_osd_param $list '' read_cache_enable 1
15580         rm -f $DIR/$tfile
15581 }
15582 run_test 151 "test cache on oss and controls ==============================="
15583
15584 test_152() {
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586
15587         local TF="$TMP/$tfile"
15588
15589         # simulate ENOMEM during write
15590 #define OBD_FAIL_OST_NOMEM      0x226
15591         lctl set_param fail_loc=0x80000226
15592         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15593         cp $TF $DIR/$tfile
15594         sync || error "sync failed"
15595         lctl set_param fail_loc=0
15596
15597         # discard client's cache
15598         cancel_lru_locks osc
15599
15600         # simulate ENOMEM during read
15601         lctl set_param fail_loc=0x80000226
15602         cmp $TF $DIR/$tfile || error "cmp failed"
15603         lctl set_param fail_loc=0
15604
15605         rm -f $TF
15606 }
15607 run_test 152 "test read/write with enomem ============================"
15608
15609 test_153() {
15610         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15611 }
15612 run_test 153 "test if fdatasync does not crash ======================="
15613
15614 dot_lustre_fid_permission_check() {
15615         local fid=$1
15616         local ffid=$MOUNT/.lustre/fid/$fid
15617         local test_dir=$2
15618
15619         echo "stat fid $fid"
15620         stat $ffid || error "stat $ffid failed."
15621         echo "touch fid $fid"
15622         touch $ffid || error "touch $ffid failed."
15623         echo "write to fid $fid"
15624         cat /etc/hosts > $ffid || error "write $ffid failed."
15625         echo "read fid $fid"
15626         diff /etc/hosts $ffid || error "read $ffid failed."
15627         echo "append write to fid $fid"
15628         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15629         echo "rename fid $fid"
15630         mv $ffid $test_dir/$tfile.1 &&
15631                 error "rename $ffid to $tfile.1 should fail."
15632         touch $test_dir/$tfile.1
15633         mv $test_dir/$tfile.1 $ffid &&
15634                 error "rename $tfile.1 to $ffid should fail."
15635         rm -f $test_dir/$tfile.1
15636         echo "truncate fid $fid"
15637         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15638         echo "link fid $fid"
15639         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15640         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15641                 echo "setfacl fid $fid"
15642                 setfacl -R -m u:$USER0:rwx $ffid ||
15643                         error "setfacl $ffid failed"
15644                 echo "getfacl fid $fid"
15645                 getfacl $ffid || error "getfacl $ffid failed."
15646         fi
15647         echo "unlink fid $fid"
15648         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15649         echo "mknod fid $fid"
15650         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15651
15652         fid=[0xf00000400:0x1:0x0]
15653         ffid=$MOUNT/.lustre/fid/$fid
15654
15655         echo "stat non-exist fid $fid"
15656         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15657         echo "write to non-exist fid $fid"
15658         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15659         echo "link new fid $fid"
15660         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15661
15662         mkdir -p $test_dir/$tdir
15663         touch $test_dir/$tdir/$tfile
15664         fid=$($LFS path2fid $test_dir/$tdir)
15665         rc=$?
15666         [ $rc -ne 0 ] &&
15667                 error "error: could not get fid for $test_dir/$dir/$tfile."
15668
15669         ffid=$MOUNT/.lustre/fid/$fid
15670
15671         echo "ls $fid"
15672         ls $ffid || error "ls $ffid failed."
15673         echo "touch $fid/$tfile.1"
15674         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15675
15676         echo "touch $MOUNT/.lustre/fid/$tfile"
15677         touch $MOUNT/.lustre/fid/$tfile && \
15678                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15679
15680         echo "setxattr to $MOUNT/.lustre/fid"
15681         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15682
15683         echo "listxattr for $MOUNT/.lustre/fid"
15684         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15685
15686         echo "delxattr from $MOUNT/.lustre/fid"
15687         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15688
15689         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15690         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15691                 error "touch invalid fid should fail."
15692
15693         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15694         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15695                 error "touch non-normal fid should fail."
15696
15697         echo "rename $tdir to $MOUNT/.lustre/fid"
15698         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15699                 error "rename to $MOUNT/.lustre/fid should fail."
15700
15701         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15702         then            # LU-3547
15703                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15704                 local new_obf_mode=777
15705
15706                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15707                 chmod $new_obf_mode $DIR/.lustre/fid ||
15708                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15709
15710                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15711                 [ $obf_mode -eq $new_obf_mode ] ||
15712                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15713
15714                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15715                 chmod $old_obf_mode $DIR/.lustre/fid ||
15716                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15717         fi
15718
15719         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15720         fid=$($LFS path2fid $test_dir/$tfile-2)
15721
15722         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15723         then # LU-5424
15724                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15725                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15726                         error "create lov data thru .lustre failed"
15727         fi
15728         echo "cp /etc/passwd $test_dir/$tfile-2"
15729         cp /etc/passwd $test_dir/$tfile-2 ||
15730                 error "copy to $test_dir/$tfile-2 failed."
15731         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15732         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15733                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15734
15735         rm -rf $test_dir/tfile.lnk
15736         rm -rf $test_dir/$tfile-2
15737 }
15738
15739 test_154A() {
15740         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15741                 skip "Need MDS version at least 2.4.1"
15742
15743         local tf=$DIR/$tfile
15744         touch $tf
15745
15746         local fid=$($LFS path2fid $tf)
15747         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15748
15749         # check that we get the same pathname back
15750         local rootpath
15751         local found
15752         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15753                 echo "$rootpath $fid"
15754                 found=$($LFS fid2path $rootpath "$fid")
15755                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15756                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15757         done
15758
15759         # check wrong root path format
15760         rootpath=$MOUNT"_wrong"
15761         found=$($LFS fid2path $rootpath "$fid")
15762         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15763 }
15764 run_test 154A "lfs path2fid and fid2path basic checks"
15765
15766 test_154B() {
15767         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15768                 skip "Need MDS version at least 2.4.1"
15769
15770         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15771         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15772         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15773         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15774
15775         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15776         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15777
15778         # check that we get the same pathname
15779         echo "PFID: $PFID, name: $name"
15780         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15781         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15782         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15783                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15784
15785         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15786 }
15787 run_test 154B "verify the ll_decode_linkea tool"
15788
15789 test_154a() {
15790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15791         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15792         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
15793                 skip "Need MDS version at least 2.2.51"
15794         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15795
15796         cp /etc/hosts $DIR/$tfile
15797
15798         fid=$($LFS path2fid $DIR/$tfile)
15799         rc=$?
15800         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15801
15802         dot_lustre_fid_permission_check "$fid" $DIR ||
15803                 error "dot lustre permission check $fid failed"
15804
15805         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15806
15807         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15808
15809         touch $MOUNT/.lustre/file &&
15810                 error "creation is not allowed under .lustre"
15811
15812         mkdir $MOUNT/.lustre/dir &&
15813                 error "mkdir is not allowed under .lustre"
15814
15815         rm -rf $DIR/$tfile
15816 }
15817 run_test 154a "Open-by-FID"
15818
15819 test_154b() {
15820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15821         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15823         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15824                 skip "Need MDS version at least 2.2.51"
15825
15826         local remote_dir=$DIR/$tdir/remote_dir
15827         local MDTIDX=1
15828         local rc=0
15829
15830         mkdir -p $DIR/$tdir
15831         $LFS mkdir -i $MDTIDX $remote_dir ||
15832                 error "create remote directory failed"
15833
15834         cp /etc/hosts $remote_dir/$tfile
15835
15836         fid=$($LFS path2fid $remote_dir/$tfile)
15837         rc=$?
15838         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15839
15840         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15841                 error "dot lustre permission check $fid failed"
15842         rm -rf $DIR/$tdir
15843 }
15844 run_test 154b "Open-by-FID for remote directory"
15845
15846 test_154c() {
15847         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15848                 skip "Need MDS version at least 2.4.1"
15849
15850         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15851         local FID1=$($LFS path2fid $DIR/$tfile.1)
15852         local FID2=$($LFS path2fid $DIR/$tfile.2)
15853         local FID3=$($LFS path2fid $DIR/$tfile.3)
15854
15855         local N=1
15856         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15857                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15858                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15859                 local want=FID$N
15860                 [ "$FID" = "${!want}" ] ||
15861                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15862                 N=$((N + 1))
15863         done
15864
15865         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15866         do
15867                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15868                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15869                 N=$((N + 1))
15870         done
15871 }
15872 run_test 154c "lfs path2fid and fid2path multiple arguments"
15873
15874 test_154d() {
15875         remote_mds_nodsh && skip "remote MDS with nodsh"
15876         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15877                 skip "Need MDS version at least 2.5.53"
15878
15879         if remote_mds; then
15880                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15881         else
15882                 nid="0@lo"
15883         fi
15884         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15885         local fd
15886         local cmd
15887
15888         rm -f $DIR/$tfile
15889         touch $DIR/$tfile
15890
15891         local fid=$($LFS path2fid $DIR/$tfile)
15892         # Open the file
15893         fd=$(free_fd)
15894         cmd="exec $fd<$DIR/$tfile"
15895         eval $cmd
15896         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15897         echo "$fid_list" | grep "$fid"
15898         rc=$?
15899
15900         cmd="exec $fd>/dev/null"
15901         eval $cmd
15902         if [ $rc -ne 0 ]; then
15903                 error "FID $fid not found in open files list $fid_list"
15904         fi
15905 }
15906 run_test 154d "Verify open file fid"
15907
15908 test_154e()
15909 {
15910         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15911                 skip "Need MDS version at least 2.6.50"
15912
15913         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15914                 error ".lustre returned by readdir"
15915         fi
15916 }
15917 run_test 154e ".lustre is not returned by readdir"
15918
15919 test_154f() {
15920         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15921
15922         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15923         mkdir_on_mdt0 $DIR/$tdir
15924         # test dirs inherit from its stripe
15925         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15926         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15927         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15928         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15929         touch $DIR/f
15930
15931         # get fid of parents
15932         local FID0=$($LFS path2fid $DIR/$tdir)
15933         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15934         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15935         local FID3=$($LFS path2fid $DIR)
15936
15937         # check that path2fid --parents returns expected <parent_fid>/name
15938         # 1) test for a directory (single parent)
15939         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15940         [ "$parent" == "$FID0/foo1" ] ||
15941                 error "expected parent: $FID0/foo1, got: $parent"
15942
15943         # 2) test for a file with nlink > 1 (multiple parents)
15944         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15945         echo "$parent" | grep -F "$FID1/$tfile" ||
15946                 error "$FID1/$tfile not returned in parent list"
15947         echo "$parent" | grep -F "$FID2/link" ||
15948                 error "$FID2/link not returned in parent list"
15949
15950         # 3) get parent by fid
15951         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15952         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15953         echo "$parent" | grep -F "$FID1/$tfile" ||
15954                 error "$FID1/$tfile not returned in parent list (by fid)"
15955         echo "$parent" | grep -F "$FID2/link" ||
15956                 error "$FID2/link not returned in parent list (by fid)"
15957
15958         # 4) test for entry in root directory
15959         parent=$($LFS path2fid --parents $DIR/f)
15960         echo "$parent" | grep -F "$FID3/f" ||
15961                 error "$FID3/f not returned in parent list"
15962
15963         # 5) test it on root directory
15964         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15965                 error "$MOUNT should not have parents"
15966
15967         # enable xattr caching and check that linkea is correctly updated
15968         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15969         save_lustre_params client "llite.*.xattr_cache" > $save
15970         lctl set_param llite.*.xattr_cache 1
15971
15972         # 6.1) linkea update on rename
15973         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15974
15975         # get parents by fid
15976         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15977         # foo1 should no longer be returned in parent list
15978         echo "$parent" | grep -F "$FID1" &&
15979                 error "$FID1 should no longer be in parent list"
15980         # the new path should appear
15981         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15982                 error "$FID2/$tfile.moved is not in parent list"
15983
15984         # 6.2) linkea update on unlink
15985         rm -f $DIR/$tdir/foo2/link
15986         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15987         # foo2/link should no longer be returned in parent list
15988         echo "$parent" | grep -F "$FID2/link" &&
15989                 error "$FID2/link should no longer be in parent list"
15990         true
15991
15992         rm -f $DIR/f
15993         restore_lustre_params < $save
15994         rm -f $save
15995 }
15996 run_test 154f "get parent fids by reading link ea"
15997
15998 test_154g()
15999 {
16000         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16001            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16002                 skip "Need MDS version at least 2.6.92"
16003
16004         mkdir_on_mdt0 $DIR/$tdir
16005         llapi_fid_test -d $DIR/$tdir
16006 }
16007 run_test 154g "various llapi FID tests"
16008
16009 test_155_small_load() {
16010     local temp=$TMP/$tfile
16011     local file=$DIR/$tfile
16012
16013     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16014         error "dd of=$temp bs=6096 count=1 failed"
16015     cp $temp $file
16016     cancel_lru_locks $OSC
16017     cmp $temp $file || error "$temp $file differ"
16018
16019     $TRUNCATE $temp 6000
16020     $TRUNCATE $file 6000
16021     cmp $temp $file || error "$temp $file differ (truncate1)"
16022
16023     echo "12345" >>$temp
16024     echo "12345" >>$file
16025     cmp $temp $file || error "$temp $file differ (append1)"
16026
16027     echo "12345" >>$temp
16028     echo "12345" >>$file
16029     cmp $temp $file || error "$temp $file differ (append2)"
16030
16031     rm -f $temp $file
16032     true
16033 }
16034
16035 test_155_big_load() {
16036         remote_ost_nodsh && skip "remote OST with nodsh"
16037
16038         local temp=$TMP/$tfile
16039         local file=$DIR/$tfile
16040
16041         free_min_max
16042         local cache_size=$(do_facet ost$((MAXI+1)) \
16043                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16044
16045         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16046         # pre-set value
16047         if [ -z "$cache_size" ]; then
16048                 cache_size=256
16049         fi
16050         local large_file_size=$((cache_size * 2))
16051
16052         echo "OSS cache size: $cache_size KB"
16053         echo "Large file size: $large_file_size KB"
16054
16055         [ $MAXV -le $large_file_size ] &&
16056                 skip_env "max available OST size needs > $large_file_size KB"
16057
16058         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16059
16060         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16061                 error "dd of=$temp bs=$large_file_size count=1k failed"
16062         cp $temp $file
16063         ls -lh $temp $file
16064         cancel_lru_locks osc
16065         cmp $temp $file || error "$temp $file differ"
16066
16067         rm -f $temp $file
16068         true
16069 }
16070
16071 save_writethrough() {
16072         local facets=$(get_facets OST)
16073
16074         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16075 }
16076
16077 test_155a() {
16078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16079
16080         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16081
16082         save_writethrough $p
16083
16084         set_cache read on
16085         set_cache writethrough on
16086         test_155_small_load
16087         restore_lustre_params < $p
16088         rm -f $p
16089 }
16090 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16091
16092 test_155b() {
16093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16094
16095         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16096
16097         save_writethrough $p
16098
16099         set_cache read on
16100         set_cache writethrough off
16101         test_155_small_load
16102         restore_lustre_params < $p
16103         rm -f $p
16104 }
16105 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16106
16107 test_155c() {
16108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16109
16110         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16111
16112         save_writethrough $p
16113
16114         set_cache read off
16115         set_cache writethrough on
16116         test_155_small_load
16117         restore_lustre_params < $p
16118         rm -f $p
16119 }
16120 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16121
16122 test_155d() {
16123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16124
16125         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16126
16127         save_writethrough $p
16128
16129         set_cache read off
16130         set_cache writethrough off
16131         test_155_small_load
16132         restore_lustre_params < $p
16133         rm -f $p
16134 }
16135 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16136
16137 test_155e() {
16138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16139
16140         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16141
16142         save_writethrough $p
16143
16144         set_cache read on
16145         set_cache writethrough on
16146         test_155_big_load
16147         restore_lustre_params < $p
16148         rm -f $p
16149 }
16150 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16151
16152 test_155f() {
16153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16154
16155         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16156
16157         save_writethrough $p
16158
16159         set_cache read on
16160         set_cache writethrough off
16161         test_155_big_load
16162         restore_lustre_params < $p
16163         rm -f $p
16164 }
16165 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16166
16167 test_155g() {
16168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16169
16170         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16171
16172         save_writethrough $p
16173
16174         set_cache read off
16175         set_cache writethrough on
16176         test_155_big_load
16177         restore_lustre_params < $p
16178         rm -f $p
16179 }
16180 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16181
16182 test_155h() {
16183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16184
16185         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16186
16187         save_writethrough $p
16188
16189         set_cache read off
16190         set_cache writethrough off
16191         test_155_big_load
16192         restore_lustre_params < $p
16193         rm -f $p
16194 }
16195 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16196
16197 test_156() {
16198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16199         remote_ost_nodsh && skip "remote OST with nodsh"
16200         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16201                 skip "stats not implemented on old servers"
16202         [ "$ost1_FSTYPE" = "zfs" ] &&
16203                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16204
16205         local CPAGES=3
16206         local BEFORE
16207         local AFTER
16208         local file="$DIR/$tfile"
16209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16210
16211         save_writethrough $p
16212         roc_hit_init
16213
16214         log "Turn on read and write cache"
16215         set_cache read on
16216         set_cache writethrough on
16217
16218         log "Write data and read it back."
16219         log "Read should be satisfied from the cache."
16220         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16221         BEFORE=$(roc_hit)
16222         cancel_lru_locks osc
16223         cat $file >/dev/null
16224         AFTER=$(roc_hit)
16225         if ! let "AFTER - BEFORE == CPAGES"; then
16226                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16227         else
16228                 log "cache hits: before: $BEFORE, after: $AFTER"
16229         fi
16230
16231         log "Read again; it should be satisfied from the cache."
16232         BEFORE=$AFTER
16233         cancel_lru_locks osc
16234         cat $file >/dev/null
16235         AFTER=$(roc_hit)
16236         if ! let "AFTER - BEFORE == CPAGES"; then
16237                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16238         else
16239                 log "cache hits:: before: $BEFORE, after: $AFTER"
16240         fi
16241
16242         log "Turn off the read cache and turn on the write cache"
16243         set_cache read off
16244         set_cache writethrough on
16245
16246         log "Read again; it should be satisfied from the cache."
16247         BEFORE=$(roc_hit)
16248         cancel_lru_locks osc
16249         cat $file >/dev/null
16250         AFTER=$(roc_hit)
16251         if ! let "AFTER - BEFORE == CPAGES"; then
16252                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16253         else
16254                 log "cache hits:: before: $BEFORE, after: $AFTER"
16255         fi
16256
16257         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16258                 # > 2.12.56 uses pagecache if cached
16259                 log "Read again; it should not be satisfied from the cache."
16260                 BEFORE=$AFTER
16261                 cancel_lru_locks osc
16262                 cat $file >/dev/null
16263                 AFTER=$(roc_hit)
16264                 if ! let "AFTER - BEFORE == 0"; then
16265                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16266                 else
16267                         log "cache hits:: before: $BEFORE, after: $AFTER"
16268                 fi
16269         fi
16270
16271         log "Write data and read it back."
16272         log "Read should be satisfied from the cache."
16273         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16274         BEFORE=$(roc_hit)
16275         cancel_lru_locks osc
16276         cat $file >/dev/null
16277         AFTER=$(roc_hit)
16278         if ! let "AFTER - BEFORE == CPAGES"; then
16279                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16280         else
16281                 log "cache hits:: before: $BEFORE, after: $AFTER"
16282         fi
16283
16284         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16285                 # > 2.12.56 uses pagecache if cached
16286                 log "Read again; it should not be satisfied from the cache."
16287                 BEFORE=$AFTER
16288                 cancel_lru_locks osc
16289                 cat $file >/dev/null
16290                 AFTER=$(roc_hit)
16291                 if ! let "AFTER - BEFORE == 0"; then
16292                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16293                 else
16294                         log "cache hits:: before: $BEFORE, after: $AFTER"
16295                 fi
16296         fi
16297
16298         log "Turn off read and write cache"
16299         set_cache read off
16300         set_cache writethrough off
16301
16302         log "Write data and read it back"
16303         log "It should not be satisfied from the cache."
16304         rm -f $file
16305         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16306         cancel_lru_locks osc
16307         BEFORE=$(roc_hit)
16308         cat $file >/dev/null
16309         AFTER=$(roc_hit)
16310         if ! let "AFTER - BEFORE == 0"; then
16311                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16312         else
16313                 log "cache hits:: before: $BEFORE, after: $AFTER"
16314         fi
16315
16316         log "Turn on the read cache and turn off the write cache"
16317         set_cache read on
16318         set_cache writethrough off
16319
16320         log "Write data and read it back"
16321         log "It should not be satisfied from the cache."
16322         rm -f $file
16323         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16324         BEFORE=$(roc_hit)
16325         cancel_lru_locks osc
16326         cat $file >/dev/null
16327         AFTER=$(roc_hit)
16328         if ! let "AFTER - BEFORE == 0"; then
16329                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16330         else
16331                 log "cache hits:: before: $BEFORE, after: $AFTER"
16332         fi
16333
16334         log "Read again; it should be satisfied from the cache."
16335         BEFORE=$(roc_hit)
16336         cancel_lru_locks osc
16337         cat $file >/dev/null
16338         AFTER=$(roc_hit)
16339         if ! let "AFTER - BEFORE == CPAGES"; then
16340                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16341         else
16342                 log "cache hits:: before: $BEFORE, after: $AFTER"
16343         fi
16344
16345         restore_lustre_params < $p
16346         rm -f $p $file
16347 }
16348 run_test 156 "Verification of tunables"
16349
16350 test_160a() {
16351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16352         remote_mds_nodsh && skip "remote MDS with nodsh"
16353         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16354                 skip "Need MDS version at least 2.2.0"
16355
16356         changelog_register || error "changelog_register failed"
16357         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16358         changelog_users $SINGLEMDS | grep -q $cl_user ||
16359                 error "User $cl_user not found in changelog_users"
16360
16361         mkdir_on_mdt0 $DIR/$tdir
16362
16363         # change something
16364         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16365         changelog_clear 0 || error "changelog_clear failed"
16366         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16367         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16368         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16369         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16370         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16371         rm $DIR/$tdir/pics/desktop.jpg
16372
16373         echo "verifying changelog mask"
16374         changelog_chmask "-MKDIR"
16375         changelog_chmask "-CLOSE"
16376
16377         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16378         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16379
16380         changelog_chmask "+MKDIR"
16381         changelog_chmask "+CLOSE"
16382
16383         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16384         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16385
16386         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16387         CLOSES=$(changelog_dump | grep -c "CLOSE")
16388         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16389         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16390
16391         # verify contents
16392         echo "verifying target fid"
16393         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16394         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16395         [ "$fidc" == "$fidf" ] ||
16396                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16397         echo "verifying parent fid"
16398         # The FID returned from the Changelog may be the directory shard on
16399         # a different MDT, and not the FID returned by path2fid on the parent.
16400         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16401         # since this is what will matter when recreating this file in the tree.
16402         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16403         local pathp=$($LFS fid2path $MOUNT "$fidp")
16404         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16405                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16406
16407         echo "getting records for $cl_user"
16408         changelog_users $SINGLEMDS
16409         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16410         local nclr=3
16411         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16412                 error "changelog_clear failed"
16413         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16414         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16415         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16416                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16417
16418         local min0_rec=$(changelog_users $SINGLEMDS |
16419                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16420         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16421                           awk '{ print $1; exit; }')
16422
16423         changelog_dump | tail -n 5
16424         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16425         [ $first_rec == $((min0_rec + 1)) ] ||
16426                 error "first index should be $min0_rec + 1 not $first_rec"
16427
16428         # LU-3446 changelog index reset on MDT restart
16429         local cur_rec1=$(changelog_users $SINGLEMDS |
16430                          awk '/^current.index:/ { print $NF }')
16431         changelog_clear 0 ||
16432                 error "clear all changelog records for $cl_user failed"
16433         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16434         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16435                 error "Fail to start $SINGLEMDS"
16436         local cur_rec2=$(changelog_users $SINGLEMDS |
16437                          awk '/^current.index:/ { print $NF }')
16438         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16439         [ $cur_rec1 == $cur_rec2 ] ||
16440                 error "current index should be $cur_rec1 not $cur_rec2"
16441
16442         echo "verifying users from this test are deregistered"
16443         changelog_deregister || error "changelog_deregister failed"
16444         changelog_users $SINGLEMDS | grep -q $cl_user &&
16445                 error "User '$cl_user' still in changelog_users"
16446
16447         # lctl get_param -n mdd.*.changelog_users
16448         # current_index: 144
16449         # ID    index (idle seconds)
16450         # cl3   144   (2) mask=<list>
16451         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16452                 # this is the normal case where all users were deregistered
16453                 # make sure no new records are added when no users are present
16454                 local last_rec1=$(changelog_users $SINGLEMDS |
16455                                   awk '/^current.index:/ { print $NF }')
16456                 touch $DIR/$tdir/chloe
16457                 local last_rec2=$(changelog_users $SINGLEMDS |
16458                                   awk '/^current.index:/ { print $NF }')
16459                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16460                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16461         else
16462                 # any changelog users must be leftovers from a previous test
16463                 changelog_users $SINGLEMDS
16464                 echo "other changelog users; can't verify off"
16465         fi
16466 }
16467 run_test 160a "changelog sanity"
16468
16469 test_160b() { # LU-3587
16470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16471         remote_mds_nodsh && skip "remote MDS with nodsh"
16472         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16473                 skip "Need MDS version at least 2.2.0"
16474
16475         changelog_register || error "changelog_register failed"
16476         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16477         changelog_users $SINGLEMDS | grep -q $cl_user ||
16478                 error "User '$cl_user' not found in changelog_users"
16479
16480         local longname1=$(str_repeat a 255)
16481         local longname2=$(str_repeat b 255)
16482
16483         cd $DIR
16484         echo "creating very long named file"
16485         touch $longname1 || error "create of '$longname1' failed"
16486         echo "renaming very long named file"
16487         mv $longname1 $longname2
16488
16489         changelog_dump | grep RENME | tail -n 5
16490         rm -f $longname2
16491 }
16492 run_test 160b "Verify that very long rename doesn't crash in changelog"
16493
16494 test_160c() {
16495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16496         remote_mds_nodsh && skip "remote MDS with nodsh"
16497
16498         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16499                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16500                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16501                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16502
16503         local rc=0
16504
16505         # Registration step
16506         changelog_register || error "changelog_register failed"
16507
16508         rm -rf $DIR/$tdir
16509         mkdir -p $DIR/$tdir
16510         $MCREATE $DIR/$tdir/foo_160c
16511         changelog_chmask "-TRUNC"
16512         $TRUNCATE $DIR/$tdir/foo_160c 200
16513         changelog_chmask "+TRUNC"
16514         $TRUNCATE $DIR/$tdir/foo_160c 199
16515         changelog_dump | tail -n 5
16516         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16517         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16518 }
16519 run_test 160c "verify that changelog log catch the truncate event"
16520
16521 test_160d() {
16522         remote_mds_nodsh && skip "remote MDS with nodsh"
16523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16525         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16526                 skip "Need MDS version at least 2.7.60"
16527
16528         # Registration step
16529         changelog_register || error "changelog_register failed"
16530
16531         mkdir -p $DIR/$tdir/migrate_dir
16532         changelog_clear 0 || error "changelog_clear failed"
16533
16534         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16535         changelog_dump | tail -n 5
16536         local migrates=$(changelog_dump | grep -c "MIGRT")
16537         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16538 }
16539 run_test 160d "verify that changelog log catch the migrate event"
16540
16541 test_160e() {
16542         remote_mds_nodsh && skip "remote MDS with nodsh"
16543
16544         # Create a user
16545         changelog_register || error "changelog_register failed"
16546
16547         local MDT0=$(facet_svc $SINGLEMDS)
16548         local rc
16549
16550         # No user (expect fail)
16551         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16552         rc=$?
16553         if [ $rc -eq 0 ]; then
16554                 error "Should fail without user"
16555         elif [ $rc -ne 4 ]; then
16556                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16557         fi
16558
16559         # Delete a future user (expect fail)
16560         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16561         rc=$?
16562         if [ $rc -eq 0 ]; then
16563                 error "Deleted non-existant user cl77"
16564         elif [ $rc -ne 2 ]; then
16565                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16566         fi
16567
16568         # Clear to a bad index (1 billion should be safe)
16569         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16570         rc=$?
16571
16572         if [ $rc -eq 0 ]; then
16573                 error "Successfully cleared to invalid CL index"
16574         elif [ $rc -ne 22 ]; then
16575                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16576         fi
16577 }
16578 run_test 160e "changelog negative testing (should return errors)"
16579
16580 test_160f() {
16581         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16582         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16583                 skip "Need MDS version at least 2.10.56"
16584
16585         local mdts=$(comma_list $(mdts_nodes))
16586
16587         # Create a user
16588         changelog_register || error "first changelog_register failed"
16589         changelog_register || error "second changelog_register failed"
16590         local cl_users
16591         declare -A cl_user1
16592         declare -A cl_user2
16593         local user_rec1
16594         local user_rec2
16595         local i
16596
16597         # generate some changelog records to accumulate on each MDT
16598         # use all_char because created files should be evenly distributed
16599         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16600                 error "test_mkdir $tdir failed"
16601         log "$(date +%s): creating first files"
16602         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16603                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16604                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16605         done
16606
16607         # check changelogs have been generated
16608         local start=$SECONDS
16609         local idle_time=$((MDSCOUNT * 5 + 5))
16610         local nbcl=$(changelog_dump | wc -l)
16611         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16612
16613         for param in "changelog_max_idle_time=$idle_time" \
16614                      "changelog_gc=1" \
16615                      "changelog_min_gc_interval=2" \
16616                      "changelog_min_free_cat_entries=3"; do
16617                 local MDT0=$(facet_svc $SINGLEMDS)
16618                 local var="${param%=*}"
16619                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16620
16621                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16622                 do_nodes $mdts $LCTL set_param mdd.*.$param
16623         done
16624
16625         # force cl_user2 to be idle (1st part), but also cancel the
16626         # cl_user1 records so that it is not evicted later in the test.
16627         local sleep1=$((idle_time / 2))
16628         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16629         sleep $sleep1
16630
16631         # simulate changelog catalog almost full
16632         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16633         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16634
16635         for i in $(seq $MDSCOUNT); do
16636                 cl_users=(${CL_USERS[mds$i]})
16637                 cl_user1[mds$i]="${cl_users[0]}"
16638                 cl_user2[mds$i]="${cl_users[1]}"
16639
16640                 [ -n "${cl_user1[mds$i]}" ] ||
16641                         error "mds$i: no user registered"
16642                 [ -n "${cl_user2[mds$i]}" ] ||
16643                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16644
16645                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16646                 [ -n "$user_rec1" ] ||
16647                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16648                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16649                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16650                 [ -n "$user_rec2" ] ||
16651                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16652                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16653                      "$user_rec1 + 2 == $user_rec2"
16654                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16655                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16656                               "$user_rec1 + 2, but is $user_rec2"
16657                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16658                 [ -n "$user_rec2" ] ||
16659                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16660                 [ $user_rec1 == $user_rec2 ] ||
16661                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16662                               "$user_rec1, but is $user_rec2"
16663         done
16664
16665         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16666         local sleep2=$((idle_time - (SECONDS - start) + 1))
16667         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16668         sleep $sleep2
16669
16670         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16671         # cl_user1 should be OK because it recently processed records.
16672         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16673         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16674                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16675                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16676         done
16677
16678         # ensure gc thread is done
16679         for i in $(mdts_nodes); do
16680                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16681                         error "$i: GC-thread not done"
16682         done
16683
16684         local first_rec
16685         for (( i = 1; i <= MDSCOUNT; i++ )); do
16686                 # check cl_user1 still registered
16687                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16688                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16689                 # check cl_user2 unregistered
16690                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16691                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16692
16693                 # check changelogs are present and starting at $user_rec1 + 1
16694                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16695                 [ -n "$user_rec1" ] ||
16696                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16697                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16698                             awk '{ print $1; exit; }')
16699
16700                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16701                 [ $((user_rec1 + 1)) == $first_rec ] ||
16702                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16703         done
16704 }
16705 run_test 160f "changelog garbage collect (timestamped users)"
16706
16707 test_160g() {
16708         remote_mds_nodsh && skip "remote MDS with nodsh"
16709         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16710                 skip "Need MDS version at least 2.14.55"
16711
16712         local mdts=$(comma_list $(mdts_nodes))
16713
16714         # Create a user
16715         changelog_register || error "first changelog_register failed"
16716         changelog_register || error "second changelog_register failed"
16717         local cl_users
16718         declare -A cl_user1
16719         declare -A cl_user2
16720         local user_rec1
16721         local user_rec2
16722         local i
16723
16724         # generate some changelog records to accumulate on each MDT
16725         # use all_char because created files should be evenly distributed
16726         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16727                 error "test_mkdir $tdir failed"
16728         for ((i = 0; i < MDSCOUNT; i++)); do
16729                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16730                         error "create $DIR/$tdir/d$i.1 failed"
16731         done
16732
16733         # check changelogs have been generated
16734         local nbcl=$(changelog_dump | wc -l)
16735         (( $nbcl > 0 )) || error "no changelogs found"
16736
16737         # reduce the max_idle_indexes value to make sure we exceed it
16738         for param in "changelog_max_idle_indexes=2" \
16739                      "changelog_gc=1" \
16740                      "changelog_min_gc_interval=2"; do
16741                 local MDT0=$(facet_svc $SINGLEMDS)
16742                 local var="${param%=*}"
16743                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16744
16745                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16746                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16747                         error "unable to set mdd.*.$param"
16748         done
16749
16750         local start=$SECONDS
16751         for i in $(seq $MDSCOUNT); do
16752                 cl_users=(${CL_USERS[mds$i]})
16753                 cl_user1[mds$i]="${cl_users[0]}"
16754                 cl_user2[mds$i]="${cl_users[1]}"
16755
16756                 [ -n "${cl_user1[mds$i]}" ] ||
16757                         error "mds$i: user1 is not registered"
16758                 [ -n "${cl_user2[mds$i]}" ] ||
16759                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16760
16761                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16762                 [ -n "$user_rec1" ] ||
16763                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16764                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16765                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16766                 [ -n "$user_rec2" ] ||
16767                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16768                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16769                      "$user_rec1 + 2 == $user_rec2"
16770                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16771                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16772                               "expected $user_rec1 + 2, but is $user_rec2"
16773                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16774                 [ -n "$user_rec2" ] ||
16775                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16776                 [ $user_rec1 == $user_rec2 ] ||
16777                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16778                               "expected $user_rec1, but is $user_rec2"
16779         done
16780
16781         # ensure we are past the previous changelog_min_gc_interval set above
16782         local sleep2=$((start + 2 - SECONDS))
16783         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16784         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16785         # cl_user1 should be OK because it recently processed records.
16786         for ((i = 0; i < MDSCOUNT; i++)); do
16787                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16788                         error "create $DIR/$tdir/d$i.3 failed"
16789         done
16790
16791         # ensure gc thread is done
16792         for i in $(mdts_nodes); do
16793                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16794                         error "$i: GC-thread not done"
16795         done
16796
16797         local first_rec
16798         for (( i = 1; i <= MDSCOUNT; i++ )); do
16799                 # check cl_user1 still registered
16800                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16801                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16802                 # check cl_user2 unregistered
16803                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16804                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16805
16806                 # check changelogs are present and starting at $user_rec1 + 1
16807                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16808                 [ -n "$user_rec1" ] ||
16809                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16810                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16811                             awk '{ print $1; exit; }')
16812
16813                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16814                 [ $((user_rec1 + 1)) == $first_rec ] ||
16815                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16816         done
16817 }
16818 run_test 160g "changelog garbage collect on idle records"
16819
16820 test_160h() {
16821         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16822         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16823                 skip "Need MDS version at least 2.10.56"
16824
16825         local mdts=$(comma_list $(mdts_nodes))
16826
16827         # Create a user
16828         changelog_register || error "first changelog_register failed"
16829         changelog_register || error "second changelog_register failed"
16830         local cl_users
16831         declare -A cl_user1
16832         declare -A cl_user2
16833         local user_rec1
16834         local user_rec2
16835         local i
16836
16837         # generate some changelog records to accumulate on each MDT
16838         # use all_char because created files should be evenly distributed
16839         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16840                 error "test_mkdir $tdir failed"
16841         for ((i = 0; i < MDSCOUNT; i++)); do
16842                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16843                         error "create $DIR/$tdir/d$i.1 failed"
16844         done
16845
16846         # check changelogs have been generated
16847         local nbcl=$(changelog_dump | wc -l)
16848         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16849
16850         for param in "changelog_max_idle_time=10" \
16851                      "changelog_gc=1" \
16852                      "changelog_min_gc_interval=2"; do
16853                 local MDT0=$(facet_svc $SINGLEMDS)
16854                 local var="${param%=*}"
16855                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16856
16857                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16858                 do_nodes $mdts $LCTL set_param mdd.*.$param
16859         done
16860
16861         # force cl_user2 to be idle (1st part)
16862         sleep 9
16863
16864         for i in $(seq $MDSCOUNT); do
16865                 cl_users=(${CL_USERS[mds$i]})
16866                 cl_user1[mds$i]="${cl_users[0]}"
16867                 cl_user2[mds$i]="${cl_users[1]}"
16868
16869                 [ -n "${cl_user1[mds$i]}" ] ||
16870                         error "mds$i: no user registered"
16871                 [ -n "${cl_user2[mds$i]}" ] ||
16872                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16873
16874                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16875                 [ -n "$user_rec1" ] ||
16876                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16877                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16878                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16879                 [ -n "$user_rec2" ] ||
16880                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16881                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16882                      "$user_rec1 + 2 == $user_rec2"
16883                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16884                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16885                               "$user_rec1 + 2, but is $user_rec2"
16886                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16887                 [ -n "$user_rec2" ] ||
16888                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16889                 [ $user_rec1 == $user_rec2 ] ||
16890                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16891                               "$user_rec1, but is $user_rec2"
16892         done
16893
16894         # force cl_user2 to be idle (2nd part) and to reach
16895         # changelog_max_idle_time
16896         sleep 2
16897
16898         # force each GC-thread start and block then
16899         # one per MDT/MDD, set fail_val accordingly
16900         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16901         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16902
16903         # generate more changelogs to trigger fail_loc
16904         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16905                 error "create $DIR/$tdir/${tfile}bis failed"
16906
16907         # stop MDT to stop GC-thread, should be done in back-ground as it will
16908         # block waiting for the thread to be released and exit
16909         declare -A stop_pids
16910         for i in $(seq $MDSCOUNT); do
16911                 stop mds$i &
16912                 stop_pids[mds$i]=$!
16913         done
16914
16915         for i in $(mdts_nodes); do
16916                 local facet
16917                 local nb=0
16918                 local facets=$(facets_up_on_host $i)
16919
16920                 for facet in ${facets//,/ }; do
16921                         if [[ $facet == mds* ]]; then
16922                                 nb=$((nb + 1))
16923                         fi
16924                 done
16925                 # ensure each MDS's gc threads are still present and all in "R"
16926                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16927                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16928                         error "$i: expected $nb GC-thread"
16929                 wait_update $i \
16930                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16931                         "R" 20 ||
16932                         error "$i: GC-thread not found in R-state"
16933                 # check umounts of each MDT on MDS have reached kthread_stop()
16934                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16935                         error "$i: expected $nb umount"
16936                 wait_update $i \
16937                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16938                         error "$i: umount not found in D-state"
16939         done
16940
16941         # release all GC-threads
16942         do_nodes $mdts $LCTL set_param fail_loc=0
16943
16944         # wait for MDT stop to complete
16945         for i in $(seq $MDSCOUNT); do
16946                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16947         done
16948
16949         # XXX
16950         # may try to check if any orphan changelog records are present
16951         # via ldiskfs/zfs and llog_reader...
16952
16953         # re-start/mount MDTs
16954         for i in $(seq $MDSCOUNT); do
16955                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16956                         error "Fail to start mds$i"
16957         done
16958
16959         local first_rec
16960         for i in $(seq $MDSCOUNT); do
16961                 # check cl_user1 still registered
16962                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16963                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16964                 # check cl_user2 unregistered
16965                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16966                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16967
16968                 # check changelogs are present and starting at $user_rec1 + 1
16969                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16970                 [ -n "$user_rec1" ] ||
16971                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16972                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16973                             awk '{ print $1; exit; }')
16974
16975                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16976                 [ $((user_rec1 + 1)) == $first_rec ] ||
16977                         error "mds$i: first index should be $user_rec1 + 1, " \
16978                               "but is $first_rec"
16979         done
16980 }
16981 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16982               "during mount"
16983
16984 test_160i() {
16985
16986         local mdts=$(comma_list $(mdts_nodes))
16987
16988         changelog_register || error "first changelog_register failed"
16989
16990         # generate some changelog records to accumulate on each MDT
16991         # use all_char because created files should be evenly distributed
16992         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16993                 error "test_mkdir $tdir failed"
16994         for ((i = 0; i < MDSCOUNT; i++)); do
16995                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16996                         error "create $DIR/$tdir/d$i.1 failed"
16997         done
16998
16999         # check changelogs have been generated
17000         local nbcl=$(changelog_dump | wc -l)
17001         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17002
17003         # simulate race between register and unregister
17004         # XXX as fail_loc is set per-MDS, with DNE configs the race
17005         # simulation will only occur for one MDT per MDS and for the
17006         # others the normal race scenario will take place
17007         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17008         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17009         do_nodes $mdts $LCTL set_param fail_val=1
17010
17011         # unregister 1st user
17012         changelog_deregister &
17013         local pid1=$!
17014         # wait some time for deregister work to reach race rdv
17015         sleep 2
17016         # register 2nd user
17017         changelog_register || error "2nd user register failed"
17018
17019         wait $pid1 || error "1st user deregister failed"
17020
17021         local i
17022         local last_rec
17023         declare -A LAST_REC
17024         for i in $(seq $MDSCOUNT); do
17025                 if changelog_users mds$i | grep "^cl"; then
17026                         # make sure new records are added with one user present
17027                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17028                                           awk '/^current.index:/ { print $NF }')
17029                 else
17030                         error "mds$i has no user registered"
17031                 fi
17032         done
17033
17034         # generate more changelog records to accumulate on each MDT
17035         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17036                 error "create $DIR/$tdir/${tfile}bis failed"
17037
17038         for i in $(seq $MDSCOUNT); do
17039                 last_rec=$(changelog_users $SINGLEMDS |
17040                            awk '/^current.index:/ { print $NF }')
17041                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17042                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17043                         error "changelogs are off on mds$i"
17044         done
17045 }
17046 run_test 160i "changelog user register/unregister race"
17047
17048 test_160j() {
17049         remote_mds_nodsh && skip "remote MDS with nodsh"
17050         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17051                 skip "Need MDS version at least 2.12.56"
17052
17053         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17054         stack_trap "umount $MOUNT2" EXIT
17055
17056         changelog_register || error "first changelog_register failed"
17057         stack_trap "changelog_deregister" EXIT
17058
17059         # generate some changelog
17060         # use all_char because created files should be evenly distributed
17061         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17062                 error "mkdir $tdir failed"
17063         for ((i = 0; i < MDSCOUNT; i++)); do
17064                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17065                         error "create $DIR/$tdir/d$i.1 failed"
17066         done
17067
17068         # open the changelog device
17069         exec 3>/dev/changelog-$FSNAME-MDT0000
17070         stack_trap "exec 3>&-" EXIT
17071         exec 4</dev/changelog-$FSNAME-MDT0000
17072         stack_trap "exec 4<&-" EXIT
17073
17074         # umount the first lustre mount
17075         umount $MOUNT
17076         stack_trap "mount_client $MOUNT" EXIT
17077
17078         # read changelog, which may or may not fail, but should not crash
17079         cat <&4 >/dev/null
17080
17081         # clear changelog
17082         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17083         changelog_users $SINGLEMDS | grep -q $cl_user ||
17084                 error "User $cl_user not found in changelog_users"
17085
17086         printf 'clear:'$cl_user':0' >&3
17087 }
17088 run_test 160j "client can be umounted while its chanangelog is being used"
17089
17090 test_160k() {
17091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17092         remote_mds_nodsh && skip "remote MDS with nodsh"
17093
17094         mkdir -p $DIR/$tdir/1/1
17095
17096         changelog_register || error "changelog_register failed"
17097         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17098
17099         changelog_users $SINGLEMDS | grep -q $cl_user ||
17100                 error "User '$cl_user' not found in changelog_users"
17101 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17102         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17103         rmdir $DIR/$tdir/1/1 & sleep 1
17104         mkdir $DIR/$tdir/2
17105         touch $DIR/$tdir/2/2
17106         rm -rf $DIR/$tdir/2
17107
17108         wait
17109         sleep 4
17110
17111         changelog_dump | grep rmdir || error "rmdir not recorded"
17112 }
17113 run_test 160k "Verify that changelog records are not lost"
17114
17115 # Verifies that a file passed as a parameter has recently had an operation
17116 # performed on it that has generated an MTIME changelog which contains the
17117 # correct parent FID. As files might reside on a different MDT from the
17118 # parent directory in DNE configurations, the FIDs are translated to paths
17119 # before being compared, which should be identical
17120 compare_mtime_changelog() {
17121         local file="${1}"
17122         local mdtidx
17123         local mtime
17124         local cl_fid
17125         local pdir
17126         local dir
17127
17128         mdtidx=$($LFS getstripe --mdt-index $file)
17129         mdtidx=$(printf "%04x" $mdtidx)
17130
17131         # Obtain the parent FID from the MTIME changelog
17132         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17133         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17134
17135         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17136         [ -z "$cl_fid" ] && error "parent FID not present"
17137
17138         # Verify that the path for the parent FID is the same as the path for
17139         # the test directory
17140         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17141
17142         dir=$(dirname $1)
17143
17144         [[ "${pdir%/}" == "$dir" ]] ||
17145                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17146 }
17147
17148 test_160l() {
17149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17150
17151         remote_mds_nodsh && skip "remote MDS with nodsh"
17152         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17153                 skip "Need MDS version at least 2.13.55"
17154
17155         local cl_user
17156
17157         changelog_register || error "changelog_register failed"
17158         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17159
17160         changelog_users $SINGLEMDS | grep -q $cl_user ||
17161                 error "User '$cl_user' not found in changelog_users"
17162
17163         # Clear some types so that MTIME changelogs are generated
17164         changelog_chmask "-CREAT"
17165         changelog_chmask "-CLOSE"
17166
17167         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17168
17169         # Test CL_MTIME during setattr
17170         touch $DIR/$tdir/$tfile
17171         compare_mtime_changelog $DIR/$tdir/$tfile
17172
17173         # Test CL_MTIME during close
17174         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17175         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17176 }
17177 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17178
17179 test_160m() {
17180         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17181         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17182                 skip "Need MDS version at least 2.14.51"
17183         local cl_users
17184         local cl_user1
17185         local cl_user2
17186         local pid1
17187
17188         # Create a user
17189         changelog_register || error "first changelog_register failed"
17190         changelog_register || error "second changelog_register failed"
17191
17192         cl_users=(${CL_USERS[mds1]})
17193         cl_user1="${cl_users[0]}"
17194         cl_user2="${cl_users[1]}"
17195         # generate some changelog records to accumulate on MDT0
17196         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17197         createmany -m $DIR/$tdir/$tfile 50 ||
17198                 error "create $DIR/$tdir/$tfile failed"
17199         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17200         rm -f $DIR/$tdir
17201
17202         # check changelogs have been generated
17203         local nbcl=$(changelog_dump | wc -l)
17204         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17205
17206 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17207         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17208
17209         __changelog_clear mds1 $cl_user1 +10
17210         __changelog_clear mds1 $cl_user2 0 &
17211         pid1=$!
17212         sleep 2
17213         __changelog_clear mds1 $cl_user1 0 ||
17214                 error "fail to cancel record for $cl_user1"
17215         wait $pid1
17216         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17217 }
17218 run_test 160m "Changelog clear race"
17219
17220 test_160n() {
17221         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17222         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17223                 skip "Need MDS version at least 2.14.51"
17224         local cl_users
17225         local cl_user1
17226         local cl_user2
17227         local pid1
17228         local first_rec
17229         local last_rec=0
17230
17231         # Create a user
17232         changelog_register || error "first changelog_register failed"
17233
17234         cl_users=(${CL_USERS[mds1]})
17235         cl_user1="${cl_users[0]}"
17236
17237         # generate some changelog records to accumulate on MDT0
17238         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17239         first_rec=$(changelog_users $SINGLEMDS |
17240                         awk '/^current.index:/ { print $NF }')
17241         while (( last_rec < (( first_rec + 65000)) )); do
17242                 createmany -m $DIR/$tdir/$tfile 10000 ||
17243                         error "create $DIR/$tdir/$tfile failed"
17244
17245                 for i in $(seq 0 10000); do
17246                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17247                                 > /dev/null
17248                 done
17249
17250                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17251                         error "unlinkmany failed unlink"
17252                 last_rec=$(changelog_users $SINGLEMDS |
17253                         awk '/^current.index:/ { print $NF }')
17254                 echo last record $last_rec
17255                 (( last_rec == 0 )) && error "no changelog found"
17256         done
17257
17258 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17259         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17260
17261         __changelog_clear mds1 $cl_user1 0 &
17262         pid1=$!
17263         sleep 2
17264         __changelog_clear mds1 $cl_user1 0 ||
17265                 error "fail to cancel record for $cl_user1"
17266         wait $pid1
17267         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17268 }
17269 run_test 160n "Changelog destroy race"
17270
17271 test_160o() {
17272         local mdt="$(facet_svc $SINGLEMDS)"
17273
17274         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17275         remote_mds_nodsh && skip "remote MDS with nodsh"
17276         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17277                 skip "Need MDS version at least 2.14.52"
17278
17279         changelog_register --user test_160o -m unlnk+close+open ||
17280                 error "changelog_register failed"
17281
17282         do_facet $SINGLEMDS $LCTL --device $mdt \
17283                                 changelog_register -u "Tt3_-#" &&
17284                 error "bad symbols in name should fail"
17285
17286         do_facet $SINGLEMDS $LCTL --device $mdt \
17287                                 changelog_register -u test_160o &&
17288                 error "the same name registration should fail"
17289
17290         do_facet $SINGLEMDS $LCTL --device $mdt \
17291                         changelog_register -u test_160toolongname &&
17292                 error "too long name registration should fail"
17293
17294         changelog_chmask "MARK+HSM"
17295         lctl get_param mdd.*.changelog*mask
17296         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17297         changelog_users $SINGLEMDS | grep -q $cl_user ||
17298                 error "User $cl_user not found in changelog_users"
17299         #verify username
17300         echo $cl_user | grep -q test_160o ||
17301                 error "User $cl_user has no specific name 'test160o'"
17302
17303         # change something
17304         changelog_clear 0 || error "changelog_clear failed"
17305         # generate some changelog records to accumulate on MDT0
17306         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17307         touch $DIR/$tdir/$tfile                 # open 1
17308
17309         OPENS=$(changelog_dump | grep -c "OPEN")
17310         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17311
17312         # must be no MKDIR it wasn't set as user mask
17313         MKDIR=$(changelog_dump | grep -c "MKDIR")
17314         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17315
17316         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17317                                 mdd.$mdt.changelog_current_mask -n)
17318         # register maskless user
17319         changelog_register || error "changelog_register failed"
17320         # effective mask should be not changed because it is not minimal
17321         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17322                                 mdd.$mdt.changelog_current_mask -n)
17323         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17324         # set server mask to minimal value
17325         changelog_chmask "MARK"
17326         # check effective mask again, should be treated as DEFMASK now
17327         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17328                                 mdd.$mdt.changelog_current_mask -n)
17329         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17330
17331         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17332                 # set server mask back to some value
17333                 changelog_chmask "CLOSE,UNLNK"
17334                 # check effective mask again, should not remain as DEFMASK
17335                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17336                                 mdd.$mdt.changelog_current_mask -n)
17337                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17338         fi
17339
17340         do_facet $SINGLEMDS $LCTL --device $mdt \
17341                                 changelog_deregister -u test_160o ||
17342                 error "cannot deregister by name"
17343 }
17344 run_test 160o "changelog user name and mask"
17345
17346 test_160p() {
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         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17351         local cl_users
17352         local cl_user1
17353         local entry_count
17354
17355         # Create a user
17356         changelog_register || error "first changelog_register failed"
17357
17358         cl_users=(${CL_USERS[mds1]})
17359         cl_user1="${cl_users[0]}"
17360
17361         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17362         createmany -m $DIR/$tdir/$tfile 50 ||
17363                 error "create $DIR/$tdir/$tfile failed"
17364         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17365         rm -rf $DIR/$tdir
17366
17367         # check changelogs have been generated
17368         entry_count=$(changelog_dump | wc -l)
17369         ((entry_count != 0)) || error "no changelog entries found"
17370
17371         # remove changelog_users and check that orphan entries are removed
17372         stop mds1
17373         local dev=$(mdsdevname 1)
17374         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17375         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17376         entry_count=$(changelog_dump | wc -l)
17377         ((entry_count == 0)) ||
17378                 error "found $entry_count changelog entries, expected none"
17379 }
17380 run_test 160p "Changelog orphan cleanup with no users"
17381
17382 test_160q() {
17383         local mdt="$(facet_svc $SINGLEMDS)"
17384         local clu
17385
17386         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17387         remote_mds_nodsh && skip "remote MDS with nodsh"
17388         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17389                 skip "Need MDS version at least 2.14.54"
17390
17391         # set server mask to minimal value like server init does
17392         changelog_chmask "MARK"
17393         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17394                 error "changelog_register failed"
17395         # check effective mask again, should be treated as DEFMASK now
17396         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17397                                 mdd.$mdt.changelog_current_mask -n)
17398         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17399                 error "changelog_deregister failed"
17400         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17401 }
17402 run_test 160q "changelog effective mask is DEFMASK if not set"
17403
17404 test_160s() {
17405         remote_mds_nodsh && skip "remote MDS with nodsh"
17406         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17407                 skip "Need MDS version at least 2.14.55"
17408
17409         local mdts=$(comma_list $(mdts_nodes))
17410
17411         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17412         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17413                                        fail_val=$((24 * 3600 * 10))
17414
17415         # Create a user which is 10 days old
17416         changelog_register || error "first changelog_register failed"
17417         local cl_users
17418         declare -A cl_user1
17419         local i
17420
17421         # generate some changelog records to accumulate on each MDT
17422         # use all_char because created files should be evenly distributed
17423         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17424                 error "test_mkdir $tdir failed"
17425         for ((i = 0; i < MDSCOUNT; i++)); do
17426                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17427                         error "create $DIR/$tdir/d$i.1 failed"
17428         done
17429
17430         # check changelogs have been generated
17431         local nbcl=$(changelog_dump | wc -l)
17432         (( nbcl > 0 )) || error "no changelogs found"
17433
17434         # reduce the max_idle_indexes value to make sure we exceed it
17435         for param in "changelog_max_idle_indexes=2097446912" \
17436                      "changelog_max_idle_time=2592000" \
17437                      "changelog_gc=1" \
17438                      "changelog_min_gc_interval=2"; do
17439                 local MDT0=$(facet_svc $SINGLEMDS)
17440                 local var="${param%=*}"
17441                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17442
17443                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17444                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17445                         error "unable to set mdd.*.$param"
17446         done
17447
17448         local start=$SECONDS
17449         for i in $(seq $MDSCOUNT); do
17450                 cl_users=(${CL_USERS[mds$i]})
17451                 cl_user1[mds$i]="${cl_users[0]}"
17452
17453                 [[ -n "${cl_user1[mds$i]}" ]] ||
17454                         error "mds$i: no user registered"
17455         done
17456
17457         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17458         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17459
17460         # ensure we are past the previous changelog_min_gc_interval set above
17461         local sleep2=$((start + 2 - SECONDS))
17462         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17463
17464         # Generate one more changelog to trigger GC
17465         for ((i = 0; i < MDSCOUNT; i++)); do
17466                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17467                         error "create $DIR/$tdir/d$i.3 failed"
17468         done
17469
17470         # ensure gc thread is done
17471         for node in $(mdts_nodes); do
17472                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17473                         error "$node: GC-thread not done"
17474         done
17475
17476         do_nodes $mdts $LCTL set_param fail_loc=0
17477
17478         for (( i = 1; i <= MDSCOUNT; i++ )); do
17479                 # check cl_user1 is purged
17480                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17481                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17482         done
17483         return 0
17484 }
17485 run_test 160s "changelog garbage collect on idle records * time"
17486
17487 test_160t() {
17488         remote_mds_nodsh && skip "remote MDS with nodsh"
17489         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17490                 skip "Need MDS version at least 2.15.50"
17491
17492         local MDT0=$(facet_svc $SINGLEMDS)
17493         local cl_users
17494         local cl_user1
17495         local cl_user2
17496         local start
17497
17498         changelog_register --user user1 -m all ||
17499                 error "user1 failed to register"
17500
17501         mkdir_on_mdt0 $DIR/$tdir
17502         # create default overstripe to maximize changelog size
17503         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17504         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17505         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17506
17507         # user2 consumes less records so less space
17508         changelog_register --user user2 || error "user2 failed to register"
17509         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17510         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17511
17512         # check changelogs have been generated
17513         local nbcl=$(changelog_dump | wc -l)
17514         (( nbcl > 0 )) || error "no changelogs found"
17515
17516         # reduce the changelog_min_gc_interval to force check
17517         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17518                 local var="${param%=*}"
17519                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17520
17521                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17522                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17523                         error "unable to set mdd.*.$param"
17524         done
17525
17526         start=$SECONDS
17527         cl_users=(${CL_USERS[mds1]})
17528         cl_user1="${cl_users[0]}"
17529         cl_user2="${cl_users[1]}"
17530
17531         [[ -n $cl_user1 ]] ||
17532                 error "mds1: user #1 isn't registered"
17533         [[ -n $cl_user2 ]] ||
17534                 error "mds1: user #2 isn't registered"
17535
17536         # ensure we are past the previous changelog_min_gc_interval set above
17537         local sleep2=$((start + 2 - SECONDS))
17538         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17539
17540         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17541         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17542                         fail_val=$(((llog_size1 + llog_size2) / 2))
17543
17544         # Generate more changelog to trigger GC
17545         createmany -o $DIR/$tdir/u3_ 4 ||
17546                 error "create failed for more files"
17547
17548         # ensure gc thread is done
17549         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17550                 error "mds1: GC-thread not done"
17551
17552         do_facet mds1 $LCTL set_param fail_loc=0
17553
17554         # check cl_user1 is purged
17555         changelog_users mds1 | grep -q "$cl_user1" &&
17556                 error "User $cl_user1 is registered"
17557         # check cl_user2 is not purged
17558         changelog_users mds1 | grep -q "$cl_user2" ||
17559                 error "User $cl_user2 is not registered"
17560 }
17561 run_test 160t "changelog garbage collect on lack of space"
17562
17563 test_161a() {
17564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17565
17566         test_mkdir -c1 $DIR/$tdir
17567         cp /etc/hosts $DIR/$tdir/$tfile
17568         test_mkdir -c1 $DIR/$tdir/foo1
17569         test_mkdir -c1 $DIR/$tdir/foo2
17570         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17571         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17572         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17573         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17574         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17575         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17576                 $LFS fid2path $DIR $FID
17577                 error "bad link ea"
17578         fi
17579         # middle
17580         rm $DIR/$tdir/foo2/zachary
17581         # last
17582         rm $DIR/$tdir/foo2/thor
17583         # first
17584         rm $DIR/$tdir/$tfile
17585         # rename
17586         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17587         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17588                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17589         rm $DIR/$tdir/foo2/maggie
17590
17591         # overflow the EA
17592         local longname=$tfile.avg_len_is_thirty_two_
17593         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17594                 error_noexit 'failed to unlink many hardlinks'" EXIT
17595         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17596                 error "failed to hardlink many files"
17597         links=$($LFS fid2path $DIR $FID | wc -l)
17598         echo -n "${links}/1000 links in link EA"
17599         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17600 }
17601 run_test 161a "link ea sanity"
17602
17603 test_161b() {
17604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17605         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17606
17607         local MDTIDX=1
17608         local remote_dir=$DIR/$tdir/remote_dir
17609
17610         mkdir -p $DIR/$tdir
17611         $LFS mkdir -i $MDTIDX $remote_dir ||
17612                 error "create remote directory failed"
17613
17614         cp /etc/hosts $remote_dir/$tfile
17615         mkdir -p $remote_dir/foo1
17616         mkdir -p $remote_dir/foo2
17617         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17618         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17619         ln $remote_dir/$tfile $remote_dir/foo1/luna
17620         ln $remote_dir/$tfile $remote_dir/foo2/thor
17621
17622         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17623                      tr -d ']')
17624         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17625                 $LFS fid2path $DIR $FID
17626                 error "bad link ea"
17627         fi
17628         # middle
17629         rm $remote_dir/foo2/zachary
17630         # last
17631         rm $remote_dir/foo2/thor
17632         # first
17633         rm $remote_dir/$tfile
17634         # rename
17635         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17636         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17637         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17638                 $LFS fid2path $DIR $FID
17639                 error "bad link rename"
17640         fi
17641         rm $remote_dir/foo2/maggie
17642
17643         # overflow the EA
17644         local longname=filename_avg_len_is_thirty_two_
17645         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17646                 error "failed to hardlink many files"
17647         links=$($LFS fid2path $DIR $FID | wc -l)
17648         echo -n "${links}/1000 links in link EA"
17649         [[ ${links} -gt 60 ]] ||
17650                 error "expected at least 60 links in link EA"
17651         unlinkmany $remote_dir/foo2/$longname 1000 ||
17652         error "failed to unlink many hardlinks"
17653 }
17654 run_test 161b "link ea sanity under remote directory"
17655
17656 test_161c() {
17657         remote_mds_nodsh && skip "remote MDS with nodsh"
17658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17659         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17660                 skip "Need MDS version at least 2.1.5"
17661
17662         # define CLF_RENAME_LAST 0x0001
17663         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17664         changelog_register || error "changelog_register failed"
17665
17666         rm -rf $DIR/$tdir
17667         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17668         touch $DIR/$tdir/foo_161c
17669         touch $DIR/$tdir/bar_161c
17670         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17671         changelog_dump | grep RENME | tail -n 5
17672         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17673         changelog_clear 0 || error "changelog_clear failed"
17674         if [ x$flags != "x0x1" ]; then
17675                 error "flag $flags is not 0x1"
17676         fi
17677
17678         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17679         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17680         touch $DIR/$tdir/foo_161c
17681         touch $DIR/$tdir/bar_161c
17682         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17683         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17684         changelog_dump | grep RENME | tail -n 5
17685         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17686         changelog_clear 0 || error "changelog_clear failed"
17687         if [ x$flags != "x0x0" ]; then
17688                 error "flag $flags is not 0x0"
17689         fi
17690         echo "rename overwrite a target having nlink > 1," \
17691                 "changelog record has flags of $flags"
17692
17693         # rename doesn't overwrite a target (changelog flag 0x0)
17694         touch $DIR/$tdir/foo_161c
17695         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17696         changelog_dump | grep RENME | tail -n 5
17697         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17698         changelog_clear 0 || error "changelog_clear failed"
17699         if [ x$flags != "x0x0" ]; then
17700                 error "flag $flags is not 0x0"
17701         fi
17702         echo "rename doesn't overwrite a target," \
17703                 "changelog record has flags of $flags"
17704
17705         # define CLF_UNLINK_LAST 0x0001
17706         # unlink a file having nlink = 1 (changelog flag 0x1)
17707         rm -f $DIR/$tdir/foo2_161c
17708         changelog_dump | grep UNLNK | tail -n 5
17709         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17710         changelog_clear 0 || error "changelog_clear failed"
17711         if [ x$flags != "x0x1" ]; then
17712                 error "flag $flags is not 0x1"
17713         fi
17714         echo "unlink a file having nlink = 1," \
17715                 "changelog record has flags of $flags"
17716
17717         # unlink a file having nlink > 1 (changelog flag 0x0)
17718         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17719         rm -f $DIR/$tdir/foobar_161c
17720         changelog_dump | grep UNLNK | tail -n 5
17721         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17722         changelog_clear 0 || error "changelog_clear failed"
17723         if [ x$flags != "x0x0" ]; then
17724                 error "flag $flags is not 0x0"
17725         fi
17726         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17727 }
17728 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17729
17730 test_161d() {
17731         remote_mds_nodsh && skip "remote MDS with nodsh"
17732         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17733
17734         local pid
17735         local fid
17736
17737         changelog_register || error "changelog_register failed"
17738
17739         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17740         # interfer with $MOUNT/.lustre/fid/ access
17741         mkdir $DIR/$tdir
17742         [[ $? -eq 0 ]] || error "mkdir failed"
17743
17744         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17745         $LCTL set_param fail_loc=0x8000140c
17746         # 5s pause
17747         $LCTL set_param fail_val=5
17748
17749         # create file
17750         echo foofoo > $DIR/$tdir/$tfile &
17751         pid=$!
17752
17753         # wait for create to be delayed
17754         sleep 2
17755
17756         ps -p $pid
17757         [[ $? -eq 0 ]] || error "create should be blocked"
17758
17759         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17760         stack_trap "rm -f $tempfile"
17761         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17762         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17763         # some delay may occur during ChangeLog publishing and file read just
17764         # above, that could allow file write to happen finally
17765         [[ -s $tempfile ]] && echo "file should be empty"
17766
17767         $LCTL set_param fail_loc=0
17768
17769         wait $pid
17770         [[ $? -eq 0 ]] || error "create failed"
17771 }
17772 run_test 161d "create with concurrent .lustre/fid access"
17773
17774 check_path() {
17775         local expected="$1"
17776         shift
17777         local fid="$2"
17778
17779         local path
17780         path=$($LFS fid2path "$@")
17781         local rc=$?
17782
17783         if [ $rc -ne 0 ]; then
17784                 error "path looked up of '$expected' failed: rc=$rc"
17785         elif [ "$path" != "$expected" ]; then
17786                 error "path looked up '$path' instead of '$expected'"
17787         else
17788                 echo "FID '$fid' resolves to path '$path' as expected"
17789         fi
17790 }
17791
17792 test_162a() { # was test_162
17793         test_mkdir -p -c1 $DIR/$tdir/d2
17794         touch $DIR/$tdir/d2/$tfile
17795         touch $DIR/$tdir/d2/x1
17796         touch $DIR/$tdir/d2/x2
17797         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17798         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17799         # regular file
17800         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17801         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17802
17803         # softlink
17804         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17805         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17806         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17807
17808         # softlink to wrong file
17809         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17810         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17811         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17812
17813         # hardlink
17814         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17815         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17816         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17817         # fid2path dir/fsname should both work
17818         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17819         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17820
17821         # hardlink count: check that there are 2 links
17822         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17823         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17824
17825         # hardlink indexing: remove the first link
17826         rm $DIR/$tdir/d2/p/q/r/hlink
17827         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17828 }
17829 run_test 162a "path lookup sanity"
17830
17831 test_162b() {
17832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17834
17835         mkdir $DIR/$tdir
17836         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17837                                 error "create striped dir failed"
17838
17839         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17840                                         tail -n 1 | awk '{print $2}')
17841         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17842
17843         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17844         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17845
17846         # regular file
17847         for ((i=0;i<5;i++)); do
17848                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17849                         error "get fid for f$i failed"
17850                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17851
17852                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17853                         error "get fid for d$i failed"
17854                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17855         done
17856
17857         return 0
17858 }
17859 run_test 162b "striped directory path lookup sanity"
17860
17861 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17862 test_162c() {
17863         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17864                 skip "Need MDS version at least 2.7.51"
17865
17866         local lpath=$tdir.local
17867         local rpath=$tdir.remote
17868
17869         test_mkdir $DIR/$lpath
17870         test_mkdir $DIR/$rpath
17871
17872         for ((i = 0; i <= 101; i++)); do
17873                 lpath="$lpath/$i"
17874                 mkdir $DIR/$lpath
17875                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17876                         error "get fid for local directory $DIR/$lpath failed"
17877                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17878
17879                 rpath="$rpath/$i"
17880                 test_mkdir $DIR/$rpath
17881                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17882                         error "get fid for remote directory $DIR/$rpath failed"
17883                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17884         done
17885
17886         return 0
17887 }
17888 run_test 162c "fid2path works with paths 100 or more directories deep"
17889
17890 oalr_event_count() {
17891         local event="${1}"
17892         local trace="${2}"
17893
17894         awk -v name="${FSNAME}-OST0000" \
17895             -v event="${event}" \
17896             '$1 == "TRACE" && $2 == event && $3 == name' \
17897             "${trace}" |
17898         wc -l
17899 }
17900
17901 oalr_expect_event_count() {
17902         local event="${1}"
17903         local trace="${2}"
17904         local expect="${3}"
17905         local count
17906
17907         count=$(oalr_event_count "${event}" "${trace}")
17908         if ((count == expect)); then
17909                 return 0
17910         fi
17911
17912         error_noexit "${event} event count was '${count}', expected ${expect}"
17913         cat "${trace}" >&2
17914         exit 1
17915 }
17916
17917 cleanup_165() {
17918         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17919         stop ost1
17920         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17921 }
17922
17923 setup_165() {
17924         sync # Flush previous IOs so we can count log entries.
17925         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17926         stack_trap cleanup_165 EXIT
17927 }
17928
17929 test_165a() {
17930         local trace="/tmp/${tfile}.trace"
17931         local rc
17932         local count
17933
17934         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17935                 skip "OFD access log unsupported"
17936
17937         setup_165
17938         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17939         sleep 5
17940
17941         do_facet ost1 ofd_access_log_reader --list
17942         stop ost1
17943
17944         do_facet ost1 killall -TERM ofd_access_log_reader
17945         wait
17946         rc=$?
17947
17948         if ((rc != 0)); then
17949                 error "ofd_access_log_reader exited with rc = '${rc}'"
17950         fi
17951
17952         # Parse trace file for discovery events:
17953         oalr_expect_event_count alr_log_add "${trace}" 1
17954         oalr_expect_event_count alr_log_eof "${trace}" 1
17955         oalr_expect_event_count alr_log_free "${trace}" 1
17956 }
17957 run_test 165a "ofd access log discovery"
17958
17959 test_165b() {
17960         local trace="/tmp/${tfile}.trace"
17961         local file="${DIR}/${tfile}"
17962         local pfid1
17963         local pfid2
17964         local -a entry
17965         local rc
17966         local count
17967         local size
17968         local flags
17969
17970         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17971                 skip "OFD access log unsupported"
17972
17973         setup_165
17974         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17975         sleep 5
17976
17977         do_facet ost1 ofd_access_log_reader --list
17978
17979         lfs setstripe -c 1 -i 0 "${file}"
17980         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17981                 error "cannot create '${file}'"
17982
17983         sleep 5
17984         do_facet ost1 killall -TERM ofd_access_log_reader
17985         wait
17986         rc=$?
17987
17988         if ((rc != 0)); then
17989                 error "ofd_access_log_reader exited with rc = '${rc}'"
17990         fi
17991
17992         oalr_expect_event_count alr_log_entry "${trace}" 1
17993
17994         pfid1=$($LFS path2fid "${file}")
17995
17996         # 1     2             3   4    5     6   7    8    9     10
17997         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17998         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17999
18000         echo "entry = '${entry[*]}'" >&2
18001
18002         pfid2=${entry[4]}
18003         if [[ "${pfid1}" != "${pfid2}" ]]; then
18004                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18005         fi
18006
18007         size=${entry[8]}
18008         if ((size != 1048576)); then
18009                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18010         fi
18011
18012         flags=${entry[10]}
18013         if [[ "${flags}" != "w" ]]; then
18014                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18015         fi
18016
18017         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18018         sleep 5
18019
18020         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18021                 error "cannot read '${file}'"
18022         sleep 5
18023
18024         do_facet ost1 killall -TERM ofd_access_log_reader
18025         wait
18026         rc=$?
18027
18028         if ((rc != 0)); then
18029                 error "ofd_access_log_reader exited with rc = '${rc}'"
18030         fi
18031
18032         oalr_expect_event_count alr_log_entry "${trace}" 1
18033
18034         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18035         echo "entry = '${entry[*]}'" >&2
18036
18037         pfid2=${entry[4]}
18038         if [[ "${pfid1}" != "${pfid2}" ]]; then
18039                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18040         fi
18041
18042         size=${entry[8]}
18043         if ((size != 524288)); then
18044                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18045         fi
18046
18047         flags=${entry[10]}
18048         if [[ "${flags}" != "r" ]]; then
18049                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18050         fi
18051 }
18052 run_test 165b "ofd access log entries are produced and consumed"
18053
18054 test_165c() {
18055         local trace="/tmp/${tfile}.trace"
18056         local file="${DIR}/${tdir}/${tfile}"
18057
18058         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18059                 skip "OFD access log unsupported"
18060
18061         test_mkdir "${DIR}/${tdir}"
18062
18063         setup_165
18064         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18065         sleep 5
18066
18067         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18068
18069         # 4096 / 64 = 64. Create twice as many entries.
18070         for ((i = 0; i < 128; i++)); do
18071                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18072                         error "cannot create file"
18073         done
18074
18075         sync
18076
18077         do_facet ost1 killall -TERM ofd_access_log_reader
18078         wait
18079         rc=$?
18080         if ((rc != 0)); then
18081                 error "ofd_access_log_reader exited with rc = '${rc}'"
18082         fi
18083
18084         unlinkmany  "${file}-%d" 128
18085 }
18086 run_test 165c "full ofd access logs do not block IOs"
18087
18088 oal_get_read_count() {
18089         local stats="$1"
18090
18091         # STATS lustre-OST0001 alr_read_count 1
18092
18093         do_facet ost1 cat "${stats}" |
18094         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18095              END { print count; }'
18096 }
18097
18098 oal_expect_read_count() {
18099         local stats="$1"
18100         local count
18101         local expect="$2"
18102
18103         # Ask ofd_access_log_reader to write stats.
18104         do_facet ost1 killall -USR1 ofd_access_log_reader
18105
18106         # Allow some time for things to happen.
18107         sleep 1
18108
18109         count=$(oal_get_read_count "${stats}")
18110         if ((count == expect)); then
18111                 return 0
18112         fi
18113
18114         error_noexit "bad read count, got ${count}, expected ${expect}"
18115         do_facet ost1 cat "${stats}" >&2
18116         exit 1
18117 }
18118
18119 test_165d() {
18120         local stats="/tmp/${tfile}.stats"
18121         local file="${DIR}/${tdir}/${tfile}"
18122         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18123
18124         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18125                 skip "OFD access log unsupported"
18126
18127         test_mkdir "${DIR}/${tdir}"
18128
18129         setup_165
18130         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18131         sleep 5
18132
18133         lfs setstripe -c 1 -i 0 "${file}"
18134
18135         do_facet ost1 lctl set_param "${param}=rw"
18136         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18137                 error "cannot create '${file}'"
18138         oal_expect_read_count "${stats}" 1
18139
18140         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18141                 error "cannot read '${file}'"
18142         oal_expect_read_count "${stats}" 2
18143
18144         do_facet ost1 lctl set_param "${param}=r"
18145         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18146                 error "cannot create '${file}'"
18147         oal_expect_read_count "${stats}" 2
18148
18149         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18150                 error "cannot read '${file}'"
18151         oal_expect_read_count "${stats}" 3
18152
18153         do_facet ost1 lctl set_param "${param}=w"
18154         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18155                 error "cannot create '${file}'"
18156         oal_expect_read_count "${stats}" 4
18157
18158         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18159                 error "cannot read '${file}'"
18160         oal_expect_read_count "${stats}" 4
18161
18162         do_facet ost1 lctl set_param "${param}=0"
18163         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18164                 error "cannot create '${file}'"
18165         oal_expect_read_count "${stats}" 4
18166
18167         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18168                 error "cannot read '${file}'"
18169         oal_expect_read_count "${stats}" 4
18170
18171         do_facet ost1 killall -TERM ofd_access_log_reader
18172         wait
18173         rc=$?
18174         if ((rc != 0)); then
18175                 error "ofd_access_log_reader exited with rc = '${rc}'"
18176         fi
18177 }
18178 run_test 165d "ofd_access_log mask works"
18179
18180 test_165e() {
18181         local stats="/tmp/${tfile}.stats"
18182         local file0="${DIR}/${tdir}-0/${tfile}"
18183         local file1="${DIR}/${tdir}-1/${tfile}"
18184
18185         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18186                 skip "OFD access log unsupported"
18187
18188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18189
18190         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18191         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18192
18193         lfs setstripe -c 1 -i 0 "${file0}"
18194         lfs setstripe -c 1 -i 0 "${file1}"
18195
18196         setup_165
18197         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18198         sleep 5
18199
18200         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18201                 error "cannot create '${file0}'"
18202         sync
18203         oal_expect_read_count "${stats}" 0
18204
18205         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18206                 error "cannot create '${file1}'"
18207         sync
18208         oal_expect_read_count "${stats}" 1
18209
18210         do_facet ost1 killall -TERM ofd_access_log_reader
18211         wait
18212         rc=$?
18213         if ((rc != 0)); then
18214                 error "ofd_access_log_reader exited with rc = '${rc}'"
18215         fi
18216 }
18217 run_test 165e "ofd_access_log MDT index filter works"
18218
18219 test_165f() {
18220         local trace="/tmp/${tfile}.trace"
18221         local rc
18222         local count
18223
18224         setup_165
18225         do_facet ost1 timeout 60 ofd_access_log_reader \
18226                 --exit-on-close --debug=- --trace=- > "${trace}" &
18227         sleep 5
18228         stop ost1
18229
18230         wait
18231         rc=$?
18232
18233         if ((rc != 0)); then
18234                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18235                 cat "${trace}"
18236                 exit 1
18237         fi
18238 }
18239 run_test 165f "ofd_access_log_reader --exit-on-close works"
18240
18241 test_169() {
18242         # do directio so as not to populate the page cache
18243         log "creating a 10 Mb file"
18244         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18245                 error "multiop failed while creating a file"
18246         log "starting reads"
18247         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18248         log "truncating the file"
18249         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18250                 error "multiop failed while truncating the file"
18251         log "killing dd"
18252         kill %+ || true # reads might have finished
18253         echo "wait until dd is finished"
18254         wait
18255         log "removing the temporary file"
18256         rm -rf $DIR/$tfile || error "tmp file removal failed"
18257 }
18258 run_test 169 "parallel read and truncate should not deadlock"
18259
18260 test_170() {
18261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18262
18263         $LCTL clear     # bug 18514
18264         $LCTL debug_daemon start $TMP/${tfile}_log_good
18265         touch $DIR/$tfile
18266         $LCTL debug_daemon stop
18267         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18268                 error "sed failed to read log_good"
18269
18270         $LCTL debug_daemon start $TMP/${tfile}_log_good
18271         rm -rf $DIR/$tfile
18272         $LCTL debug_daemon stop
18273
18274         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18275                error "lctl df log_bad failed"
18276
18277         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18278         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18279
18280         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18281         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18282
18283         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18284                 error "bad_line good_line1 good_line2 are empty"
18285
18286         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18287         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18288         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18289
18290         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18291         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18292         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18293
18294         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18295                 error "bad_line_new good_line_new are empty"
18296
18297         local expected_good=$((good_line1 + good_line2*2))
18298
18299         rm -f $TMP/${tfile}*
18300         # LU-231, short malformed line may not be counted into bad lines
18301         if [ $bad_line -ne $bad_line_new ] &&
18302                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18303                 error "expected $bad_line bad lines, but got $bad_line_new"
18304                 return 1
18305         fi
18306
18307         if [ $expected_good -ne $good_line_new ]; then
18308                 error "expected $expected_good good lines, but got $good_line_new"
18309                 return 2
18310         fi
18311         true
18312 }
18313 run_test 170 "test lctl df to handle corrupted log ====================="
18314
18315 test_171() { # bug20592
18316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18317
18318         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18319         $LCTL set_param fail_loc=0x50e
18320         $LCTL set_param fail_val=3000
18321         multiop_bg_pause $DIR/$tfile O_s || true
18322         local MULTIPID=$!
18323         kill -USR1 $MULTIPID
18324         # cause log dump
18325         sleep 3
18326         wait $MULTIPID
18327         if dmesg | grep "recursive fault"; then
18328                 error "caught a recursive fault"
18329         fi
18330         $LCTL set_param fail_loc=0
18331         true
18332 }
18333 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18334
18335 test_172() {
18336
18337         #define OBD_FAIL_OBD_CLEANUP  0x60e
18338         $LCTL set_param fail_loc=0x60e
18339         umount $MOUNT || error "umount $MOUNT failed"
18340         stack_trap "mount_client $MOUNT"
18341
18342         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18343                 error "no client OBDs are remained"
18344
18345         $LCTL dl | while read devno state type name foo; do
18346                 case $type in
18347                 lov|osc|lmv|mdc)
18348                         $LCTL --device $name cleanup
18349                         $LCTL --device $name detach
18350                         ;;
18351                 *)
18352                         # skip server devices
18353                         ;;
18354                 esac
18355         done
18356
18357         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18358                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18359                 error "some client OBDs are still remained"
18360         fi
18361
18362 }
18363 run_test 172 "manual device removal with lctl cleanup/detach ======"
18364
18365 # it would be good to share it with obdfilter-survey/iokit-libecho code
18366 setup_obdecho_osc () {
18367         local rc=0
18368         local ost_nid=$1
18369         local obdfilter_name=$2
18370         echo "Creating new osc for $obdfilter_name on $ost_nid"
18371         # make sure we can find loopback nid
18372         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18373
18374         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18375                            ${obdfilter_name}_osc_UUID || rc=2; }
18376         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18377                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18378         return $rc
18379 }
18380
18381 cleanup_obdecho_osc () {
18382         local obdfilter_name=$1
18383         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18384         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18385         return 0
18386 }
18387
18388 obdecho_test() {
18389         local OBD=$1
18390         local node=$2
18391         local pages=${3:-64}
18392         local rc=0
18393         local id
18394
18395         local count=10
18396         local obd_size=$(get_obd_size $node $OBD)
18397         local page_size=$(get_page_size $node)
18398         if [[ -n "$obd_size" ]]; then
18399                 local new_count=$((obd_size / (pages * page_size / 1024)))
18400                 [[ $new_count -ge $count ]] || count=$new_count
18401         fi
18402
18403         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18404         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18405                            rc=2; }
18406         if [ $rc -eq 0 ]; then
18407             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18408             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18409         fi
18410         echo "New object id is $id"
18411         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18412                            rc=4; }
18413         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18414                            "test_brw $count w v $pages $id" || rc=4; }
18415         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18416                            rc=4; }
18417         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18418                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18419         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18420                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18421         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18422         return $rc
18423 }
18424
18425 test_180a() {
18426         skip "obdecho on osc is no longer supported"
18427 }
18428 run_test 180a "test obdecho on osc"
18429
18430 test_180b() {
18431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18432         remote_ost_nodsh && skip "remote OST with nodsh"
18433
18434         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18435                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18436                 error "failed to load module obdecho"
18437
18438         local target=$(do_facet ost1 $LCTL dl |
18439                        awk '/obdfilter/ { print $4; exit; }')
18440
18441         if [ -n "$target" ]; then
18442                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18443         else
18444                 do_facet ost1 $LCTL dl
18445                 error "there is no obdfilter target on ost1"
18446         fi
18447 }
18448 run_test 180b "test obdecho directly on obdfilter"
18449
18450 test_180c() { # LU-2598
18451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18452         remote_ost_nodsh && skip "remote OST with nodsh"
18453         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18454                 skip "Need MDS version at least 2.4.0"
18455
18456         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18457                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18458                 error "failed to load module obdecho"
18459
18460         local target=$(do_facet ost1 $LCTL dl |
18461                        awk '/obdfilter/ { print $4; exit; }')
18462
18463         if [ -n "$target" ]; then
18464                 local pages=16384 # 64MB bulk I/O RPC size
18465
18466                 obdecho_test "$target" ost1 "$pages" ||
18467                         error "obdecho_test with pages=$pages failed with $?"
18468         else
18469                 do_facet ost1 $LCTL dl
18470                 error "there is no obdfilter target on ost1"
18471         fi
18472 }
18473 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18474
18475 test_181() { # bug 22177
18476         test_mkdir $DIR/$tdir
18477         # create enough files to index the directory
18478         createmany -o $DIR/$tdir/foobar 4000
18479         # print attributes for debug purpose
18480         lsattr -d .
18481         # open dir
18482         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18483         MULTIPID=$!
18484         # remove the files & current working dir
18485         unlinkmany $DIR/$tdir/foobar 4000
18486         rmdir $DIR/$tdir
18487         kill -USR1 $MULTIPID
18488         wait $MULTIPID
18489         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18490         return 0
18491 }
18492 run_test 181 "Test open-unlinked dir ========================"
18493
18494 test_182a() {
18495         local fcount=1000
18496         local tcount=10
18497
18498         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18499
18500         $LCTL set_param mdc.*.rpc_stats=clear
18501
18502         for (( i = 0; i < $tcount; i++ )) ; do
18503                 mkdir $DIR/$tdir/$i
18504         done
18505
18506         for (( i = 0; i < $tcount; i++ )) ; do
18507                 createmany -o $DIR/$tdir/$i/f- $fcount &
18508         done
18509         wait
18510
18511         for (( i = 0; i < $tcount; i++ )) ; do
18512                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18513         done
18514         wait
18515
18516         $LCTL get_param mdc.*.rpc_stats
18517
18518         rm -rf $DIR/$tdir
18519 }
18520 run_test 182a "Test parallel modify metadata operations from mdc"
18521
18522 test_182b() {
18523         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18524         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18525         local dcount=1000
18526         local tcount=10
18527         local stime
18528         local etime
18529         local delta
18530
18531         do_facet mds1 $LCTL list_param \
18532                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18533                 skip "MDS lacks parallel RPC handling"
18534
18535         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18536
18537         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18538                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18539
18540         stime=$(date +%s)
18541         createmany -i 0 -d $DIR/$tdir/t- $tcount
18542
18543         for (( i = 0; i < $tcount; i++ )) ; do
18544                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18545         done
18546         wait
18547         etime=$(date +%s)
18548         delta=$((etime - stime))
18549         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18550
18551         stime=$(date +%s)
18552         for (( i = 0; i < $tcount; i++ )) ; do
18553                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18554         done
18555         wait
18556         etime=$(date +%s)
18557         delta=$((etime - stime))
18558         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18559
18560         rm -rf $DIR/$tdir
18561
18562         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18563
18564         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18565
18566         stime=$(date +%s)
18567         createmany -i 0 -d $DIR/$tdir/t- $tcount
18568
18569         for (( i = 0; i < $tcount; i++ )) ; do
18570                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18571         done
18572         wait
18573         etime=$(date +%s)
18574         delta=$((etime - stime))
18575         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18576
18577         stime=$(date +%s)
18578         for (( i = 0; i < $tcount; i++ )) ; do
18579                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18580         done
18581         wait
18582         etime=$(date +%s)
18583         delta=$((etime - stime))
18584         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18585
18586         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18587 }
18588 run_test 182b "Test parallel modify metadata operations from osp"
18589
18590 test_183() { # LU-2275
18591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18592         remote_mds_nodsh && skip "remote MDS with nodsh"
18593         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18594                 skip "Need MDS version at least 2.3.56"
18595
18596         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18597         echo aaa > $DIR/$tdir/$tfile
18598
18599 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18600         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18601
18602         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18603         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18604
18605         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18606
18607         # Flush negative dentry cache
18608         touch $DIR/$tdir/$tfile
18609
18610         # We are not checking for any leaked references here, they'll
18611         # become evident next time we do cleanup with module unload.
18612         rm -rf $DIR/$tdir
18613 }
18614 run_test 183 "No crash or request leak in case of strange dispositions ========"
18615
18616 # test suite 184 is for LU-2016, LU-2017
18617 test_184a() {
18618         check_swap_layouts_support
18619
18620         dir0=$DIR/$tdir/$testnum
18621         test_mkdir -p -c1 $dir0
18622         ref1=/etc/passwd
18623         ref2=/etc/group
18624         file1=$dir0/f1
18625         file2=$dir0/f2
18626         $LFS setstripe -c1 $file1
18627         cp $ref1 $file1
18628         $LFS setstripe -c2 $file2
18629         cp $ref2 $file2
18630         gen1=$($LFS getstripe -g $file1)
18631         gen2=$($LFS getstripe -g $file2)
18632
18633         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18634         gen=$($LFS getstripe -g $file1)
18635         [[ $gen1 != $gen ]] ||
18636                 error "Layout generation on $file1 does not change"
18637         gen=$($LFS getstripe -g $file2)
18638         [[ $gen2 != $gen ]] ||
18639                 error "Layout generation on $file2 does not change"
18640
18641         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18642         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18643
18644         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18645 }
18646 run_test 184a "Basic layout swap"
18647
18648 test_184b() {
18649         check_swap_layouts_support
18650
18651         dir0=$DIR/$tdir/$testnum
18652         mkdir -p $dir0 || error "creating dir $dir0"
18653         file1=$dir0/f1
18654         file2=$dir0/f2
18655         file3=$dir0/f3
18656         dir1=$dir0/d1
18657         dir2=$dir0/d2
18658         mkdir $dir1 $dir2
18659         $LFS setstripe -c1 $file1
18660         $LFS setstripe -c2 $file2
18661         $LFS setstripe -c1 $file3
18662         chown $RUNAS_ID $file3
18663         gen1=$($LFS getstripe -g $file1)
18664         gen2=$($LFS getstripe -g $file2)
18665
18666         $LFS swap_layouts $dir1 $dir2 &&
18667                 error "swap of directories layouts should fail"
18668         $LFS swap_layouts $dir1 $file1 &&
18669                 error "swap of directory and file layouts should fail"
18670         $RUNAS $LFS swap_layouts $file1 $file2 &&
18671                 error "swap of file we cannot write should fail"
18672         $LFS swap_layouts $file1 $file3 &&
18673                 error "swap of file with different owner should fail"
18674         /bin/true # to clear error code
18675 }
18676 run_test 184b "Forbidden layout swap (will generate errors)"
18677
18678 test_184c() {
18679         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18680         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18681         check_swap_layouts_support
18682         check_swap_layout_no_dom $DIR
18683
18684         local dir0=$DIR/$tdir/$testnum
18685         mkdir -p $dir0 || error "creating dir $dir0"
18686
18687         local ref1=$dir0/ref1
18688         local ref2=$dir0/ref2
18689         local file1=$dir0/file1
18690         local file2=$dir0/file2
18691         # create a file large enough for the concurrent test
18692         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18693         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18694         echo "ref file size: ref1($(stat -c %s $ref1))," \
18695              "ref2($(stat -c %s $ref2))"
18696
18697         cp $ref2 $file2
18698         dd if=$ref1 of=$file1 bs=16k &
18699         local DD_PID=$!
18700
18701         # Make sure dd starts to copy file, but wait at most 5 seconds
18702         local loops=0
18703         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18704
18705         $LFS swap_layouts $file1 $file2
18706         local rc=$?
18707         wait $DD_PID
18708         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18709         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18710
18711         # how many bytes copied before swapping layout
18712         local copied=$(stat -c %s $file2)
18713         local remaining=$(stat -c %s $ref1)
18714         remaining=$((remaining - copied))
18715         echo "Copied $copied bytes before swapping layout..."
18716
18717         cmp -n $copied $file1 $ref2 | grep differ &&
18718                 error "Content mismatch [0, $copied) of ref2 and file1"
18719         cmp -n $copied $file2 $ref1 ||
18720                 error "Content mismatch [0, $copied) of ref1 and file2"
18721         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18722                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18723
18724         # clean up
18725         rm -f $ref1 $ref2 $file1 $file2
18726 }
18727 run_test 184c "Concurrent write and layout swap"
18728
18729 test_184d() {
18730         check_swap_layouts_support
18731         check_swap_layout_no_dom $DIR
18732         [ -z "$(which getfattr 2>/dev/null)" ] &&
18733                 skip_env "no getfattr command"
18734
18735         local file1=$DIR/$tdir/$tfile-1
18736         local file2=$DIR/$tdir/$tfile-2
18737         local file3=$DIR/$tdir/$tfile-3
18738         local lovea1
18739         local lovea2
18740
18741         mkdir -p $DIR/$tdir
18742         touch $file1 || error "create $file1 failed"
18743         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18744                 error "create $file2 failed"
18745         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18746                 error "create $file3 failed"
18747         lovea1=$(get_layout_param $file1)
18748
18749         $LFS swap_layouts $file2 $file3 ||
18750                 error "swap $file2 $file3 layouts failed"
18751         $LFS swap_layouts $file1 $file2 ||
18752                 error "swap $file1 $file2 layouts failed"
18753
18754         lovea2=$(get_layout_param $file2)
18755         echo "$lovea1"
18756         echo "$lovea2"
18757         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18758
18759         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18760         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18761 }
18762 run_test 184d "allow stripeless layouts swap"
18763
18764 test_184e() {
18765         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18766                 skip "Need MDS version at least 2.6.94"
18767         check_swap_layouts_support
18768         check_swap_layout_no_dom $DIR
18769         [ -z "$(which getfattr 2>/dev/null)" ] &&
18770                 skip_env "no getfattr command"
18771
18772         local file1=$DIR/$tdir/$tfile-1
18773         local file2=$DIR/$tdir/$tfile-2
18774         local file3=$DIR/$tdir/$tfile-3
18775         local lovea
18776
18777         mkdir -p $DIR/$tdir
18778         touch $file1 || error "create $file1 failed"
18779         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18780                 error "create $file2 failed"
18781         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18782                 error "create $file3 failed"
18783
18784         $LFS swap_layouts $file1 $file2 ||
18785                 error "swap $file1 $file2 layouts failed"
18786
18787         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18788         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18789
18790         echo 123 > $file1 || error "Should be able to write into $file1"
18791
18792         $LFS swap_layouts $file1 $file3 ||
18793                 error "swap $file1 $file3 layouts failed"
18794
18795         echo 123 > $file1 || error "Should be able to write into $file1"
18796
18797         rm -rf $file1 $file2 $file3
18798 }
18799 run_test 184e "Recreate layout after stripeless layout swaps"
18800
18801 test_184f() {
18802         # Create a file with name longer than sizeof(struct stat) ==
18803         # 144 to see if we can get chars from the file name to appear
18804         # in the returned striping. Note that 'f' == 0x66.
18805         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18806
18807         mkdir -p $DIR/$tdir
18808         mcreate $DIR/$tdir/$file
18809         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18810                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18811         fi
18812 }
18813 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18814
18815 test_185() { # LU-2441
18816         # LU-3553 - no volatile file support in old servers
18817         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18818                 skip "Need MDS version at least 2.3.60"
18819
18820         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18821         touch $DIR/$tdir/spoo
18822         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18823         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18824                 error "cannot create/write a volatile file"
18825         [ "$FILESET" == "" ] &&
18826         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18827                 error "FID is still valid after close"
18828
18829         multiop_bg_pause $DIR/$tdir vVw4096_c
18830         local multi_pid=$!
18831
18832         local OLD_IFS=$IFS
18833         IFS=":"
18834         local fidv=($fid)
18835         IFS=$OLD_IFS
18836         # assume that the next FID for this client is sequential, since stdout
18837         # is unfortunately eaten by multiop_bg_pause
18838         local n=$((${fidv[1]} + 1))
18839         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18840         if [ "$FILESET" == "" ]; then
18841                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18842                         error "FID is missing before close"
18843         fi
18844         kill -USR1 $multi_pid
18845         # 1 second delay, so if mtime change we will see it
18846         sleep 1
18847         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18848         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18849 }
18850 run_test 185 "Volatile file support"
18851
18852 function create_check_volatile() {
18853         local idx=$1
18854         local tgt
18855
18856         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18857         local PID=$!
18858         sleep 1
18859         local FID=$(cat /tmp/${tfile}.fid)
18860         [ "$FID" == "" ] && error "can't get FID for volatile"
18861         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18862         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18863         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18864         kill -USR1 $PID
18865         wait
18866         sleep 1
18867         cancel_lru_locks mdc # flush opencache
18868         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18869         return 0
18870 }
18871
18872 test_185a(){
18873         # LU-12516 - volatile creation via .lustre
18874         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18875                 skip "Need MDS version at least 2.3.55"
18876
18877         create_check_volatile 0
18878         [ $MDSCOUNT -lt 2 ] && return 0
18879
18880         # DNE case
18881         create_check_volatile 1
18882
18883         return 0
18884 }
18885 run_test 185a "Volatile file creation in .lustre/fid/"
18886
18887 test_187a() {
18888         remote_mds_nodsh && skip "remote MDS with nodsh"
18889         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18890                 skip "Need MDS version at least 2.3.0"
18891
18892         local dir0=$DIR/$tdir/$testnum
18893         mkdir -p $dir0 || error "creating dir $dir0"
18894
18895         local file=$dir0/file1
18896         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18897         local dv1=$($LFS data_version $file)
18898         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18899         local dv2=$($LFS data_version $file)
18900         [[ $dv1 != $dv2 ]] ||
18901                 error "data version did not change on write $dv1 == $dv2"
18902
18903         # clean up
18904         rm -f $file1
18905 }
18906 run_test 187a "Test data version change"
18907
18908 test_187b() {
18909         remote_mds_nodsh && skip "remote MDS with nodsh"
18910         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18911                 skip "Need MDS version at least 2.3.0"
18912
18913         local dir0=$DIR/$tdir/$testnum
18914         mkdir -p $dir0 || error "creating dir $dir0"
18915
18916         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18917         [[ ${DV[0]} != ${DV[1]} ]] ||
18918                 error "data version did not change on write"\
18919                       " ${DV[0]} == ${DV[1]}"
18920
18921         # clean up
18922         rm -f $file1
18923 }
18924 run_test 187b "Test data version change on volatile file"
18925
18926 test_200() {
18927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18928         remote_mgs_nodsh && skip "remote MGS with nodsh"
18929         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18930
18931         local POOL=${POOL:-cea1}
18932         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18933         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18934         # Pool OST targets
18935         local first_ost=0
18936         local last_ost=$(($OSTCOUNT - 1))
18937         local ost_step=2
18938         local ost_list=$(seq $first_ost $ost_step $last_ost)
18939         local ost_range="$first_ost $last_ost $ost_step"
18940         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18941         local file_dir=$POOL_ROOT/file_tst
18942         local subdir=$test_path/subdir
18943         local rc=0
18944
18945         while : ; do
18946                 # former test_200a test_200b
18947                 pool_add $POOL                          || { rc=$? ; break; }
18948                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18949                 # former test_200c test_200d
18950                 mkdir -p $test_path
18951                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18952                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18953                 mkdir -p $subdir
18954                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18955                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18956                                                         || { rc=$? ; break; }
18957                 # former test_200e test_200f
18958                 local files=$((OSTCOUNT*3))
18959                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18960                                                         || { rc=$? ; break; }
18961                 pool_create_files $POOL $file_dir $files "$ost_list" \
18962                                                         || { rc=$? ; break; }
18963                 # former test_200g test_200h
18964                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18965                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18966
18967                 # former test_201a test_201b test_201c
18968                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18969
18970                 local f=$test_path/$tfile
18971                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18972                 pool_remove $POOL $f                    || { rc=$? ; break; }
18973                 break
18974         done
18975
18976         destroy_test_pools
18977
18978         return $rc
18979 }
18980 run_test 200 "OST pools"
18981
18982 # usage: default_attr <count | size | offset>
18983 default_attr() {
18984         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18985 }
18986
18987 # usage: check_default_stripe_attr
18988 check_default_stripe_attr() {
18989         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18990         case $1 in
18991         --stripe-count|-c)
18992                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18993         --stripe-size|-S)
18994                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18995         --stripe-index|-i)
18996                 EXPECTED=-1;;
18997         *)
18998                 error "unknown getstripe attr '$1'"
18999         esac
19000
19001         [ $ACTUAL == $EXPECTED ] ||
19002                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19003 }
19004
19005 test_204a() {
19006         test_mkdir $DIR/$tdir
19007         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19008
19009         check_default_stripe_attr --stripe-count
19010         check_default_stripe_attr --stripe-size
19011         check_default_stripe_attr --stripe-index
19012 }
19013 run_test 204a "Print default stripe attributes"
19014
19015 test_204b() {
19016         test_mkdir $DIR/$tdir
19017         $LFS setstripe --stripe-count 1 $DIR/$tdir
19018
19019         check_default_stripe_attr --stripe-size
19020         check_default_stripe_attr --stripe-index
19021 }
19022 run_test 204b "Print default stripe size and offset"
19023
19024 test_204c() {
19025         test_mkdir $DIR/$tdir
19026         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19027
19028         check_default_stripe_attr --stripe-count
19029         check_default_stripe_attr --stripe-index
19030 }
19031 run_test 204c "Print default stripe count and offset"
19032
19033 test_204d() {
19034         test_mkdir $DIR/$tdir
19035         $LFS setstripe --stripe-index 0 $DIR/$tdir
19036
19037         check_default_stripe_attr --stripe-count
19038         check_default_stripe_attr --stripe-size
19039 }
19040 run_test 204d "Print default stripe count and size"
19041
19042 test_204e() {
19043         test_mkdir $DIR/$tdir
19044         $LFS setstripe -d $DIR/$tdir
19045
19046         check_default_stripe_attr --stripe-count --raw
19047         check_default_stripe_attr --stripe-size --raw
19048         check_default_stripe_attr --stripe-index --raw
19049 }
19050 run_test 204e "Print raw stripe attributes"
19051
19052 test_204f() {
19053         test_mkdir $DIR/$tdir
19054         $LFS setstripe --stripe-count 1 $DIR/$tdir
19055
19056         check_default_stripe_attr --stripe-size --raw
19057         check_default_stripe_attr --stripe-index --raw
19058 }
19059 run_test 204f "Print raw stripe size and offset"
19060
19061 test_204g() {
19062         test_mkdir $DIR/$tdir
19063         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19064
19065         check_default_stripe_attr --stripe-count --raw
19066         check_default_stripe_attr --stripe-index --raw
19067 }
19068 run_test 204g "Print raw stripe count and offset"
19069
19070 test_204h() {
19071         test_mkdir $DIR/$tdir
19072         $LFS setstripe --stripe-index 0 $DIR/$tdir
19073
19074         check_default_stripe_attr --stripe-count --raw
19075         check_default_stripe_attr --stripe-size --raw
19076 }
19077 run_test 204h "Print raw stripe count and size"
19078
19079 # Figure out which job scheduler is being used, if any,
19080 # or use a fake one
19081 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19082         JOBENV=SLURM_JOB_ID
19083 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19084         JOBENV=LSB_JOBID
19085 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19086         JOBENV=PBS_JOBID
19087 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19088         JOBENV=LOADL_STEP_ID
19089 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19090         JOBENV=JOB_ID
19091 else
19092         $LCTL list_param jobid_name > /dev/null 2>&1
19093         if [ $? -eq 0 ]; then
19094                 JOBENV=nodelocal
19095         else
19096                 JOBENV=FAKE_JOBID
19097         fi
19098 fi
19099 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19100
19101 verify_jobstats() {
19102         local cmd=($1)
19103         shift
19104         local facets="$@"
19105
19106 # we don't really need to clear the stats for this test to work, since each
19107 # command has a unique jobid, but it makes debugging easier if needed.
19108 #       for facet in $facets; do
19109 #               local dev=$(convert_facet2label $facet)
19110 #               # clear old jobstats
19111 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19112 #       done
19113
19114         # use a new JobID for each test, or we might see an old one
19115         [ "$JOBENV" = "FAKE_JOBID" ] &&
19116                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19117
19118         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19119
19120         [ "$JOBENV" = "nodelocal" ] && {
19121                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19122                 $LCTL set_param jobid_name=$FAKE_JOBID
19123                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19124         }
19125
19126         log "Test: ${cmd[*]}"
19127         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19128
19129         if [ $JOBENV = "FAKE_JOBID" ]; then
19130                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19131         else
19132                 ${cmd[*]}
19133         fi
19134
19135         # all files are created on OST0000
19136         for facet in $facets; do
19137                 local stats="*.$(convert_facet2label $facet).job_stats"
19138
19139                 # strip out libtool wrappers for in-tree executables
19140                 if (( $(do_facet $facet lctl get_param $stats |
19141                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19142                         do_facet $facet lctl get_param $stats
19143                         error "No jobstats for $JOBVAL found on $facet::$stats"
19144                 fi
19145         done
19146 }
19147
19148 jobstats_set() {
19149         local new_jobenv=$1
19150
19151         set_persistent_param_and_check client "jobid_var" \
19152                 "$FSNAME.sys.jobid_var" $new_jobenv
19153 }
19154
19155 test_205a() { # Job stats
19156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19157         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19158                 skip "Need MDS version with at least 2.7.1"
19159         remote_mgs_nodsh && skip "remote MGS with nodsh"
19160         remote_mds_nodsh && skip "remote MDS with nodsh"
19161         remote_ost_nodsh && skip "remote OST with nodsh"
19162         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19163                 skip "Server doesn't support jobstats"
19164         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19165
19166         local old_jobenv=$($LCTL get_param -n jobid_var)
19167         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19168
19169         if [[ $PERM_CMD == *"set_param -P"* ]]; then
19170                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
19171         else
19172                 stack_trap "do_facet mgs $PERM_CMD \
19173                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
19174         fi
19175         changelog_register
19176
19177         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19178                                 mdt.*.job_cleanup_interval | head -n 1)
19179         local new_interval=5
19180         do_facet $SINGLEMDS \
19181                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19182         stack_trap "do_facet $SINGLEMDS \
19183                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19184         local start=$SECONDS
19185
19186         local cmd
19187         # mkdir
19188         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19189         verify_jobstats "$cmd" "$SINGLEMDS"
19190         # rmdir
19191         cmd="rmdir $DIR/$tdir"
19192         verify_jobstats "$cmd" "$SINGLEMDS"
19193         # mkdir on secondary MDT
19194         if [ $MDSCOUNT -gt 1 ]; then
19195                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19196                 verify_jobstats "$cmd" "mds2"
19197         fi
19198         # mknod
19199         cmd="mknod $DIR/$tfile c 1 3"
19200         verify_jobstats "$cmd" "$SINGLEMDS"
19201         # unlink
19202         cmd="rm -f $DIR/$tfile"
19203         verify_jobstats "$cmd" "$SINGLEMDS"
19204         # create all files on OST0000 so verify_jobstats can find OST stats
19205         # open & close
19206         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19207         verify_jobstats "$cmd" "$SINGLEMDS"
19208         # setattr
19209         cmd="touch $DIR/$tfile"
19210         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19211         # write
19212         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19213         verify_jobstats "$cmd" "ost1"
19214         # read
19215         cancel_lru_locks osc
19216         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19217         verify_jobstats "$cmd" "ost1"
19218         # truncate
19219         cmd="$TRUNCATE $DIR/$tfile 0"
19220         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19221         # rename
19222         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19223         verify_jobstats "$cmd" "$SINGLEMDS"
19224         # jobstats expiry - sleep until old stats should be expired
19225         local left=$((new_interval + 5 - (SECONDS - start)))
19226         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19227                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19228                         "0" $left
19229         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19230         verify_jobstats "$cmd" "$SINGLEMDS"
19231         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19232             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19233
19234         # Ensure that jobid are present in changelog (if supported by MDS)
19235         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19236                 changelog_dump | tail -10
19237                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19238                 [ $jobids -eq 9 ] ||
19239                         error "Wrong changelog jobid count $jobids != 9"
19240
19241                 # LU-5862
19242                 JOBENV="disable"
19243                 jobstats_set $JOBENV
19244                 touch $DIR/$tfile
19245                 changelog_dump | grep $tfile
19246                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19247                 [ $jobids -eq 0 ] ||
19248                         error "Unexpected jobids when jobid_var=$JOBENV"
19249         fi
19250
19251         # test '%j' access to environment variable - if supported
19252         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19253                 JOBENV="JOBCOMPLEX"
19254                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19255
19256                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19257         fi
19258
19259         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19260                 JOBENV="JOBCOMPLEX"
19261                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19262
19263                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19264         fi
19265
19266         # test '%j' access to per-session jobid - if supported
19267         if lctl list_param jobid_this_session > /dev/null 2>&1
19268         then
19269                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19270                 lctl set_param jobid_this_session=$USER
19271
19272                 JOBENV="JOBCOMPLEX"
19273                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19274
19275                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19276         fi
19277 }
19278 run_test 205a "Verify job stats"
19279
19280 # LU-13117, LU-13597
19281 test_205b() {
19282         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19283                 skip "Need MDS version at least 2.13.54.91"
19284
19285         local job_stats="mdt.*.job_stats"
19286         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19287
19288         do_facet mds1 $LCTL set_param $job_stats=clear
19289
19290         # Setting jobid_var to USER might not be supported
19291         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19292         $LCTL set_param jobid_var=USER || true
19293         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19294         $LCTL set_param jobid_name="%j.%e.%u"
19295
19296         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19297         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19298                 { do_facet mds1 $LCTL get_param $job_stats;
19299                   error "Unexpected jobid found"; }
19300         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19301                 { do_facet mds1 $LCTL get_param $job_stats;
19302                   error "wrong job_stats format found"; }
19303
19304         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19305                 echo "MDS does not yet escape jobid" && return 0
19306         $LCTL set_param jobid_var=TEST205b
19307         env -i TEST205b="has sp" touch $DIR/$tfile.2
19308         do_facet mds1 $LCTL get_param $job_stats | grep "has.*x20sp" ||
19309                 { do_facet mds1 $LCTL get_param $job_stats;
19310                   error "jobid not escaped"; }
19311 }
19312 run_test 205b "Verify job stats jobid and output format"
19313
19314 # LU-13733
19315 test_205c() {
19316         $LCTL set_param llite.*.stats=0
19317         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19318         $LCTL get_param llite.*.stats
19319         $LCTL get_param llite.*.stats | grep \
19320                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19321                         error "wrong client stats format found"
19322 }
19323 run_test 205c "Verify client stats format"
19324
19325 test_205d() {
19326         local file=$DIR/$tdir/$tfile
19327
19328         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19329                 skip "need lustre >= 2.15.53 for lljobstat"
19330         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19331                 skip "need lustre >= 2.15.53 for lljobstat"
19332         verify_yaml_available || skip_env "YAML verification not installed"
19333
19334         test_mkdir -i 0 $DIR/$tdir
19335         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19336
19337         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19338                 error "failed to write data to $file"
19339         mv $file $file.2
19340
19341         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19342         echo -n 'verify rename_stats...'
19343         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19344                 verify_yaml || error "rename_stats is not valid YAML"
19345         echo " OK"
19346
19347         echo -n 'verify mdt job_stats...'
19348         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19349                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19350         echo " OK"
19351
19352         echo -n 'verify ost job_stats...'
19353         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19354                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19355         echo " OK"
19356 }
19357 run_test 205d "verify the format of some stats files"
19358
19359 test_205e() {
19360         local ops_comma
19361         local file=$DIR/$tdir/$tfile
19362
19363         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19364                 skip "need lustre >= 2.15.53 for lljobstat"
19365         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19366                 skip "need lustre >= 2.15.53 for lljobstat"
19367         verify_yaml_available || skip_env "YAML verification not installed"
19368
19369         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19370
19371         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19372                 error "failed to create $file on ost1"
19373         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19374                 error "failed to write data to $file"
19375
19376         do_facet mds1 "$LCTL get_param *.*.job_stats"
19377         do_facet ost1 "$LCTL get_param *.*.job_stats"
19378
19379         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19380         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19381                 error "The output of lljobstat is not an valid YAML"
19382
19383         # verify that job dd.0 does exist and has some ops on ost1
19384         # typically this line is like:
19385         # - dd.0:            {ops: 20, ...}
19386         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19387                     awk '$2=="dd.0:" {print $4}')
19388
19389         (( ${ops_comma%,} >= 10 )) ||
19390                 error "cannot find job dd.0 with ops >= 10"
19391 }
19392 run_test 205e "verify the output of lljobstat"
19393
19394 # LU-1480, LU-1773 and LU-1657
19395 test_206() {
19396         mkdir -p $DIR/$tdir
19397         $LFS setstripe -c -1 $DIR/$tdir
19398 #define OBD_FAIL_LOV_INIT 0x1403
19399         $LCTL set_param fail_loc=0xa0001403
19400         $LCTL set_param fail_val=1
19401         touch $DIR/$tdir/$tfile || true
19402 }
19403 run_test 206 "fail lov_init_raid0() doesn't lbug"
19404
19405 test_207a() {
19406         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19407         local fsz=`stat -c %s $DIR/$tfile`
19408         cancel_lru_locks mdc
19409
19410         # do not return layout in getattr intent
19411 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19412         $LCTL set_param fail_loc=0x170
19413         local sz=`stat -c %s $DIR/$tfile`
19414
19415         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19416
19417         rm -rf $DIR/$tfile
19418 }
19419 run_test 207a "can refresh layout at glimpse"
19420
19421 test_207b() {
19422         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19423         local cksum=`md5sum $DIR/$tfile`
19424         local fsz=`stat -c %s $DIR/$tfile`
19425         cancel_lru_locks mdc
19426         cancel_lru_locks osc
19427
19428         # do not return layout in getattr intent
19429 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19430         $LCTL set_param fail_loc=0x171
19431
19432         # it will refresh layout after the file is opened but before read issues
19433         echo checksum is "$cksum"
19434         echo "$cksum" |md5sum -c --quiet || error "file differs"
19435
19436         rm -rf $DIR/$tfile
19437 }
19438 run_test 207b "can refresh layout at open"
19439
19440 test_208() {
19441         # FIXME: in this test suite, only RD lease is used. This is okay
19442         # for now as only exclusive open is supported. After generic lease
19443         # is done, this test suite should be revised. - Jinshan
19444
19445         remote_mds_nodsh && skip "remote MDS with nodsh"
19446         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19447                 skip "Need MDS version at least 2.4.52"
19448
19449         echo "==== test 1: verify get lease work"
19450         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19451
19452         echo "==== test 2: verify lease can be broken by upcoming open"
19453         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19454         local PID=$!
19455         sleep 2
19456
19457         $MULTIOP $DIR/$tfile oO_RDWR:c
19458         kill -USR1 $PID && wait $PID || error "break lease error"
19459
19460         echo "==== test 3: verify lease can't be granted if an open already exists"
19461         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19462         local PID=$!
19463         sleep 2
19464
19465         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19466         kill -USR1 $PID && wait $PID || error "open file error"
19467
19468         echo "==== test 4: lease can sustain over recovery"
19469         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19470         PID=$!
19471         sleep 2
19472
19473         fail mds1
19474
19475         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19476
19477         echo "==== test 5: lease broken can't be regained by replay"
19478         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19479         PID=$!
19480         sleep 2
19481
19482         # open file to break lease and then recovery
19483         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19484         fail mds1
19485
19486         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19487
19488         rm -f $DIR/$tfile
19489 }
19490 run_test 208 "Exclusive open"
19491
19492 test_209() {
19493         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19494                 skip_env "must have disp_stripe"
19495
19496         touch $DIR/$tfile
19497         sync; sleep 5; sync;
19498
19499         echo 3 > /proc/sys/vm/drop_caches
19500         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19501                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19502         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19503
19504         # open/close 500 times
19505         for i in $(seq 500); do
19506                 cat $DIR/$tfile
19507         done
19508
19509         echo 3 > /proc/sys/vm/drop_caches
19510         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19511                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19512         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19513
19514         echo "before: $req_before, after: $req_after"
19515         [ $((req_after - req_before)) -ge 300 ] &&
19516                 error "open/close requests are not freed"
19517         return 0
19518 }
19519 run_test 209 "read-only open/close requests should be freed promptly"
19520
19521 test_210() {
19522         local pid
19523
19524         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19525         pid=$!
19526         sleep 1
19527
19528         $LFS getstripe $DIR/$tfile
19529         kill -USR1 $pid
19530         wait $pid || error "multiop failed"
19531
19532         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19533         pid=$!
19534         sleep 1
19535
19536         $LFS getstripe $DIR/$tfile
19537         kill -USR1 $pid
19538         wait $pid || error "multiop failed"
19539 }
19540 run_test 210 "lfs getstripe does not break leases"
19541
19542 test_212() {
19543         size=`date +%s`
19544         size=$((size % 8192 + 1))
19545         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19546         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19547         rm -f $DIR/f212 $DIR/f212.xyz
19548 }
19549 run_test 212 "Sendfile test ============================================"
19550
19551 test_213() {
19552         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19553         cancel_lru_locks osc
19554         lctl set_param fail_loc=0x8000040f
19555         # generate a read lock
19556         cat $DIR/$tfile > /dev/null
19557         # write to the file, it will try to cancel the above read lock.
19558         cat /etc/hosts >> $DIR/$tfile
19559 }
19560 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19561
19562 test_214() { # for bug 20133
19563         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19564         for (( i=0; i < 340; i++ )) ; do
19565                 touch $DIR/$tdir/d214c/a$i
19566         done
19567
19568         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19569         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19570         ls $DIR/d214c || error "ls $DIR/d214c failed"
19571         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19572         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19573 }
19574 run_test 214 "hash-indexed directory test - bug 20133"
19575
19576 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19577 create_lnet_proc_files() {
19578         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19579 }
19580
19581 # counterpart of create_lnet_proc_files
19582 remove_lnet_proc_files() {
19583         rm -f $TMP/lnet_$1.sys
19584 }
19585
19586 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19587 # 3rd arg as regexp for body
19588 check_lnet_proc_stats() {
19589         local l=$(cat "$TMP/lnet_$1" |wc -l)
19590         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19591
19592         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19593 }
19594
19595 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19596 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19597 # optional and can be regexp for 2nd line (lnet.routes case)
19598 check_lnet_proc_entry() {
19599         local blp=2          # blp stands for 'position of 1st line of body'
19600         [ -z "$5" ] || blp=3 # lnet.routes case
19601
19602         local l=$(cat "$TMP/lnet_$1" |wc -l)
19603         # subtracting one from $blp because the body can be empty
19604         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19605
19606         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19607                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19608
19609         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19610                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19611
19612         # bail out if any unexpected line happened
19613         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19614         [ "$?" != 0 ] || error "$2 misformatted"
19615 }
19616
19617 test_215() { # for bugs 18102, 21079, 21517
19618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19619
19620         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19621         local P='[1-9][0-9]*'           # positive numeric
19622         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19623         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19624         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19625         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19626
19627         local L1 # regexp for 1st line
19628         local L2 # regexp for 2nd line (optional)
19629         local BR # regexp for the rest (body)
19630
19631         # lnet.stats should look as 11 space-separated non-negative numerics
19632         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19633         create_lnet_proc_files "stats"
19634         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19635         remove_lnet_proc_files "stats"
19636
19637         # lnet.routes should look like this:
19638         # Routing disabled/enabled
19639         # net hops priority state router
19640         # where net is a string like tcp0, hops > 0, priority >= 0,
19641         # state is up/down,
19642         # router is a string like 192.168.1.1@tcp2
19643         L1="^Routing (disabled|enabled)$"
19644         L2="^net +hops +priority +state +router$"
19645         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19646         create_lnet_proc_files "routes"
19647         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19648         remove_lnet_proc_files "routes"
19649
19650         # lnet.routers should look like this:
19651         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19652         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19653         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19654         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19655         L1="^ref +rtr_ref +alive +router$"
19656         BR="^$P +$P +(up|down) +$NID$"
19657         create_lnet_proc_files "routers"
19658         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19659         remove_lnet_proc_files "routers"
19660
19661         # lnet.peers should look like this:
19662         # nid refs state last max rtr min tx min queue
19663         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19664         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19665         # numeric (0 or >0 or <0), queue >= 0.
19666         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19667         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19668         create_lnet_proc_files "peers"
19669         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19670         remove_lnet_proc_files "peers"
19671
19672         # lnet.buffers  should look like this:
19673         # pages count credits min
19674         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19675         L1="^pages +count +credits +min$"
19676         BR="^ +$N +$N +$I +$I$"
19677         create_lnet_proc_files "buffers"
19678         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19679         remove_lnet_proc_files "buffers"
19680
19681         # lnet.nis should look like this:
19682         # nid status alive refs peer rtr max tx min
19683         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19684         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19685         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19686         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19687         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
19688         create_lnet_proc_files "nis"
19689         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
19690         remove_lnet_proc_files "nis"
19691
19692         # can we successfully write to lnet.stats?
19693         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
19694 }
19695 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
19696
19697 test_216() { # bug 20317
19698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19699         remote_ost_nodsh && skip "remote OST with nodsh"
19700
19701         local node
19702         local facets=$(get_facets OST)
19703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19704
19705         save_lustre_params client "osc.*.contention_seconds" > $p
19706         save_lustre_params $facets \
19707                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
19708         save_lustre_params $facets \
19709                 "ldlm.namespaces.filter-*.contended_locks" >> $p
19710         save_lustre_params $facets \
19711                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
19712         clear_stats osc.*.osc_stats
19713
19714         # agressive lockless i/o settings
19715         do_nodes $(comma_list $(osts_nodes)) \
19716                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
19717                         ldlm.namespaces.filter-*.contended_locks=0 \
19718                         ldlm.namespaces.filter-*.contention_seconds=60"
19719         lctl set_param -n osc.*.contention_seconds=60
19720
19721         $DIRECTIO write $DIR/$tfile 0 10 4096
19722         $CHECKSTAT -s 40960 $DIR/$tfile
19723
19724         # disable lockless i/o
19725         do_nodes $(comma_list $(osts_nodes)) \
19726                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
19727                         ldlm.namespaces.filter-*.contended_locks=32 \
19728                         ldlm.namespaces.filter-*.contention_seconds=0"
19729         lctl set_param -n osc.*.contention_seconds=0
19730         clear_stats osc.*.osc_stats
19731
19732         dd if=/dev/zero of=$DIR/$tfile count=0
19733         $CHECKSTAT -s 0 $DIR/$tfile
19734
19735         restore_lustre_params <$p
19736         rm -f $p
19737         rm $DIR/$tfile
19738 }
19739 run_test 216 "check lockless direct write updates file size and kms correctly"
19740
19741 test_217() { # bug 22430
19742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19743
19744         local node
19745         local nid
19746
19747         for node in $(nodes_list); do
19748                 nid=$(host_nids_address $node $NETTYPE)
19749                 if [[ $nid = *-* ]] ; then
19750                         echo "lctl ping $(h2nettype $nid)"
19751                         lctl ping $(h2nettype $nid)
19752                 else
19753                         echo "skipping $node (no hyphen detected)"
19754                 fi
19755         done
19756 }
19757 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
19758
19759 test_218() {
19760        # do directio so as not to populate the page cache
19761        log "creating a 10 Mb file"
19762        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
19763        log "starting reads"
19764        dd if=$DIR/$tfile of=/dev/null bs=4096 &
19765        log "truncating the file"
19766        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
19767        log "killing dd"
19768        kill %+ || true # reads might have finished
19769        echo "wait until dd is finished"
19770        wait
19771        log "removing the temporary file"
19772        rm -rf $DIR/$tfile || error "tmp file removal failed"
19773 }
19774 run_test 218 "parallel read and truncate should not deadlock"
19775
19776 test_219() {
19777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19778
19779         # write one partial page
19780         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
19781         # set no grant so vvp_io_commit_write will do sync write
19782         $LCTL set_param fail_loc=0x411
19783         # write a full page at the end of file
19784         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
19785
19786         $LCTL set_param fail_loc=0
19787         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
19788         $LCTL set_param fail_loc=0x411
19789         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
19790
19791         # LU-4201
19792         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
19793         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
19794 }
19795 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
19796
19797 test_220() { #LU-325
19798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19799         remote_ost_nodsh && skip "remote OST with nodsh"
19800         remote_mds_nodsh && skip "remote MDS with nodsh"
19801         remote_mgs_nodsh && skip "remote MGS with nodsh"
19802
19803         local OSTIDX=0
19804
19805         # create on MDT0000 so the last_id and next_id are correct
19806         mkdir_on_mdt0 $DIR/$tdir
19807         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
19808         OST=${OST%_UUID}
19809
19810         # on the mdt's osc
19811         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
19812         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
19813                         osp.$mdtosc_proc1.prealloc_last_id)
19814         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
19815                         osp.$mdtosc_proc1.prealloc_next_id)
19816
19817         $LFS df -i
19818
19819         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
19820         #define OBD_FAIL_OST_ENOINO              0x229
19821         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
19822         create_pool $FSNAME.$TESTNAME || return 1
19823         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
19824
19825         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
19826
19827         MDSOBJS=$((last_id - next_id))
19828         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
19829
19830         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
19831         echo "OST still has $count kbytes free"
19832
19833         echo "create $MDSOBJS files @next_id..."
19834         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
19835
19836         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19837                         osp.$mdtosc_proc1.prealloc_last_id)
19838         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
19839                         osp.$mdtosc_proc1.prealloc_next_id)
19840
19841         echo "after creation, last_id=$last_id2, next_id=$next_id2"
19842         $LFS df -i
19843
19844         echo "cleanup..."
19845
19846         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
19847         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
19848
19849         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19850                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19851         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19852                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19853         echo "unlink $MDSOBJS files @$next_id..."
19854         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19855 }
19856 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19857
19858 test_221() {
19859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19860
19861         dd if=`which date` of=$MOUNT/date oflag=sync
19862         chmod +x $MOUNT/date
19863
19864         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19865         $LCTL set_param fail_loc=0x80001401
19866
19867         $MOUNT/date > /dev/null
19868         rm -f $MOUNT/date
19869 }
19870 run_test 221 "make sure fault and truncate race to not cause OOM"
19871
19872 test_222a () {
19873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19874
19875         rm -rf $DIR/$tdir
19876         test_mkdir $DIR/$tdir
19877         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19878         createmany -o $DIR/$tdir/$tfile 10
19879         cancel_lru_locks mdc
19880         cancel_lru_locks osc
19881         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19882         $LCTL set_param fail_loc=0x31a
19883         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19884         $LCTL set_param fail_loc=0
19885         rm -r $DIR/$tdir
19886 }
19887 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19888
19889 test_222b () {
19890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19891
19892         rm -rf $DIR/$tdir
19893         test_mkdir $DIR/$tdir
19894         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19895         createmany -o $DIR/$tdir/$tfile 10
19896         cancel_lru_locks mdc
19897         cancel_lru_locks osc
19898         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19899         $LCTL set_param fail_loc=0x31a
19900         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19901         $LCTL set_param fail_loc=0
19902 }
19903 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19904
19905 test_223 () {
19906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19907
19908         rm -rf $DIR/$tdir
19909         test_mkdir $DIR/$tdir
19910         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19911         createmany -o $DIR/$tdir/$tfile 10
19912         cancel_lru_locks mdc
19913         cancel_lru_locks osc
19914         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19915         $LCTL set_param fail_loc=0x31b
19916         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19917         $LCTL set_param fail_loc=0
19918         rm -r $DIR/$tdir
19919 }
19920 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19921
19922 test_224a() { # LU-1039, MRP-303
19923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19924         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19925         $LCTL set_param fail_loc=0x508
19926         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19927         $LCTL set_param fail_loc=0
19928         df $DIR
19929 }
19930 run_test 224a "Don't panic on bulk IO failure"
19931
19932 test_224bd_sub() { # LU-1039, MRP-303
19933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19934         local timeout=$1
19935
19936         shift
19937         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19938
19939         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19940
19941         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19942         cancel_lru_locks osc
19943         set_checksums 0
19944         stack_trap "set_checksums $ORIG_CSUM" EXIT
19945         local at_max_saved=0
19946
19947         # adaptive timeouts may prevent seeing the issue
19948         if at_is_enabled; then
19949                 at_max_saved=$(at_max_get mds)
19950                 at_max_set 0 mds client
19951                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19952         fi
19953
19954         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19955         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19956         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19957
19958         do_facet ost1 $LCTL set_param fail_loc=0
19959         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19960         df $DIR
19961 }
19962
19963 test_224b() {
19964         test_224bd_sub 3 error "dd failed"
19965 }
19966 run_test 224b "Don't panic on bulk IO failure"
19967
19968 test_224c() { # LU-6441
19969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19970         remote_mds_nodsh && skip "remote MDS with nodsh"
19971
19972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19973         save_writethrough $p
19974         set_cache writethrough on
19975
19976         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19977         local at_max=$($LCTL get_param -n at_max)
19978         local timeout=$($LCTL get_param -n timeout)
19979         local test_at="at_max"
19980         local param_at="$FSNAME.sys.at_max"
19981         local test_timeout="timeout"
19982         local param_timeout="$FSNAME.sys.timeout"
19983
19984         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19985
19986         set_persistent_param_and_check client "$test_at" "$param_at" 0
19987         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19988
19989         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19990         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19991         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19992         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19993         sync
19994         do_facet ost1 "$LCTL set_param fail_loc=0"
19995
19996         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19997         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19998                 $timeout
19999
20000         $LCTL set_param -n $pages_per_rpc
20001         restore_lustre_params < $p
20002         rm -f $p
20003 }
20004 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20005
20006 test_224d() { # LU-11169
20007         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20008 }
20009 run_test 224d "Don't corrupt data on bulk IO timeout"
20010
20011 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20012 test_225a () {
20013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20014         if [ -z ${MDSSURVEY} ]; then
20015                 skip_env "mds-survey not found"
20016         fi
20017         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20018                 skip "Need MDS version at least 2.2.51"
20019
20020         local mds=$(facet_host $SINGLEMDS)
20021         local target=$(do_nodes $mds 'lctl dl' |
20022                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20023
20024         local cmd1="file_count=1000 thrhi=4"
20025         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20026         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20027         local cmd="$cmd1 $cmd2 $cmd3"
20028
20029         rm -f ${TMP}/mds_survey*
20030         echo + $cmd
20031         eval $cmd || error "mds-survey with zero-stripe failed"
20032         cat ${TMP}/mds_survey*
20033         rm -f ${TMP}/mds_survey*
20034 }
20035 run_test 225a "Metadata survey sanity with zero-stripe"
20036
20037 test_225b () {
20038         if [ -z ${MDSSURVEY} ]; then
20039                 skip_env "mds-survey not found"
20040         fi
20041         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20042                 skip "Need MDS version at least 2.2.51"
20043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20044         remote_mds_nodsh && skip "remote MDS with nodsh"
20045         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20046                 skip_env "Need to mount OST to test"
20047         fi
20048
20049         local mds=$(facet_host $SINGLEMDS)
20050         local target=$(do_nodes $mds 'lctl dl' |
20051                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20052
20053         local cmd1="file_count=1000 thrhi=4"
20054         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20055         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20056         local cmd="$cmd1 $cmd2 $cmd3"
20057
20058         rm -f ${TMP}/mds_survey*
20059         echo + $cmd
20060         eval $cmd || error "mds-survey with stripe_count failed"
20061         cat ${TMP}/mds_survey*
20062         rm -f ${TMP}/mds_survey*
20063 }
20064 run_test 225b "Metadata survey sanity with stripe_count = 1"
20065
20066 mcreate_path2fid () {
20067         local mode=$1
20068         local major=$2
20069         local minor=$3
20070         local name=$4
20071         local desc=$5
20072         local path=$DIR/$tdir/$name
20073         local fid
20074         local rc
20075         local fid_path
20076
20077         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20078                 error "cannot create $desc"
20079
20080         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20081         rc=$?
20082         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20083
20084         fid_path=$($LFS fid2path $MOUNT $fid)
20085         rc=$?
20086         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20087
20088         [ "$path" == "$fid_path" ] ||
20089                 error "fid2path returned $fid_path, expected $path"
20090
20091         echo "pass with $path and $fid"
20092 }
20093
20094 test_226a () {
20095         rm -rf $DIR/$tdir
20096         mkdir -p $DIR/$tdir
20097
20098         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20099         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20100         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20101         mcreate_path2fid 0040666 0 0 dir "directory"
20102         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20103         mcreate_path2fid 0100666 0 0 file "regular file"
20104         mcreate_path2fid 0120666 0 0 link "symbolic link"
20105         mcreate_path2fid 0140666 0 0 sock "socket"
20106 }
20107 run_test 226a "call path2fid and fid2path on files of all type"
20108
20109 test_226b () {
20110         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20111
20112         local MDTIDX=1
20113
20114         rm -rf $DIR/$tdir
20115         mkdir -p $DIR/$tdir
20116         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20117                 error "create remote directory failed"
20118         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20119         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20120                                 "character special file (null)"
20121         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20122                                 "character special file (no device)"
20123         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20124         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20125                                 "block special file (loop)"
20126         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20127         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20128         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20129 }
20130 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20131
20132 test_226c () {
20133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20134         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20135                 skip "Need MDS version at least 2.13.55"
20136
20137         local submnt=/mnt/submnt
20138         local srcfile=/etc/passwd
20139         local dstfile=$submnt/passwd
20140         local path
20141         local fid
20142
20143         rm -rf $DIR/$tdir
20144         rm -rf $submnt
20145         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20146                 error "create remote directory failed"
20147         mkdir -p $submnt || error "create $submnt failed"
20148         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20149                 error "mount $submnt failed"
20150         stack_trap "umount $submnt" EXIT
20151
20152         cp $srcfile $dstfile
20153         fid=$($LFS path2fid $dstfile)
20154         path=$($LFS fid2path $submnt "$fid")
20155         [ "$path" = "$dstfile" ] ||
20156                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20157 }
20158 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20159
20160 # LU-1299 Executing or running ldd on a truncated executable does not
20161 # cause an out-of-memory condition.
20162 test_227() {
20163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20164         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20165
20166         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20167         chmod +x $MOUNT/date
20168
20169         $MOUNT/date > /dev/null
20170         ldd $MOUNT/date > /dev/null
20171         rm -f $MOUNT/date
20172 }
20173 run_test 227 "running truncated executable does not cause OOM"
20174
20175 # LU-1512 try to reuse idle OI blocks
20176 test_228a() {
20177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20178         remote_mds_nodsh && skip "remote MDS with nodsh"
20179         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20180
20181         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20182         local myDIR=$DIR/$tdir
20183
20184         mkdir -p $myDIR
20185         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20186         $LCTL set_param fail_loc=0x80001002
20187         createmany -o $myDIR/t- 10000
20188         $LCTL set_param fail_loc=0
20189         # The guard is current the largest FID holder
20190         touch $myDIR/guard
20191         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20192                     tr -d '[')
20193         local IDX=$(($SEQ % 64))
20194
20195         do_facet $SINGLEMDS sync
20196         # Make sure journal flushed.
20197         sleep 6
20198         local blk1=$(do_facet $SINGLEMDS \
20199                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20200                      grep Blockcount | awk '{print $4}')
20201
20202         # Remove old files, some OI blocks will become idle.
20203         unlinkmany $myDIR/t- 10000
20204         # Create new files, idle OI blocks should be reused.
20205         createmany -o $myDIR/t- 2000
20206         do_facet $SINGLEMDS sync
20207         # Make sure journal flushed.
20208         sleep 6
20209         local blk2=$(do_facet $SINGLEMDS \
20210                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20211                      grep Blockcount | awk '{print $4}')
20212
20213         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20214 }
20215 run_test 228a "try to reuse idle OI blocks"
20216
20217 test_228b() {
20218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20219         remote_mds_nodsh && skip "remote MDS with nodsh"
20220         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20221
20222         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20223         local myDIR=$DIR/$tdir
20224
20225         mkdir -p $myDIR
20226         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20227         $LCTL set_param fail_loc=0x80001002
20228         createmany -o $myDIR/t- 10000
20229         $LCTL set_param fail_loc=0
20230         # The guard is current the largest FID holder
20231         touch $myDIR/guard
20232         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20233                     tr -d '[')
20234         local IDX=$(($SEQ % 64))
20235
20236         do_facet $SINGLEMDS sync
20237         # Make sure journal flushed.
20238         sleep 6
20239         local blk1=$(do_facet $SINGLEMDS \
20240                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20241                      grep Blockcount | awk '{print $4}')
20242
20243         # Remove old files, some OI blocks will become idle.
20244         unlinkmany $myDIR/t- 10000
20245
20246         # stop the MDT
20247         stop $SINGLEMDS || error "Fail to stop MDT."
20248         # remount the MDT
20249         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20250                 error "Fail to start MDT."
20251
20252         client_up || error "Fail to df."
20253         # Create new files, idle OI blocks should be reused.
20254         createmany -o $myDIR/t- 2000
20255         do_facet $SINGLEMDS sync
20256         # Make sure journal flushed.
20257         sleep 6
20258         local blk2=$(do_facet $SINGLEMDS \
20259                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20260                      grep Blockcount | awk '{print $4}')
20261
20262         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20263 }
20264 run_test 228b "idle OI blocks can be reused after MDT restart"
20265
20266 #LU-1881
20267 test_228c() {
20268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20269         remote_mds_nodsh && skip "remote MDS with nodsh"
20270         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20271
20272         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20273         local myDIR=$DIR/$tdir
20274
20275         mkdir -p $myDIR
20276         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20277         $LCTL set_param fail_loc=0x80001002
20278         # 20000 files can guarantee there are index nodes in the OI file
20279         createmany -o $myDIR/t- 20000
20280         $LCTL set_param fail_loc=0
20281         # The guard is current the largest FID holder
20282         touch $myDIR/guard
20283         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20284                     tr -d '[')
20285         local IDX=$(($SEQ % 64))
20286
20287         do_facet $SINGLEMDS sync
20288         # Make sure journal flushed.
20289         sleep 6
20290         local blk1=$(do_facet $SINGLEMDS \
20291                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20292                      grep Blockcount | awk '{print $4}')
20293
20294         # Remove old files, some OI blocks will become idle.
20295         unlinkmany $myDIR/t- 20000
20296         rm -f $myDIR/guard
20297         # The OI file should become empty now
20298
20299         # Create new files, idle OI blocks should be reused.
20300         createmany -o $myDIR/t- 2000
20301         do_facet $SINGLEMDS sync
20302         # Make sure journal flushed.
20303         sleep 6
20304         local blk2=$(do_facet $SINGLEMDS \
20305                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20306                      grep Blockcount | awk '{print $4}')
20307
20308         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20309 }
20310 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20311
20312 test_229() { # LU-2482, LU-3448
20313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20314         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20315         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20316                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20317
20318         rm -f $DIR/$tfile
20319
20320         # Create a file with a released layout and stripe count 2.
20321         $MULTIOP $DIR/$tfile H2c ||
20322                 error "failed to create file with released layout"
20323
20324         $LFS getstripe -v $DIR/$tfile
20325
20326         local pattern=$($LFS getstripe -L $DIR/$tfile)
20327         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20328
20329         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20330                 error "getstripe"
20331         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20332         stat $DIR/$tfile || error "failed to stat released file"
20333
20334         chown $RUNAS_ID $DIR/$tfile ||
20335                 error "chown $RUNAS_ID $DIR/$tfile failed"
20336
20337         chgrp $RUNAS_ID $DIR/$tfile ||
20338                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20339
20340         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20341         rm $DIR/$tfile || error "failed to remove released file"
20342 }
20343 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20344
20345 test_230a() {
20346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20348         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20349                 skip "Need MDS version at least 2.11.52"
20350
20351         local MDTIDX=1
20352
20353         test_mkdir $DIR/$tdir
20354         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20355         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20356         [ $mdt_idx -ne 0 ] &&
20357                 error "create local directory on wrong MDT $mdt_idx"
20358
20359         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20360                         error "create remote directory failed"
20361         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20362         [ $mdt_idx -ne $MDTIDX ] &&
20363                 error "create remote directory on wrong MDT $mdt_idx"
20364
20365         createmany -o $DIR/$tdir/test_230/t- 10 ||
20366                 error "create files on remote directory failed"
20367         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20368         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20369         rm -r $DIR/$tdir || error "unlink remote directory failed"
20370 }
20371 run_test 230a "Create remote directory and files under the remote directory"
20372
20373 test_230b() {
20374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20376         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20377                 skip "Need MDS version at least 2.11.52"
20378
20379         local MDTIDX=1
20380         local mdt_index
20381         local i
20382         local file
20383         local pid
20384         local stripe_count
20385         local migrate_dir=$DIR/$tdir/migrate_dir
20386         local other_dir=$DIR/$tdir/other_dir
20387
20388         test_mkdir $DIR/$tdir
20389         test_mkdir -i0 -c1 $migrate_dir
20390         test_mkdir -i0 -c1 $other_dir
20391         for ((i=0; i<10; i++)); do
20392                 mkdir -p $migrate_dir/dir_${i}
20393                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20394                         error "create files under remote dir failed $i"
20395         done
20396
20397         cp /etc/passwd $migrate_dir/$tfile
20398         cp /etc/passwd $other_dir/$tfile
20399         chattr +SAD $migrate_dir
20400         chattr +SAD $migrate_dir/$tfile
20401
20402         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20403         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20404         local old_dir_mode=$(stat -c%f $migrate_dir)
20405         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20406
20407         mkdir -p $migrate_dir/dir_default_stripe2
20408         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20409         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20410
20411         mkdir -p $other_dir
20412         ln $migrate_dir/$tfile $other_dir/luna
20413         ln $migrate_dir/$tfile $migrate_dir/sofia
20414         ln $other_dir/$tfile $migrate_dir/david
20415         ln -s $migrate_dir/$tfile $other_dir/zachary
20416         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20417         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20418
20419         local len
20420         local lnktgt
20421
20422         # inline symlink
20423         for len in 58 59 60; do
20424                 lnktgt=$(str_repeat 'l' $len)
20425                 touch $migrate_dir/$lnktgt
20426                 ln -s $lnktgt $migrate_dir/${len}char_ln
20427         done
20428
20429         # PATH_MAX
20430         for len in 4094 4095; do
20431                 lnktgt=$(str_repeat 'l' $len)
20432                 ln -s $lnktgt $migrate_dir/${len}char_ln
20433         done
20434
20435         # NAME_MAX
20436         for len in 254 255; do
20437                 touch $migrate_dir/$(str_repeat 'l' $len)
20438         done
20439
20440         $LFS migrate -m $MDTIDX $migrate_dir ||
20441                 error "fails on migrating remote dir to MDT1"
20442
20443         echo "migratate to MDT1, then checking.."
20444         for ((i = 0; i < 10; i++)); do
20445                 for file in $(find $migrate_dir/dir_${i}); do
20446                         mdt_index=$($LFS getstripe -m $file)
20447                         # broken symlink getstripe will fail
20448                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20449                                 error "$file is not on MDT${MDTIDX}"
20450                 done
20451         done
20452
20453         # the multiple link file should still in MDT0
20454         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20455         [ $mdt_index == 0 ] ||
20456                 error "$file is not on MDT${MDTIDX}"
20457
20458         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20459         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20460                 error " expect $old_dir_flag get $new_dir_flag"
20461
20462         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20463         [ "$old_file_flag" = "$new_file_flag" ] ||
20464                 error " expect $old_file_flag get $new_file_flag"
20465
20466         local new_dir_mode=$(stat -c%f $migrate_dir)
20467         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20468                 error "expect mode $old_dir_mode get $new_dir_mode"
20469
20470         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20471         [ "$old_file_mode" = "$new_file_mode" ] ||
20472                 error "expect mode $old_file_mode get $new_file_mode"
20473
20474         diff /etc/passwd $migrate_dir/$tfile ||
20475                 error "$tfile different after migration"
20476
20477         diff /etc/passwd $other_dir/luna ||
20478                 error "luna different after migration"
20479
20480         diff /etc/passwd $migrate_dir/sofia ||
20481                 error "sofia different after migration"
20482
20483         diff /etc/passwd $migrate_dir/david ||
20484                 error "david different after migration"
20485
20486         diff /etc/passwd $other_dir/zachary ||
20487                 error "zachary different after migration"
20488
20489         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20490                 error "${tfile}_ln different after migration"
20491
20492         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20493                 error "${tfile}_ln_other different after migration"
20494
20495         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20496         [ $stripe_count = 2 ] ||
20497                 error "dir strpe_count $d != 2 after migration."
20498
20499         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20500         [ $stripe_count = 2 ] ||
20501                 error "file strpe_count $d != 2 after migration."
20502
20503         #migrate back to MDT0
20504         MDTIDX=0
20505
20506         $LFS migrate -m $MDTIDX $migrate_dir ||
20507                 error "fails on migrating remote dir to MDT0"
20508
20509         echo "migrate back to MDT0, checking.."
20510         for file in $(find $migrate_dir); do
20511                 mdt_index=$($LFS getstripe -m $file)
20512                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20513                         error "$file is not on MDT${MDTIDX}"
20514         done
20515
20516         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20517         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20518                 error " expect $old_dir_flag get $new_dir_flag"
20519
20520         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20521         [ "$old_file_flag" = "$new_file_flag" ] ||
20522                 error " expect $old_file_flag get $new_file_flag"
20523
20524         local new_dir_mode=$(stat -c%f $migrate_dir)
20525         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20526                 error "expect mode $old_dir_mode get $new_dir_mode"
20527
20528         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20529         [ "$old_file_mode" = "$new_file_mode" ] ||
20530                 error "expect mode $old_file_mode get $new_file_mode"
20531
20532         diff /etc/passwd ${migrate_dir}/$tfile ||
20533                 error "$tfile different after migration"
20534
20535         diff /etc/passwd ${other_dir}/luna ||
20536                 error "luna different after migration"
20537
20538         diff /etc/passwd ${migrate_dir}/sofia ||
20539                 error "sofia different after migration"
20540
20541         diff /etc/passwd ${other_dir}/zachary ||
20542                 error "zachary different after migration"
20543
20544         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20545                 error "${tfile}_ln different after migration"
20546
20547         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20548                 error "${tfile}_ln_other different after migration"
20549
20550         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20551         [ $stripe_count = 2 ] ||
20552                 error "dir strpe_count $d != 2 after migration."
20553
20554         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20555         [ $stripe_count = 2 ] ||
20556                 error "file strpe_count $d != 2 after migration."
20557
20558         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20559 }
20560 run_test 230b "migrate directory"
20561
20562 test_230c() {
20563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20565         remote_mds_nodsh && skip "remote MDS with nodsh"
20566         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20567                 skip "Need MDS version at least 2.11.52"
20568
20569         local MDTIDX=1
20570         local total=3
20571         local mdt_index
20572         local file
20573         local migrate_dir=$DIR/$tdir/migrate_dir
20574
20575         #If migrating directory fails in the middle, all entries of
20576         #the directory is still accessiable.
20577         test_mkdir $DIR/$tdir
20578         test_mkdir -i0 -c1 $migrate_dir
20579         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20580         stat $migrate_dir
20581         createmany -o $migrate_dir/f $total ||
20582                 error "create files under ${migrate_dir} failed"
20583
20584         # fail after migrating top dir, and this will fail only once, so the
20585         # first sub file migration will fail (currently f3), others succeed.
20586         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20587         do_facet mds1 lctl set_param fail_loc=0x1801
20588         local t=$(ls $migrate_dir | wc -l)
20589         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20590                 error "migrate should fail"
20591         local u=$(ls $migrate_dir | wc -l)
20592         [ "$u" == "$t" ] || error "$u != $t during migration"
20593
20594         # add new dir/file should succeed
20595         mkdir $migrate_dir/dir ||
20596                 error "mkdir failed under migrating directory"
20597         touch $migrate_dir/file ||
20598                 error "create file failed under migrating directory"
20599
20600         # add file with existing name should fail
20601         for file in $migrate_dir/f*; do
20602                 stat $file > /dev/null || error "stat $file failed"
20603                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20604                         error "open(O_CREAT|O_EXCL) $file should fail"
20605                 $MULTIOP $file m && error "create $file should fail"
20606                 touch $DIR/$tdir/remote_dir/$tfile ||
20607                         error "touch $tfile failed"
20608                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20609                         error "link $file should fail"
20610                 mdt_index=$($LFS getstripe -m $file)
20611                 if [ $mdt_index == 0 ]; then
20612                         # file failed to migrate is not allowed to rename to
20613                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20614                                 error "rename to $file should fail"
20615                 else
20616                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20617                                 error "rename to $file failed"
20618                 fi
20619                 echo hello >> $file || error "write $file failed"
20620         done
20621
20622         # resume migration with different options should fail
20623         $LFS migrate -m 0 $migrate_dir &&
20624                 error "migrate -m 0 $migrate_dir should fail"
20625
20626         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20627                 error "migrate -c 2 $migrate_dir should fail"
20628
20629         # resume migration should succeed
20630         $LFS migrate -m $MDTIDX $migrate_dir ||
20631                 error "migrate $migrate_dir failed"
20632
20633         echo "Finish migration, then checking.."
20634         for file in $(find $migrate_dir); do
20635                 mdt_index=$($LFS getstripe -m $file)
20636                 [ $mdt_index == $MDTIDX ] ||
20637                         error "$file is not on MDT${MDTIDX}"
20638         done
20639
20640         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20641 }
20642 run_test 230c "check directory accessiblity if migration failed"
20643
20644 test_230d() {
20645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20647         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20648                 skip "Need MDS version at least 2.11.52"
20649         # LU-11235
20650         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20651
20652         local migrate_dir=$DIR/$tdir/migrate_dir
20653         local old_index
20654         local new_index
20655         local old_count
20656         local new_count
20657         local new_hash
20658         local mdt_index
20659         local i
20660         local j
20661
20662         old_index=$((RANDOM % MDSCOUNT))
20663         old_count=$((MDSCOUNT - old_index))
20664         new_index=$((RANDOM % MDSCOUNT))
20665         new_count=$((MDSCOUNT - new_index))
20666         new_hash=1 # for all_char
20667
20668         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20669         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20670
20671         test_mkdir $DIR/$tdir
20672         test_mkdir -i $old_index -c $old_count $migrate_dir
20673
20674         for ((i=0; i<100; i++)); do
20675                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20676                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20677                         error "create files under remote dir failed $i"
20678         done
20679
20680         echo -n "Migrate from MDT$old_index "
20681         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20682         echo -n "to MDT$new_index"
20683         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20684         echo
20685
20686         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20687         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
20688                 error "migrate remote dir error"
20689
20690         echo "Finish migration, then checking.."
20691         for file in $(find $migrate_dir -maxdepth 1); do
20692                 mdt_index=$($LFS getstripe -m $file)
20693                 if [ $mdt_index -lt $new_index ] ||
20694                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
20695                         error "$file is on MDT$mdt_index"
20696                 fi
20697         done
20698
20699         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20700 }
20701 run_test 230d "check migrate big directory"
20702
20703 test_230e() {
20704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20705         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20706         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20707                 skip "Need MDS version at least 2.11.52"
20708
20709         local i
20710         local j
20711         local a_fid
20712         local b_fid
20713
20714         mkdir_on_mdt0 $DIR/$tdir
20715         mkdir $DIR/$tdir/migrate_dir
20716         mkdir $DIR/$tdir/other_dir
20717         touch $DIR/$tdir/migrate_dir/a
20718         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
20719         ls $DIR/$tdir/other_dir
20720
20721         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20722                 error "migrate dir fails"
20723
20724         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20725         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20726
20727         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20728         [ $mdt_index == 0 ] || error "a is not on MDT0"
20729
20730         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
20731                 error "migrate dir fails"
20732
20733         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
20734         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
20735
20736         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20737         [ $mdt_index == 1 ] || error "a is not on MDT1"
20738
20739         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
20740         [ $mdt_index == 1 ] || error "b is not on MDT1"
20741
20742         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20743         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
20744
20745         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
20746
20747         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20748 }
20749 run_test 230e "migrate mulitple local link files"
20750
20751 test_230f() {
20752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20754         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20755                 skip "Need MDS version at least 2.11.52"
20756
20757         local a_fid
20758         local ln_fid
20759
20760         mkdir -p $DIR/$tdir
20761         mkdir $DIR/$tdir/migrate_dir
20762         $LFS mkdir -i1 $DIR/$tdir/other_dir
20763         touch $DIR/$tdir/migrate_dir/a
20764         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
20765         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
20766         ls $DIR/$tdir/other_dir
20767
20768         # a should be migrated to MDT1, since no other links on MDT0
20769         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20770                 error "#1 migrate dir fails"
20771         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
20772         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
20773         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20774         [ $mdt_index == 1 ] || error "a is not on MDT1"
20775
20776         # a should stay on MDT1, because it is a mulitple link file
20777         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20778                 error "#2 migrate dir fails"
20779         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20780         [ $mdt_index == 1 ] || error "a is not on MDT1"
20781
20782         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
20783                 error "#3 migrate dir fails"
20784
20785         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
20786         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
20787         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
20788
20789         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
20790         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
20791
20792         # a should be migrated to MDT0, since no other links on MDT1
20793         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
20794                 error "#4 migrate dir fails"
20795         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
20796         [ $mdt_index == 0 ] || error "a is not on MDT0"
20797
20798         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20799 }
20800 run_test 230f "migrate mulitple remote link files"
20801
20802 test_230g() {
20803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20804         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20805         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20806                 skip "Need MDS version at least 2.11.52"
20807
20808         mkdir -p $DIR/$tdir/migrate_dir
20809
20810         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
20811                 error "migrating dir to non-exist MDT succeeds"
20812         true
20813 }
20814 run_test 230g "migrate dir to non-exist MDT"
20815
20816 test_230h() {
20817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20819         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20820                 skip "Need MDS version at least 2.11.52"
20821
20822         local mdt_index
20823
20824         mkdir -p $DIR/$tdir/migrate_dir
20825
20826         $LFS migrate -m1 $DIR &&
20827                 error "migrating mountpoint1 should fail"
20828
20829         $LFS migrate -m1 $DIR/$tdir/.. &&
20830                 error "migrating mountpoint2 should fail"
20831
20832         # same as mv
20833         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
20834                 error "migrating $tdir/migrate_dir/.. should fail"
20835
20836         true
20837 }
20838 run_test 230h "migrate .. and root"
20839
20840 test_230i() {
20841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20842         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20843         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20844                 skip "Need MDS version at least 2.11.52"
20845
20846         mkdir -p $DIR/$tdir/migrate_dir
20847
20848         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
20849                 error "migration fails with a tailing slash"
20850
20851         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20852                 error "migration fails with two tailing slashes"
20853 }
20854 run_test 230i "lfs migrate -m tolerates trailing slashes"
20855
20856 test_230j() {
20857         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20858         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20859                 skip "Need MDS version at least 2.11.52"
20860
20861         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20862         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20863                 error "create $tfile failed"
20864         cat /etc/passwd > $DIR/$tdir/$tfile
20865
20866         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20867
20868         cmp /etc/passwd $DIR/$tdir/$tfile ||
20869                 error "DoM file mismatch after migration"
20870 }
20871 run_test 230j "DoM file data not changed after dir migration"
20872
20873 test_230k() {
20874         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20875         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20876                 skip "Need MDS version at least 2.11.56"
20877
20878         local total=20
20879         local files_on_starting_mdt=0
20880
20881         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20882         $LFS getdirstripe $DIR/$tdir
20883         for i in $(seq $total); do
20884                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20885                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20886                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20887         done
20888
20889         echo "$files_on_starting_mdt files on MDT0"
20890
20891         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20892         $LFS getdirstripe $DIR/$tdir
20893
20894         files_on_starting_mdt=0
20895         for i in $(seq $total); do
20896                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20897                         error "file $tfile.$i mismatch after migration"
20898                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20899                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20900         done
20901
20902         echo "$files_on_starting_mdt files on MDT1 after migration"
20903         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20904
20905         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20906         $LFS getdirstripe $DIR/$tdir
20907
20908         files_on_starting_mdt=0
20909         for i in $(seq $total); do
20910                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20911                         error "file $tfile.$i mismatch after 2nd migration"
20912                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20913                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20914         done
20915
20916         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20917         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20918
20919         true
20920 }
20921 run_test 230k "file data not changed after dir migration"
20922
20923 test_230l() {
20924         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20925         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20926                 skip "Need MDS version at least 2.11.56"
20927
20928         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20929         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20930                 error "create files under remote dir failed $i"
20931         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20932 }
20933 run_test 230l "readdir between MDTs won't crash"
20934
20935 test_230m() {
20936         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20937         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20938                 skip "Need MDS version at least 2.11.56"
20939
20940         local MDTIDX=1
20941         local mig_dir=$DIR/$tdir/migrate_dir
20942         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20943         local shortstr="b"
20944         local val
20945
20946         echo "Creating files and dirs with xattrs"
20947         test_mkdir $DIR/$tdir
20948         test_mkdir -i0 -c1 $mig_dir
20949         mkdir $mig_dir/dir
20950         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20951                 error "cannot set xattr attr1 on dir"
20952         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20953                 error "cannot set xattr attr2 on dir"
20954         touch $mig_dir/dir/f0
20955         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20956                 error "cannot set xattr attr1 on file"
20957         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20958                 error "cannot set xattr attr2 on file"
20959         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20960         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20961         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20962         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20963         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20964         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20965         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20966         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20967         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20968
20969         echo "Migrating to MDT1"
20970         $LFS migrate -m $MDTIDX $mig_dir ||
20971                 error "fails on migrating dir to MDT1"
20972
20973         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20974         echo "Checking xattrs"
20975         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20976         [ "$val" = $longstr ] ||
20977                 error "expecting xattr1 $longstr on dir, found $val"
20978         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20979         [ "$val" = $shortstr ] ||
20980                 error "expecting xattr2 $shortstr on dir, found $val"
20981         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20982         [ "$val" = $longstr ] ||
20983                 error "expecting xattr1 $longstr on file, found $val"
20984         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20985         [ "$val" = $shortstr ] ||
20986                 error "expecting xattr2 $shortstr on file, found $val"
20987 }
20988 run_test 230m "xattrs not changed after dir migration"
20989
20990 test_230n() {
20991         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20992         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20993                 skip "Need MDS version at least 2.13.53"
20994
20995         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20996         cat /etc/hosts > $DIR/$tdir/$tfile
20997         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20998         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20999
21000         cmp /etc/hosts $DIR/$tdir/$tfile ||
21001                 error "File data mismatch after migration"
21002 }
21003 run_test 230n "Dir migration with mirrored file"
21004
21005 test_230o() {
21006         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21007         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21008                 skip "Need MDS version at least 2.13.52"
21009
21010         local mdts=$(comma_list $(mdts_nodes))
21011         local timeout=100
21012         local restripe_status
21013         local delta
21014         local i
21015
21016         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21017
21018         # in case "crush" hash type is not set
21019         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21020
21021         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21022                            mdt.*MDT0000.enable_dir_restripe)
21023         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21024         stack_trap "do_nodes $mdts $LCTL set_param \
21025                     mdt.*.enable_dir_restripe=$restripe_status"
21026
21027         mkdir $DIR/$tdir
21028         createmany -m $DIR/$tdir/f 100 ||
21029                 error "create files under remote dir failed $i"
21030         createmany -d $DIR/$tdir/d 100 ||
21031                 error "create dirs under remote dir failed $i"
21032
21033         for i in $(seq 2 $MDSCOUNT); do
21034                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21035                 $LFS setdirstripe -c $i $DIR/$tdir ||
21036                         error "split -c $i $tdir failed"
21037                 wait_update $HOSTNAME \
21038                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21039                         error "dir split not finished"
21040                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21041                         awk '/migrate/ {sum += $2} END { print sum }')
21042                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21043                 # delta is around total_files/stripe_count
21044                 (( $delta < 200 / (i - 1) + 4 )) ||
21045                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21046         done
21047 }
21048 run_test 230o "dir split"
21049
21050 test_230p() {
21051         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21052         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21053                 skip "Need MDS version at least 2.13.52"
21054
21055         local mdts=$(comma_list $(mdts_nodes))
21056         local timeout=100
21057         local restripe_status
21058         local delta
21059         local c
21060
21061         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21062
21063         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21064
21065         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21066                            mdt.*MDT0000.enable_dir_restripe)
21067         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21068         stack_trap "do_nodes $mdts $LCTL set_param \
21069                     mdt.*.enable_dir_restripe=$restripe_status"
21070
21071         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21072         createmany -m $DIR/$tdir/f 100 ||
21073                 error "create files under remote dir failed"
21074         createmany -d $DIR/$tdir/d 100 ||
21075                 error "create dirs under remote dir failed"
21076
21077         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21078                 local mdt_hash="crush"
21079
21080                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21081                 $LFS setdirstripe -c $c $DIR/$tdir ||
21082                         error "split -c $c $tdir failed"
21083                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21084                         mdt_hash="$mdt_hash,fixed"
21085                 elif [ $c -eq 1 ]; then
21086                         mdt_hash="none"
21087                 fi
21088                 wait_update $HOSTNAME \
21089                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21090                         error "dir merge not finished"
21091                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21092                         awk '/migrate/ {sum += $2} END { print sum }')
21093                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21094                 # delta is around total_files/stripe_count
21095                 (( delta < 200 / c + 4 )) ||
21096                         error "$delta files migrated >= $((200 / c + 4))"
21097         done
21098 }
21099 run_test 230p "dir merge"
21100
21101 test_230q() {
21102         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21103         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21104                 skip "Need MDS version at least 2.13.52"
21105
21106         local mdts=$(comma_list $(mdts_nodes))
21107         local saved_threshold=$(do_facet mds1 \
21108                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21109         local saved_delta=$(do_facet mds1 \
21110                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21111         local threshold=100
21112         local delta=2
21113         local total=0
21114         local stripe_count=0
21115         local stripe_index
21116         local nr_files
21117         local create
21118
21119         # test with fewer files on ZFS
21120         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21121
21122         stack_trap "do_nodes $mdts $LCTL set_param \
21123                     mdt.*.dir_split_count=$saved_threshold"
21124         stack_trap "do_nodes $mdts $LCTL set_param \
21125                     mdt.*.dir_split_delta=$saved_delta"
21126         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21127         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21128         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21129         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21130         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21131         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21132
21133         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21134         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21135
21136         create=$((threshold * 3 / 2))
21137         while [ $stripe_count -lt $MDSCOUNT ]; do
21138                 createmany -m $DIR/$tdir/f $total $create ||
21139                         error "create sub files failed"
21140                 stat $DIR/$tdir > /dev/null
21141                 total=$((total + create))
21142                 stripe_count=$((stripe_count + delta))
21143                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21144
21145                 wait_update $HOSTNAME \
21146                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21147                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21148
21149                 wait_update $HOSTNAME \
21150                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21151                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21152
21153                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21154                 echo "$nr_files/$total files on MDT$stripe_index after split"
21155                 # allow 10% margin of imbalance with crush hash
21156                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21157                         error "$nr_files files on MDT$stripe_index after split"
21158
21159                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21160                 [ $nr_files -eq $total ] ||
21161                         error "total sub files $nr_files != $total"
21162         done
21163
21164         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21165
21166         echo "fixed layout directory won't auto split"
21167         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21168         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21169                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21170         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21171                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21172 }
21173 run_test 230q "dir auto split"
21174
21175 test_230r() {
21176         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21177         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21178         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21179                 skip "Need MDS version at least 2.13.54"
21180
21181         # maximum amount of local locks:
21182         # parent striped dir - 2 locks
21183         # new stripe in parent to migrate to - 1 lock
21184         # source and target - 2 locks
21185         # Total 5 locks for regular file
21186         mkdir -p $DIR/$tdir
21187         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21188         touch $DIR/$tdir/dir1/eee
21189
21190         # create 4 hardlink for 4 more locks
21191         # Total: 9 locks > RS_MAX_LOCKS (8)
21192         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21193         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21194         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21195         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21196         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21197         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21198         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21199         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21200
21201         cancel_lru_locks mdc
21202
21203         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21204                 error "migrate dir fails"
21205
21206         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21207 }
21208 run_test 230r "migrate with too many local locks"
21209
21210 test_230s() {
21211         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21212                 skip "Need MDS version at least 2.14.52"
21213
21214         local mdts=$(comma_list $(mdts_nodes))
21215         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21216                                 mdt.*MDT0000.enable_dir_restripe)
21217
21218         stack_trap "do_nodes $mdts $LCTL set_param \
21219                     mdt.*.enable_dir_restripe=$restripe_status"
21220
21221         local st
21222         for st in 0 1; do
21223                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21224                 test_mkdir $DIR/$tdir
21225                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21226                         error "$LFS mkdir should return EEXIST if target exists"
21227                 rmdir $DIR/$tdir
21228         done
21229 }
21230 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21231
21232 test_230t()
21233 {
21234         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21235         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21236                 skip "Need MDS version at least 2.14.50"
21237
21238         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21239         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21240         $LFS project -p 1 -s $DIR/$tdir ||
21241                 error "set $tdir project id failed"
21242         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21243                 error "set subdir project id failed"
21244         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21245 }
21246 run_test 230t "migrate directory with project ID set"
21247
21248 test_230u()
21249 {
21250         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21251         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21252                 skip "Need MDS version at least 2.14.53"
21253
21254         local count
21255
21256         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21257         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21258         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21259         for i in $(seq 0 $((MDSCOUNT - 1))); do
21260                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21261                 echo "$count dirs migrated to MDT$i"
21262         done
21263         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21264         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21265 }
21266 run_test 230u "migrate directory by QOS"
21267
21268 test_230v()
21269 {
21270         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21271         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21272                 skip "Need MDS version at least 2.14.53"
21273
21274         local count
21275
21276         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21277         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21278         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21279         for i in $(seq 0 $((MDSCOUNT - 1))); do
21280                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21281                 echo "$count subdirs migrated to MDT$i"
21282                 (( i == 3 )) && (( count > 0 )) &&
21283                         error "subdir shouldn't be migrated to MDT3"
21284         done
21285         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21286         (( count == 3 )) || error "dirs migrated to $count MDTs"
21287 }
21288 run_test 230v "subdir migrated to the MDT where its parent is located"
21289
21290 test_230w() {
21291         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21292         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21293                 skip "Need MDS version at least 2.15.0"
21294
21295         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21296         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21297         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21298
21299         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21300                 error "migrate failed"
21301
21302         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21303                 error "$tdir stripe count mismatch"
21304
21305         for i in $(seq 0 9); do
21306                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21307                         error "d$i is striped"
21308         done
21309 }
21310 run_test 230w "non-recursive mode dir migration"
21311
21312 test_230x() {
21313         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21314         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21315                 skip "Need MDS version at least 2.15.0"
21316
21317         mkdir -p $DIR/$tdir || error "mkdir failed"
21318         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21319
21320         local mdt_name=$(mdtname_from_index 0)
21321         local low=$(do_facet mds2 $LCTL get_param -n \
21322                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21323         local high=$(do_facet mds2 $LCTL get_param -n \
21324                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21325         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21326         local maxage=$(do_facet mds2 $LCTL get_param -n \
21327                 osp.*$mdt_name-osp-MDT0001.maxage)
21328
21329         stack_trap "do_facet mds2 $LCTL set_param -n \
21330                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21331                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21332         stack_trap "do_facet mds2 $LCTL set_param -n \
21333                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21334
21335         do_facet mds2 $LCTL set_param -n \
21336                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21337         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21338         sleep 4
21339         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21340                 error "migrate $tdir should fail"
21341
21342         do_facet mds2 $LCTL set_param -n \
21343                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21344         do_facet mds2 $LCTL set_param -n \
21345                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21346         sleep 4
21347         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21348                 error "migrate failed"
21349         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21350                 error "$tdir stripe count mismatch"
21351 }
21352 run_test 230x "dir migration check space"
21353
21354 test_231a()
21355 {
21356         # For simplicity this test assumes that max_pages_per_rpc
21357         # is the same across all OSCs
21358         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21359         local bulk_size=$((max_pages * PAGE_SIZE))
21360         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21361                                        head -n 1)
21362
21363         mkdir -p $DIR/$tdir
21364         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21365                 error "failed to set stripe with -S ${brw_size}M option"
21366
21367         # clear the OSC stats
21368         $LCTL set_param osc.*.stats=0 &>/dev/null
21369         stop_writeback
21370
21371         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21372         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21373                 oflag=direct &>/dev/null || error "dd failed"
21374
21375         sync; sleep 1; sync # just to be safe
21376         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21377         if [ x$nrpcs != "x1" ]; then
21378                 $LCTL get_param osc.*.stats
21379                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21380         fi
21381
21382         start_writeback
21383         # Drop the OSC cache, otherwise we will read from it
21384         cancel_lru_locks osc
21385
21386         # clear the OSC stats
21387         $LCTL set_param osc.*.stats=0 &>/dev/null
21388
21389         # Client reads $bulk_size.
21390         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21391                 iflag=direct &>/dev/null || error "dd failed"
21392
21393         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21394         if [ x$nrpcs != "x1" ]; then
21395                 $LCTL get_param osc.*.stats
21396                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21397         fi
21398 }
21399 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21400
21401 test_231b() {
21402         mkdir -p $DIR/$tdir
21403         local i
21404         for i in {0..1023}; do
21405                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21406                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21407                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21408         done
21409         sync
21410 }
21411 run_test 231b "must not assert on fully utilized OST request buffer"
21412
21413 test_232a() {
21414         mkdir -p $DIR/$tdir
21415         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21416
21417         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21418         do_facet ost1 $LCTL set_param fail_loc=0x31c
21419
21420         # ignore dd failure
21421         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21422
21423         do_facet ost1 $LCTL set_param fail_loc=0
21424         umount_client $MOUNT || error "umount failed"
21425         mount_client $MOUNT || error "mount failed"
21426         stop ost1 || error "cannot stop ost1"
21427         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21428 }
21429 run_test 232a "failed lock should not block umount"
21430
21431 test_232b() {
21432         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21433                 skip "Need MDS version at least 2.10.58"
21434
21435         mkdir -p $DIR/$tdir
21436         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21437         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21438         sync
21439         cancel_lru_locks osc
21440
21441         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21442         do_facet ost1 $LCTL set_param fail_loc=0x31c
21443
21444         # ignore failure
21445         $LFS data_version $DIR/$tdir/$tfile || true
21446
21447         do_facet ost1 $LCTL set_param fail_loc=0
21448         umount_client $MOUNT || error "umount failed"
21449         mount_client $MOUNT || error "mount failed"
21450         stop ost1 || error "cannot stop ost1"
21451         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21452 }
21453 run_test 232b "failed data version lock should not block umount"
21454
21455 test_233a() {
21456         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21457                 skip "Need MDS version at least 2.3.64"
21458         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21459
21460         local fid=$($LFS path2fid $MOUNT)
21461
21462         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21463                 error "cannot access $MOUNT using its FID '$fid'"
21464 }
21465 run_test 233a "checking that OBF of the FS root succeeds"
21466
21467 test_233b() {
21468         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21469                 skip "Need MDS version at least 2.5.90"
21470         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21471
21472         local fid=$($LFS path2fid $MOUNT/.lustre)
21473
21474         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21475                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21476
21477         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21478         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21479                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21480 }
21481 run_test 233b "checking that OBF of the FS .lustre succeeds"
21482
21483 test_234() {
21484         local p="$TMP/sanityN-$TESTNAME.parameters"
21485         save_lustre_params client "llite.*.xattr_cache" > $p
21486         lctl set_param llite.*.xattr_cache 1 ||
21487                 skip_env "xattr cache is not supported"
21488
21489         mkdir -p $DIR/$tdir || error "mkdir failed"
21490         touch $DIR/$tdir/$tfile || error "touch failed"
21491         # OBD_FAIL_LLITE_XATTR_ENOMEM
21492         $LCTL set_param fail_loc=0x1405
21493         getfattr -n user.attr $DIR/$tdir/$tfile &&
21494                 error "getfattr should have failed with ENOMEM"
21495         $LCTL set_param fail_loc=0x0
21496         rm -rf $DIR/$tdir
21497
21498         restore_lustre_params < $p
21499         rm -f $p
21500 }
21501 run_test 234 "xattr cache should not crash on ENOMEM"
21502
21503 test_235() {
21504         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21505                 skip "Need MDS version at least 2.4.52"
21506
21507         flock_deadlock $DIR/$tfile
21508         local RC=$?
21509         case $RC in
21510                 0)
21511                 ;;
21512                 124) error "process hangs on a deadlock"
21513                 ;;
21514                 *) error "error executing flock_deadlock $DIR/$tfile"
21515                 ;;
21516         esac
21517 }
21518 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21519
21520 #LU-2935
21521 test_236() {
21522         check_swap_layouts_support
21523
21524         local ref1=/etc/passwd
21525         local ref2=/etc/group
21526         local file1=$DIR/$tdir/f1
21527         local file2=$DIR/$tdir/f2
21528
21529         test_mkdir -c1 $DIR/$tdir
21530         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21531         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21532         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21533         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21534         local fd=$(free_fd)
21535         local cmd="exec $fd<>$file2"
21536         eval $cmd
21537         rm $file2
21538         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21539                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21540         cmd="exec $fd>&-"
21541         eval $cmd
21542         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21543
21544         #cleanup
21545         rm -rf $DIR/$tdir
21546 }
21547 run_test 236 "Layout swap on open unlinked file"
21548
21549 # LU-4659 linkea consistency
21550 test_238() {
21551         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21552                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21553                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21554                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21555
21556         touch $DIR/$tfile
21557         ln $DIR/$tfile $DIR/$tfile.lnk
21558         touch $DIR/$tfile.new
21559         mv $DIR/$tfile.new $DIR/$tfile
21560         local fid1=$($LFS path2fid $DIR/$tfile)
21561         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21562         local path1=$($LFS fid2path $FSNAME "$fid1")
21563         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21564         local path2=$($LFS fid2path $FSNAME "$fid2")
21565         [ $tfile.lnk == $path2 ] ||
21566                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21567         rm -f $DIR/$tfile*
21568 }
21569 run_test 238 "Verify linkea consistency"
21570
21571 test_239A() { # was test_239
21572         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21573                 skip "Need MDS version at least 2.5.60"
21574
21575         local list=$(comma_list $(mdts_nodes))
21576
21577         mkdir -p $DIR/$tdir
21578         createmany -o $DIR/$tdir/f- 5000
21579         unlinkmany $DIR/$tdir/f- 5000
21580         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21581                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21582         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21583                         osp.*MDT*.sync_in_flight" | calc_sum)
21584         [ "$changes" -eq 0 ] || error "$changes not synced"
21585 }
21586 run_test 239A "osp_sync test"
21587
21588 test_239a() { #LU-5297
21589         remote_mds_nodsh && skip "remote MDS with nodsh"
21590
21591         touch $DIR/$tfile
21592         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21593         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21594         chgrp $RUNAS_GID $DIR/$tfile
21595         wait_delete_completed
21596 }
21597 run_test 239a "process invalid osp sync record correctly"
21598
21599 test_239b() { #LU-5297
21600         remote_mds_nodsh && skip "remote MDS with nodsh"
21601
21602         touch $DIR/$tfile1
21603         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21604         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21605         chgrp $RUNAS_GID $DIR/$tfile1
21606         wait_delete_completed
21607         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21608         touch $DIR/$tfile2
21609         chgrp $RUNAS_GID $DIR/$tfile2
21610         wait_delete_completed
21611 }
21612 run_test 239b "process osp sync record with ENOMEM error correctly"
21613
21614 test_240() {
21615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21616         remote_mds_nodsh && skip "remote MDS with nodsh"
21617
21618         mkdir -p $DIR/$tdir
21619
21620         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21621                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21622         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21623                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21624
21625         umount_client $MOUNT || error "umount failed"
21626         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21627         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21628         mount_client $MOUNT || error "failed to mount client"
21629
21630         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21631         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21632 }
21633 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21634
21635 test_241_bio() {
21636         local count=$1
21637         local bsize=$2
21638
21639         for LOOP in $(seq $count); do
21640                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21641                 cancel_lru_locks $OSC || true
21642         done
21643 }
21644
21645 test_241_dio() {
21646         local count=$1
21647         local bsize=$2
21648
21649         for LOOP in $(seq $1); do
21650                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21651                         2>/dev/null
21652         done
21653 }
21654
21655 test_241a() { # was test_241
21656         local bsize=$PAGE_SIZE
21657
21658         (( bsize < 40960 )) && bsize=40960
21659         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21660         ls -la $DIR/$tfile
21661         cancel_lru_locks $OSC
21662         test_241_bio 1000 $bsize &
21663         PID=$!
21664         test_241_dio 1000 $bsize
21665         wait $PID
21666 }
21667 run_test 241a "bio vs dio"
21668
21669 test_241b() {
21670         local bsize=$PAGE_SIZE
21671
21672         (( bsize < 40960 )) && bsize=40960
21673         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21674         ls -la $DIR/$tfile
21675         test_241_dio 1000 $bsize &
21676         PID=$!
21677         test_241_dio 1000 $bsize
21678         wait $PID
21679 }
21680 run_test 241b "dio vs dio"
21681
21682 test_242() {
21683         remote_mds_nodsh && skip "remote MDS with nodsh"
21684
21685         mkdir_on_mdt0 $DIR/$tdir
21686         touch $DIR/$tdir/$tfile
21687
21688         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
21689         do_facet mds1 lctl set_param fail_loc=0x105
21690         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
21691
21692         do_facet mds1 lctl set_param fail_loc=0
21693         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
21694 }
21695 run_test 242 "mdt_readpage failure should not cause directory unreadable"
21696
21697 test_243()
21698 {
21699         test_mkdir $DIR/$tdir
21700         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
21701 }
21702 run_test 243 "various group lock tests"
21703
21704 test_244a()
21705 {
21706         test_mkdir $DIR/$tdir
21707         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
21708         sendfile_grouplock $DIR/$tdir/$tfile || \
21709                 error "sendfile+grouplock failed"
21710         rm -rf $DIR/$tdir
21711 }
21712 run_test 244a "sendfile with group lock tests"
21713
21714 test_244b()
21715 {
21716         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21717
21718         local threads=50
21719         local size=$((1024*1024))
21720
21721         test_mkdir $DIR/$tdir
21722         for i in $(seq 1 $threads); do
21723                 local file=$DIR/$tdir/file_$((i / 10))
21724                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
21725                 local pids[$i]=$!
21726         done
21727         for i in $(seq 1 $threads); do
21728                 wait ${pids[$i]}
21729         done
21730 }
21731 run_test 244b "multi-threaded write with group lock"
21732
21733 test_245a() {
21734         local flagname="multi_mod_rpcs"
21735         local connect_data_name="max_mod_rpcs"
21736         local out
21737
21738         # check if multiple modify RPCs flag is set
21739         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
21740                 grep "connect_flags:")
21741         echo "$out"
21742
21743         echo "$out" | grep -qw $flagname
21744         if [ $? -ne 0 ]; then
21745                 echo "connect flag $flagname is not set"
21746                 return
21747         fi
21748
21749         # check if multiple modify RPCs data is set
21750         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
21751         echo "$out"
21752
21753         echo "$out" | grep -qw $connect_data_name ||
21754                 error "import should have connect data $connect_data_name"
21755 }
21756 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
21757
21758 test_245b() {
21759         local flagname="multi_mod_rpcs"
21760         local connect_data_name="max_mod_rpcs"
21761         local out
21762
21763         remote_mds_nodsh && skip "remote MDS with nodsh"
21764         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
21765
21766         # check if multiple modify RPCs flag is set
21767         out=$(do_facet mds1 \
21768               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
21769               grep "connect_flags:")
21770         echo "$out"
21771
21772         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
21773
21774         # check if multiple modify RPCs data is set
21775         out=$(do_facet mds1 \
21776               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
21777
21778         [[ "$out" =~ $connect_data_name ]] ||
21779                 {
21780                         echo "$out"
21781                         error "missing connect data $connect_data_name"
21782                 }
21783 }
21784 run_test 245b "check osp connection flag/data: multiple modify RPCs"
21785
21786 cleanup_247() {
21787         local submount=$1
21788
21789         trap 0
21790         umount_client $submount
21791         rmdir $submount
21792 }
21793
21794 test_247a() {
21795         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21796                 grep -q subtree ||
21797                 skip_env "Fileset feature is not supported"
21798
21799         local submount=${MOUNT}_$tdir
21800
21801         mkdir $MOUNT/$tdir
21802         mkdir -p $submount || error "mkdir $submount failed"
21803         FILESET="$FILESET/$tdir" mount_client $submount ||
21804                 error "mount $submount failed"
21805         trap "cleanup_247 $submount" EXIT
21806         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
21807         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
21808                 error "read $MOUNT/$tdir/$tfile failed"
21809         cleanup_247 $submount
21810 }
21811 run_test 247a "mount subdir as fileset"
21812
21813 test_247b() {
21814         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21815                 skip_env "Fileset feature is not supported"
21816
21817         local submount=${MOUNT}_$tdir
21818
21819         rm -rf $MOUNT/$tdir
21820         mkdir -p $submount || error "mkdir $submount failed"
21821         SKIP_FILESET=1
21822         FILESET="$FILESET/$tdir" mount_client $submount &&
21823                 error "mount $submount should fail"
21824         rmdir $submount
21825 }
21826 run_test 247b "mount subdir that dose not exist"
21827
21828 test_247c() {
21829         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21830                 skip_env "Fileset feature is not supported"
21831
21832         local submount=${MOUNT}_$tdir
21833
21834         mkdir -p $MOUNT/$tdir/dir1
21835         mkdir -p $submount || error "mkdir $submount failed"
21836         trap "cleanup_247 $submount" EXIT
21837         FILESET="$FILESET/$tdir" mount_client $submount ||
21838                 error "mount $submount failed"
21839         local fid=$($LFS path2fid $MOUNT/)
21840         $LFS fid2path $submount $fid && error "fid2path should fail"
21841         cleanup_247 $submount
21842 }
21843 run_test 247c "running fid2path outside subdirectory root"
21844
21845 test_247d() {
21846         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21847                 skip "Fileset feature is not supported"
21848
21849         local submount=${MOUNT}_$tdir
21850
21851         mkdir -p $MOUNT/$tdir/dir1
21852         mkdir -p $submount || error "mkdir $submount failed"
21853         FILESET="$FILESET/$tdir" mount_client $submount ||
21854                 error "mount $submount failed"
21855         trap "cleanup_247 $submount" EXIT
21856
21857         local td=$submount/dir1
21858         local fid=$($LFS path2fid $td)
21859         [ -z "$fid" ] && error "path2fid unable to get $td FID"
21860
21861         # check that we get the same pathname back
21862         local rootpath
21863         local found
21864         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
21865                 echo "$rootpath $fid"
21866                 found=$($LFS fid2path $rootpath "$fid")
21867                 [ -n "$found" ] || error "fid2path should succeed"
21868                 [ "$found" == "$td" ] || error "fid2path $found != $td"
21869         done
21870         # check wrong root path format
21871         rootpath=$submount"_wrong"
21872         found=$($LFS fid2path $rootpath "$fid")
21873         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
21874
21875         cleanup_247 $submount
21876 }
21877 run_test 247d "running fid2path inside subdirectory root"
21878
21879 # LU-8037
21880 test_247e() {
21881         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
21882                 grep -q subtree ||
21883                 skip "Fileset feature is not supported"
21884
21885         local submount=${MOUNT}_$tdir
21886
21887         mkdir $MOUNT/$tdir
21888         mkdir -p $submount || error "mkdir $submount failed"
21889         FILESET="$FILESET/.." mount_client $submount &&
21890                 error "mount $submount should fail"
21891         rmdir $submount
21892 }
21893 run_test 247e "mount .. as fileset"
21894
21895 test_247f() {
21896         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
21897         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
21898                 skip "Need at least version 2.14.50.162"
21899         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
21900                 skip "Fileset feature is not supported"
21901
21902         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21903         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
21904                 error "mkdir remote failed"
21905         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
21906                 error "mkdir remote/subdir failed"
21907         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
21908                 error "mkdir striped failed"
21909         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
21910
21911         local submount=${MOUNT}_$tdir
21912
21913         mkdir -p $submount || error "mkdir $submount failed"
21914         stack_trap "rmdir $submount"
21915
21916         local dir
21917         local fileset=$FILESET
21918         local mdts=$(comma_list $(mdts_nodes))
21919
21920         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21921         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
21922                 $tdir/striped/subdir $tdir/striped/.; do
21923                 FILESET="$fileset/$dir" mount_client $submount ||
21924                         error "mount $dir failed"
21925                 umount_client $submount
21926         done
21927 }
21928 run_test 247f "mount striped or remote directory as fileset"
21929
21930 test_subdir_mount_lock()
21931 {
21932         local testdir=$1
21933         local submount=${MOUNT}_$(basename $testdir)
21934
21935         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
21936
21937         mkdir -p $submount || error "mkdir $submount failed"
21938         stack_trap "rmdir $submount"
21939
21940         FILESET="$fileset/$testdir" mount_client $submount ||
21941                 error "mount $FILESET failed"
21942         stack_trap "umount $submount"
21943
21944         local mdts=$(comma_list $(mdts_nodes))
21945
21946         local nrpcs
21947
21948         stat $submount > /dev/null || error "stat $submount failed"
21949         cancel_lru_locks $MDC
21950         stat $submount > /dev/null || error "stat $submount failed"
21951         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21952         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21953         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
21954         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21955                 awk '/getattr/ {sum += $2} END {print sum}')
21956
21957         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21958 }
21959
21960 test_247g() {
21961         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21962
21963         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21964                 error "mkdir $tdir failed"
21965         test_subdir_mount_lock $tdir
21966 }
21967 run_test 247g "striped directory submount revalidate ROOT from cache"
21968
21969 test_247h() {
21970         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
21971         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
21972                 skip "Need MDS version at least 2.15.51"
21973
21974         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
21975         test_subdir_mount_lock $tdir
21976         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
21977         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
21978                 error "mkdir $tdir.1 failed"
21979         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
21980 }
21981 run_test 247h "remote directory submount revalidate ROOT from cache"
21982
21983 test_248a() {
21984         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21985         [ -z "$fast_read_sav" ] && skip "no fast read support"
21986
21987         # create a large file for fast read verification
21988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21989
21990         # make sure the file is created correctly
21991         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21992                 { rm -f $DIR/$tfile; skip "file creation error"; }
21993
21994         echo "Test 1: verify that fast read is 4 times faster on cache read"
21995
21996         # small read with fast read enabled
21997         $LCTL set_param -n llite.*.fast_read=1
21998         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21999                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22000                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22001         # small read with fast read disabled
22002         $LCTL set_param -n llite.*.fast_read=0
22003         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22004                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22005                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22006
22007         # verify that fast read is 4 times faster for cache read
22008         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22009                 error_not_in_vm "fast read was not 4 times faster: " \
22010                            "$t_fast vs $t_slow"
22011
22012         echo "Test 2: verify the performance between big and small read"
22013         $LCTL set_param -n llite.*.fast_read=1
22014
22015         # 1k non-cache read
22016         cancel_lru_locks osc
22017         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22018                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22019                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22020
22021         # 1M non-cache read
22022         cancel_lru_locks osc
22023         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22024                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22025                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22026
22027         # verify that big IO is not 4 times faster than small IO
22028         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22029                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22030
22031         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22032         rm -f $DIR/$tfile
22033 }
22034 run_test 248a "fast read verification"
22035
22036 test_248b() {
22037         # Default short_io_bytes=16384, try both smaller and larger sizes.
22038         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22039         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22040         echo "bs=53248 count=113 normal buffered write"
22041         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22042                 error "dd of initial data file failed"
22043         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22044
22045         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22046         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22047                 error "dd with sync normal writes failed"
22048         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22049
22050         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22051         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22052                 error "dd with sync small writes failed"
22053         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22054
22055         cancel_lru_locks osc
22056
22057         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22058         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22059         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22060         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22061                 iflag=direct || error "dd with O_DIRECT small read failed"
22062         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22063         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22064                 error "compare $TMP/$tfile.1 failed"
22065
22066         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22067         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22068
22069         # just to see what the maximum tunable value is, and test parsing
22070         echo "test invalid parameter 2MB"
22071         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22072                 error "too-large short_io_bytes allowed"
22073         echo "test maximum parameter 512KB"
22074         # if we can set a larger short_io_bytes, run test regardless of version
22075         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22076                 # older clients may not allow setting it this large, that's OK
22077                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22078                         skip "Need at least client version 2.13.50"
22079                 error "medium short_io_bytes failed"
22080         fi
22081         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22082         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22083
22084         echo "test large parameter 64KB"
22085         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22086         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22087
22088         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22089         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22090                 error "dd with sync large writes failed"
22091         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22092
22093         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22094         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22095         num=$((113 * 4096 / PAGE_SIZE))
22096         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22097         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22098                 error "dd with O_DIRECT large writes failed"
22099         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22100                 error "compare $DIR/$tfile.3 failed"
22101
22102         cancel_lru_locks osc
22103
22104         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22105         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22106                 error "dd with O_DIRECT large read failed"
22107         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22108                 error "compare $TMP/$tfile.2 failed"
22109
22110         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22111         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22112                 error "dd with O_DIRECT large read failed"
22113         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22114                 error "compare $TMP/$tfile.3 failed"
22115 }
22116 run_test 248b "test short_io read and write for both small and large sizes"
22117
22118 test_249() { # LU-7890
22119         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22120                 skip "Need at least version 2.8.54"
22121
22122         rm -f $DIR/$tfile
22123         $LFS setstripe -c 1 $DIR/$tfile
22124         # Offset 2T == 4k * 512M
22125         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22126                 error "dd to 2T offset failed"
22127 }
22128 run_test 249 "Write above 2T file size"
22129
22130 test_250() {
22131         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22132          && skip "no 16TB file size limit on ZFS"
22133
22134         $LFS setstripe -c 1 $DIR/$tfile
22135         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22136         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22137         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22138         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22139                 conv=notrunc,fsync && error "append succeeded"
22140         return 0
22141 }
22142 run_test 250 "Write above 16T limit"
22143
22144 test_251() {
22145         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22146
22147         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22148         #Skip once - writing the first stripe will succeed
22149         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22150         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22151                 error "short write happened"
22152
22153         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22154         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22155                 error "short read happened"
22156
22157         rm -f $DIR/$tfile
22158 }
22159 run_test 251 "Handling short read and write correctly"
22160
22161 test_252() {
22162         remote_mds_nodsh && skip "remote MDS with nodsh"
22163         remote_ost_nodsh && skip "remote OST with nodsh"
22164         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22165                 skip_env "ldiskfs only test"
22166         fi
22167
22168         local tgt
22169         local dev
22170         local out
22171         local uuid
22172         local num
22173         local gen
22174
22175         # check lr_reader on OST0000
22176         tgt=ost1
22177         dev=$(facet_device $tgt)
22178         out=$(do_facet $tgt $LR_READER $dev)
22179         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22180         echo "$out"
22181         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22182         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22183                 error "Invalid uuid returned by $LR_READER on target $tgt"
22184         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22185
22186         # check lr_reader -c on MDT0000
22187         tgt=mds1
22188         dev=$(facet_device $tgt)
22189         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22190                 skip "$LR_READER does not support additional options"
22191         fi
22192         out=$(do_facet $tgt $LR_READER -c $dev)
22193         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22194         echo "$out"
22195         num=$(echo "$out" | grep -c "mdtlov")
22196         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22197                 error "Invalid number of mdtlov clients returned by $LR_READER"
22198         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22199
22200         # check lr_reader -cr on MDT0000
22201         out=$(do_facet $tgt $LR_READER -cr $dev)
22202         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22203         echo "$out"
22204         echo "$out" | grep -q "^reply_data:$" ||
22205                 error "$LR_READER should have returned 'reply_data' section"
22206         num=$(echo "$out" | grep -c "client_generation")
22207         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22208 }
22209 run_test 252 "check lr_reader tool"
22210
22211 test_253() {
22212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22213         remote_mds_nodsh && skip "remote MDS with nodsh"
22214         remote_mgs_nodsh && skip "remote MGS with nodsh"
22215
22216         local ostidx=0
22217         local rc=0
22218         local ost_name=$(ostname_from_index $ostidx)
22219
22220         # on the mdt's osc
22221         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22222         do_facet $SINGLEMDS $LCTL get_param -n \
22223                 osp.$mdtosc_proc1.reserved_mb_high ||
22224                 skip  "remote MDS does not support reserved_mb_high"
22225
22226         rm -rf $DIR/$tdir
22227         wait_mds_ost_sync
22228         wait_delete_completed
22229         mkdir $DIR/$tdir
22230
22231         pool_add $TESTNAME || error "Pool creation failed"
22232         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22233
22234         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22235                 error "Setstripe failed"
22236
22237         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22238
22239         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22240                     grep "watermarks")
22241         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22242
22243         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22244                         osp.$mdtosc_proc1.prealloc_status)
22245         echo "prealloc_status $oa_status"
22246
22247         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22248                 error "File creation should fail"
22249
22250         #object allocation was stopped, but we still able to append files
22251         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22252                 oflag=append || error "Append failed"
22253
22254         rm -f $DIR/$tdir/$tfile.0
22255
22256         # For this test, we want to delete the files we created to go out of
22257         # space but leave the watermark, so we remain nearly out of space
22258         ost_watermarks_enospc_delete_files $tfile $ostidx
22259
22260         wait_delete_completed
22261
22262         sleep_maxage
22263
22264         for i in $(seq 10 12); do
22265                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22266                         2>/dev/null || error "File creation failed after rm"
22267         done
22268
22269         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22270                         osp.$mdtosc_proc1.prealloc_status)
22271         echo "prealloc_status $oa_status"
22272
22273         if (( oa_status != 0 )); then
22274                 error "Object allocation still disable after rm"
22275         fi
22276 }
22277 run_test 253 "Check object allocation limit"
22278
22279 test_254() {
22280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22281         remote_mds_nodsh && skip "remote MDS with nodsh"
22282
22283         local mdt=$(facet_svc $SINGLEMDS)
22284
22285         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22286                 skip "MDS does not support changelog_size"
22287
22288         local cl_user
22289
22290         changelog_register || error "changelog_register failed"
22291
22292         changelog_clear 0 || error "changelog_clear failed"
22293
22294         local size1=$(do_facet $SINGLEMDS \
22295                       $LCTL get_param -n mdd.$mdt.changelog_size)
22296         echo "Changelog size $size1"
22297
22298         rm -rf $DIR/$tdir
22299         $LFS mkdir -i 0 $DIR/$tdir
22300         # change something
22301         mkdir -p $DIR/$tdir/pics/2008/zachy
22302         touch $DIR/$tdir/pics/2008/zachy/timestamp
22303         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22304         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22305         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22306         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22307         rm $DIR/$tdir/pics/desktop.jpg
22308
22309         local size2=$(do_facet $SINGLEMDS \
22310                       $LCTL get_param -n mdd.$mdt.changelog_size)
22311         echo "Changelog size after work $size2"
22312
22313         (( $size2 > $size1 )) ||
22314                 error "new Changelog size=$size2 less than old size=$size1"
22315 }
22316 run_test 254 "Check changelog size"
22317
22318 ladvise_no_type()
22319 {
22320         local type=$1
22321         local file=$2
22322
22323         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22324                 awk -F: '{print $2}' | grep $type > /dev/null
22325         if [ $? -ne 0 ]; then
22326                 return 0
22327         fi
22328         return 1
22329 }
22330
22331 ladvise_no_ioctl()
22332 {
22333         local file=$1
22334
22335         lfs ladvise -a willread $file > /dev/null 2>&1
22336         if [ $? -eq 0 ]; then
22337                 return 1
22338         fi
22339
22340         lfs ladvise -a willread $file 2>&1 |
22341                 grep "Inappropriate ioctl for device" > /dev/null
22342         if [ $? -eq 0 ]; then
22343                 return 0
22344         fi
22345         return 1
22346 }
22347
22348 percent() {
22349         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22350 }
22351
22352 # run a random read IO workload
22353 # usage: random_read_iops <filename> <filesize> <iosize>
22354 random_read_iops() {
22355         local file=$1
22356         local fsize=$2
22357         local iosize=${3:-4096}
22358
22359         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22360                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22361 }
22362
22363 drop_file_oss_cache() {
22364         local file="$1"
22365         local nodes="$2"
22366
22367         $LFS ladvise -a dontneed $file 2>/dev/null ||
22368                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22369 }
22370
22371 ladvise_willread_performance()
22372 {
22373         local repeat=10
22374         local average_origin=0
22375         local average_cache=0
22376         local average_ladvise=0
22377
22378         for ((i = 1; i <= $repeat; i++)); do
22379                 echo "Iter $i/$repeat: reading without willread hint"
22380                 cancel_lru_locks osc
22381                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22382                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22383                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22384                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22385
22386                 cancel_lru_locks osc
22387                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22388                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22389                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22390
22391                 cancel_lru_locks osc
22392                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22393                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22394                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22395                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22396                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22397         done
22398         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22399         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22400         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22401
22402         speedup_cache=$(percent $average_cache $average_origin)
22403         speedup_ladvise=$(percent $average_ladvise $average_origin)
22404
22405         echo "Average uncached read: $average_origin"
22406         echo "Average speedup with OSS cached read: " \
22407                 "$average_cache = +$speedup_cache%"
22408         echo "Average speedup with ladvise willread: " \
22409                 "$average_ladvise = +$speedup_ladvise%"
22410
22411         local lowest_speedup=20
22412         if (( ${average_cache%.*} < $lowest_speedup )); then
22413                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22414                      " got $average_cache%. Skipping ladvise willread check."
22415                 return 0
22416         fi
22417
22418         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22419         # it is still good to run until then to exercise 'ladvise willread'
22420         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22421                 [ "$ost1_FSTYPE" = "zfs" ] &&
22422                 echo "osd-zfs does not support dontneed or drop_caches" &&
22423                 return 0
22424
22425         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22426         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22427                 error_not_in_vm "Speedup with willread is less than " \
22428                         "$lowest_speedup%, got $average_ladvise%"
22429 }
22430
22431 test_255a() {
22432         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22433                 skip "lustre < 2.8.54 does not support ladvise "
22434         remote_ost_nodsh && skip "remote OST with nodsh"
22435
22436         stack_trap "rm -f $DIR/$tfile"
22437         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22438
22439         ladvise_no_type willread $DIR/$tfile &&
22440                 skip "willread ladvise is not supported"
22441
22442         ladvise_no_ioctl $DIR/$tfile &&
22443                 skip "ladvise ioctl is not supported"
22444
22445         local size_mb=100
22446         local size=$((size_mb * 1048576))
22447         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22448                 error "dd to $DIR/$tfile failed"
22449
22450         lfs ladvise -a willread $DIR/$tfile ||
22451                 error "Ladvise failed with no range argument"
22452
22453         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22454                 error "Ladvise failed with no -l or -e argument"
22455
22456         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22457                 error "Ladvise failed with only -e argument"
22458
22459         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22460                 error "Ladvise failed with only -l argument"
22461
22462         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22463                 error "End offset should not be smaller than start offset"
22464
22465         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22466                 error "End offset should not be equal to start offset"
22467
22468         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22469                 error "Ladvise failed with overflowing -s argument"
22470
22471         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22472                 error "Ladvise failed with overflowing -e argument"
22473
22474         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22475                 error "Ladvise failed with overflowing -l argument"
22476
22477         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22478                 error "Ladvise succeeded with conflicting -l and -e arguments"
22479
22480         echo "Synchronous ladvise should wait"
22481         local delay=4
22482 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22483         do_nodes $(comma_list $(osts_nodes)) \
22484                 $LCTL set_param fail_val=$delay fail_loc=0x237
22485
22486         local start_ts=$SECONDS
22487         lfs ladvise -a willread $DIR/$tfile ||
22488                 error "Ladvise failed with no range argument"
22489         local end_ts=$SECONDS
22490         local inteval_ts=$((end_ts - start_ts))
22491
22492         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22493                 error "Synchronous advice didn't wait reply"
22494         fi
22495
22496         echo "Asynchronous ladvise shouldn't wait"
22497         local start_ts=$SECONDS
22498         lfs ladvise -a willread -b $DIR/$tfile ||
22499                 error "Ladvise failed with no range argument"
22500         local end_ts=$SECONDS
22501         local inteval_ts=$((end_ts - start_ts))
22502
22503         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22504                 error "Asynchronous advice blocked"
22505         fi
22506
22507         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22508         ladvise_willread_performance
22509 }
22510 run_test 255a "check 'lfs ladvise -a willread'"
22511
22512 facet_meminfo() {
22513         local facet=$1
22514         local info=$2
22515
22516         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22517 }
22518
22519 test_255b() {
22520         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22521                 skip "lustre < 2.8.54 does not support ladvise "
22522         remote_ost_nodsh && skip "remote OST with nodsh"
22523
22524         stack_trap "rm -f $DIR/$tfile"
22525         lfs setstripe -c 1 -i 0 $DIR/$tfile
22526
22527         ladvise_no_type dontneed $DIR/$tfile &&
22528                 skip "dontneed ladvise is not supported"
22529
22530         ladvise_no_ioctl $DIR/$tfile &&
22531                 skip "ladvise ioctl is not supported"
22532
22533         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22534                 [ "$ost1_FSTYPE" = "zfs" ] &&
22535                 skip "zfs-osd does not support 'ladvise dontneed'"
22536
22537         local size_mb=100
22538         local size=$((size_mb * 1048576))
22539         # In order to prevent disturbance of other processes, only check 3/4
22540         # of the memory usage
22541         local kibibytes=$((size_mb * 1024 * 3 / 4))
22542
22543         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22544                 error "dd to $DIR/$tfile failed"
22545
22546         #force write to complete before dropping OST cache & checking memory
22547         sync
22548
22549         local total=$(facet_meminfo ost1 MemTotal)
22550         echo "Total memory: $total KiB"
22551
22552         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22553         local before_read=$(facet_meminfo ost1 Cached)
22554         echo "Cache used before read: $before_read KiB"
22555
22556         lfs ladvise -a willread $DIR/$tfile ||
22557                 error "Ladvise willread failed"
22558         local after_read=$(facet_meminfo ost1 Cached)
22559         echo "Cache used after read: $after_read KiB"
22560
22561         lfs ladvise -a dontneed $DIR/$tfile ||
22562                 error "Ladvise dontneed again failed"
22563         local no_read=$(facet_meminfo ost1 Cached)
22564         echo "Cache used after dontneed ladvise: $no_read KiB"
22565
22566         if [ $total -lt $((before_read + kibibytes)) ]; then
22567                 echo "Memory is too small, abort checking"
22568                 return 0
22569         fi
22570
22571         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22572                 error "Ladvise willread should use more memory" \
22573                         "than $kibibytes KiB"
22574         fi
22575
22576         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22577                 error "Ladvise dontneed should release more memory" \
22578                         "than $kibibytes KiB"
22579         fi
22580 }
22581 run_test 255b "check 'lfs ladvise -a dontneed'"
22582
22583 test_255c() {
22584         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22585                 skip "lustre < 2.10.50 does not support lockahead"
22586
22587         local ost1_imp=$(get_osc_import_name client ost1)
22588         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22589                          cut -d'.' -f2)
22590         local count
22591         local new_count
22592         local difference
22593         local i
22594         local rc
22595
22596         test_mkdir -p $DIR/$tdir
22597         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22598
22599         #test 10 returns only success/failure
22600         i=10
22601         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22602         rc=$?
22603         if [ $rc -eq 255 ]; then
22604                 error "Ladvise test${i} failed, ${rc}"
22605         fi
22606
22607         #test 11 counts lock enqueue requests, all others count new locks
22608         i=11
22609         count=$(do_facet ost1 \
22610                 $LCTL get_param -n ost.OSS.ost.stats)
22611         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22612
22613         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22614         rc=$?
22615         if [ $rc -eq 255 ]; then
22616                 error "Ladvise test${i} failed, ${rc}"
22617         fi
22618
22619         new_count=$(do_facet ost1 \
22620                 $LCTL get_param -n ost.OSS.ost.stats)
22621         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22622                    awk '{ print $2 }')
22623
22624         difference="$((new_count - count))"
22625         if [ $difference -ne $rc ]; then
22626                 error "Ladvise test${i}, bad enqueue count, returned " \
22627                       "${rc}, actual ${difference}"
22628         fi
22629
22630         for i in $(seq 12 21); do
22631                 # If we do not do this, we run the risk of having too many
22632                 # locks and starting lock cancellation while we are checking
22633                 # lock counts.
22634                 cancel_lru_locks osc
22635
22636                 count=$($LCTL get_param -n \
22637                        ldlm.namespaces.$imp_name.lock_unused_count)
22638
22639                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22640                 rc=$?
22641                 if [ $rc -eq 255 ]; then
22642                         error "Ladvise test ${i} failed, ${rc}"
22643                 fi
22644
22645                 new_count=$($LCTL get_param -n \
22646                        ldlm.namespaces.$imp_name.lock_unused_count)
22647                 difference="$((new_count - count))"
22648
22649                 # Test 15 output is divided by 100 to map down to valid return
22650                 if [ $i -eq 15 ]; then
22651                         rc="$((rc * 100))"
22652                 fi
22653
22654                 if [ $difference -ne $rc ]; then
22655                         error "Ladvise test ${i}, bad lock count, returned " \
22656                               "${rc}, actual ${difference}"
22657                 fi
22658         done
22659
22660         #test 22 returns only success/failure
22661         i=22
22662         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22663         rc=$?
22664         if [ $rc -eq 255 ]; then
22665                 error "Ladvise test${i} failed, ${rc}"
22666         fi
22667 }
22668 run_test 255c "suite of ladvise lockahead tests"
22669
22670 test_256() {
22671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22672         remote_mds_nodsh && skip "remote MDS with nodsh"
22673         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22674         changelog_users $SINGLEMDS | grep "^cl" &&
22675                 skip "active changelog user"
22676
22677         local cl_user
22678         local cat_sl
22679         local mdt_dev
22680
22681         mdt_dev=$(facet_device $SINGLEMDS)
22682         echo $mdt_dev
22683
22684         changelog_register || error "changelog_register failed"
22685
22686         rm -rf $DIR/$tdir
22687         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
22688
22689         changelog_clear 0 || error "changelog_clear failed"
22690
22691         # change something
22692         touch $DIR/$tdir/{1..10}
22693
22694         # stop the MDT
22695         stop $SINGLEMDS || error "Fail to stop MDT"
22696
22697         # remount the MDT
22698         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22699                 error "Fail to start MDT"
22700
22701         #after mount new plainllog is used
22702         touch $DIR/$tdir/{11..19}
22703         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
22704         stack_trap "rm -f $tmpfile"
22705         cat_sl=$(do_facet $SINGLEMDS "sync; \
22706                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22707                  llog_reader $tmpfile | grep -c type=1064553b")
22708         do_facet $SINGLEMDS llog_reader $tmpfile
22709
22710         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
22711
22712         changelog_clear 0 || error "changelog_clear failed"
22713
22714         cat_sl=$(do_facet $SINGLEMDS "sync; \
22715                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
22716                  llog_reader $tmpfile | grep -c type=1064553b")
22717
22718         if (( cat_sl == 2 )); then
22719                 error "Empty plain llog was not deleted from changelog catalog"
22720         elif (( cat_sl != 1 )); then
22721                 error "Active plain llog shouldn't be deleted from catalog"
22722         fi
22723 }
22724 run_test 256 "Check llog delete for empty and not full state"
22725
22726 test_257() {
22727         remote_mds_nodsh && skip "remote MDS with nodsh"
22728         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22729                 skip "Need MDS version at least 2.8.55"
22730
22731         test_mkdir $DIR/$tdir
22732
22733         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
22734                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
22735         stat $DIR/$tdir
22736
22737 #define OBD_FAIL_MDS_XATTR_REP                  0x161
22738         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22739         local facet=mds$((mdtidx + 1))
22740         set_nodes_failloc $(facet_active_host $facet) 0x80000161
22741         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
22742
22743         stop $facet || error "stop MDS failed"
22744         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
22745                 error "start MDS fail"
22746         wait_recovery_complete $facet
22747 }
22748 run_test 257 "xattr locks are not lost"
22749
22750 # Verify we take the i_mutex when security requires it
22751 test_258a() {
22752 #define OBD_FAIL_IMUTEX_SEC 0x141c
22753         $LCTL set_param fail_loc=0x141c
22754         touch $DIR/$tfile
22755         chmod u+s $DIR/$tfile
22756         chmod a+rwx $DIR/$tfile
22757         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22758         RC=$?
22759         if [ $RC -ne 0 ]; then
22760                 error "error, failed to take i_mutex, rc=$?"
22761         fi
22762         rm -f $DIR/$tfile
22763 }
22764 run_test 258a "verify i_mutex security behavior when suid attributes is set"
22765
22766 # Verify we do NOT take the i_mutex in the normal case
22767 test_258b() {
22768 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
22769         $LCTL set_param fail_loc=0x141d
22770         touch $DIR/$tfile
22771         chmod a+rwx $DIR
22772         chmod a+rw $DIR/$tfile
22773         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
22774         RC=$?
22775         if [ $RC -ne 0 ]; then
22776                 error "error, took i_mutex unnecessarily, rc=$?"
22777         fi
22778         rm -f $DIR/$tfile
22779
22780 }
22781 run_test 258b "verify i_mutex security behavior"
22782
22783 test_259() {
22784         local file=$DIR/$tfile
22785         local before
22786         local after
22787
22788         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22789
22790         stack_trap "rm -f $file" EXIT
22791
22792         wait_delete_completed
22793         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22794         echo "before: $before"
22795
22796         $LFS setstripe -i 0 -c 1 $file
22797         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
22798         sync_all_data
22799         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22800         echo "after write: $after"
22801
22802 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
22803         do_facet ost1 $LCTL set_param fail_loc=0x2301
22804         $TRUNCATE $file 0
22805         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22806         echo "after truncate: $after"
22807
22808         stop ost1
22809         do_facet ost1 $LCTL set_param fail_loc=0
22810         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
22811         sleep 2
22812         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
22813         echo "after restart: $after"
22814         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
22815                 error "missing truncate?"
22816
22817         return 0
22818 }
22819 run_test 259 "crash at delayed truncate"
22820
22821 test_260() {
22822 #define OBD_FAIL_MDC_CLOSE               0x806
22823         $LCTL set_param fail_loc=0x80000806
22824         touch $DIR/$tfile
22825
22826 }
22827 run_test 260 "Check mdc_close fail"
22828
22829 ### Data-on-MDT sanity tests ###
22830 test_270a() {
22831         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22832                 skip "Need MDS version at least 2.10.55 for DoM"
22833
22834         # create DoM file
22835         local dom=$DIR/$tdir/dom_file
22836         local tmp=$DIR/$tdir/tmp_file
22837
22838         mkdir_on_mdt0 $DIR/$tdir
22839
22840         # basic checks for DoM component creation
22841         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
22842                 error "Can set MDT layout to non-first entry"
22843
22844         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
22845                 error "Can define multiple entries as MDT layout"
22846
22847         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
22848
22849         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
22850         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
22851         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
22852
22853         local mdtidx=$($LFS getstripe -m $dom)
22854         local mdtname=MDT$(printf %04x $mdtidx)
22855         local facet=mds$((mdtidx + 1))
22856         local space_check=1
22857
22858         # Skip free space checks with ZFS
22859         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
22860
22861         # write
22862         sync
22863         local size_tmp=$((65536 * 3))
22864         local mdtfree1=$(do_facet $facet \
22865                          lctl get_param -n osd*.*$mdtname.kbytesfree)
22866
22867         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22868         # check also direct IO along write
22869         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
22870         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22871         sync
22872         cmp $tmp $dom || error "file data is different"
22873         [ $(stat -c%s $dom) == $size_tmp ] ||
22874                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22875         if [ $space_check == 1 ]; then
22876                 local mdtfree2=$(do_facet $facet \
22877                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
22878
22879                 # increase in usage from by $size_tmp
22880                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22881                         error "MDT free space wrong after write: " \
22882                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22883         fi
22884
22885         # truncate
22886         local size_dom=10000
22887
22888         $TRUNCATE $dom $size_dom
22889         [ $(stat -c%s $dom) == $size_dom ] ||
22890                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
22891         if [ $space_check == 1 ]; then
22892                 mdtfree1=$(do_facet $facet \
22893                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22894                 # decrease in usage from $size_tmp to new $size_dom
22895                 [ $(($mdtfree1 - $mdtfree2)) -ge \
22896                   $(((size_tmp - size_dom) / 1024)) ] ||
22897                         error "MDT free space is wrong after truncate: " \
22898                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
22899         fi
22900
22901         # append
22902         cat $tmp >> $dom
22903         sync
22904         size_dom=$((size_dom + size_tmp))
22905         [ $(stat -c%s $dom) == $size_dom ] ||
22906                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
22907         if [ $space_check == 1 ]; then
22908                 mdtfree2=$(do_facet $facet \
22909                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22910                 # increase in usage by $size_tmp from previous
22911                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
22912                         error "MDT free space is wrong after append: " \
22913                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
22914         fi
22915
22916         # delete
22917         rm $dom
22918         if [ $space_check == 1 ]; then
22919                 mdtfree1=$(do_facet $facet \
22920                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22921                 # decrease in usage by $size_dom from previous
22922                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
22923                         error "MDT free space is wrong after removal: " \
22924                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22925         fi
22926
22927         # combined striping
22928         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22929                 error "Can't create DoM + OST striping"
22930
22931         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22932         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22933         # check also direct IO along write
22934         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22935         sync
22936         cmp $tmp $dom || error "file data is different"
22937         [ $(stat -c%s $dom) == $size_tmp ] ||
22938                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22939         rm $dom $tmp
22940
22941         return 0
22942 }
22943 run_test 270a "DoM: basic functionality tests"
22944
22945 test_270b() {
22946         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22947                 skip "Need MDS version at least 2.10.55"
22948
22949         local dom=$DIR/$tdir/dom_file
22950         local max_size=1048576
22951
22952         mkdir -p $DIR/$tdir
22953         $LFS setstripe -E $max_size -L mdt $dom
22954
22955         # truncate over the limit
22956         $TRUNCATE $dom $(($max_size + 1)) &&
22957                 error "successful truncate over the maximum size"
22958         # write over the limit
22959         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22960                 error "successful write over the maximum size"
22961         # append over the limit
22962         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22963         echo "12345" >> $dom && error "successful append over the maximum size"
22964         rm $dom
22965
22966         return 0
22967 }
22968 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22969
22970 test_270c() {
22971         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22972                 skip "Need MDS version at least 2.10.55"
22973
22974         mkdir -p $DIR/$tdir
22975         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22976
22977         # check files inherit DoM EA
22978         touch $DIR/$tdir/first
22979         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22980                 error "bad pattern"
22981         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22982                 error "bad stripe count"
22983         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22984                 error "bad stripe size"
22985
22986         # check directory inherits DoM EA and uses it as default
22987         mkdir $DIR/$tdir/subdir
22988         touch $DIR/$tdir/subdir/second
22989         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22990                 error "bad pattern in sub-directory"
22991         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22992                 error "bad stripe count in sub-directory"
22993         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22994                 error "bad stripe size in sub-directory"
22995         return 0
22996 }
22997 run_test 270c "DoM: DoM EA inheritance tests"
22998
22999 test_270d() {
23000         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23001                 skip "Need MDS version at least 2.10.55"
23002
23003         mkdir -p $DIR/$tdir
23004         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23005
23006         # inherit default DoM striping
23007         mkdir $DIR/$tdir/subdir
23008         touch $DIR/$tdir/subdir/f1
23009
23010         # change default directory striping
23011         $LFS setstripe -c 1 $DIR/$tdir/subdir
23012         touch $DIR/$tdir/subdir/f2
23013         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23014                 error "wrong default striping in file 2"
23015         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23016                 error "bad pattern in file 2"
23017         return 0
23018 }
23019 run_test 270d "DoM: change striping from DoM to RAID0"
23020
23021 test_270e() {
23022         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23023                 skip "Need MDS version at least 2.10.55"
23024
23025         mkdir -p $DIR/$tdir/dom
23026         mkdir -p $DIR/$tdir/norm
23027         DOMFILES=20
23028         NORMFILES=10
23029         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23030         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23031
23032         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23033         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23034
23035         # find DoM files by layout
23036         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23037         [ $NUM -eq  $DOMFILES ] ||
23038                 error "lfs find -L: found $NUM, expected $DOMFILES"
23039         echo "Test 1: lfs find 20 DOM files by layout: OK"
23040
23041         # there should be 1 dir with default DOM striping
23042         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23043         [ $NUM -eq  1 ] ||
23044                 error "lfs find -L: found $NUM, expected 1 dir"
23045         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23046
23047         # find DoM files by stripe size
23048         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23049         [ $NUM -eq  $DOMFILES ] ||
23050                 error "lfs find -S: found $NUM, expected $DOMFILES"
23051         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23052
23053         # find files by stripe offset except DoM files
23054         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23055         [ $NUM -eq  $NORMFILES ] ||
23056                 error "lfs find -i: found $NUM, expected $NORMFILES"
23057         echo "Test 5: lfs find no DOM files by stripe index: OK"
23058         return 0
23059 }
23060 run_test 270e "DoM: lfs find with DoM files test"
23061
23062 test_270f() {
23063         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23064                 skip "Need MDS version at least 2.10.55"
23065
23066         local mdtname=${FSNAME}-MDT0000-mdtlov
23067         local dom=$DIR/$tdir/dom_file
23068         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23069                                                 lod.$mdtname.dom_stripesize)
23070         local dom_limit=131072
23071
23072         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23073         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23074                                                 lod.$mdtname.dom_stripesize)
23075         [ ${dom_limit} -eq ${dom_current} ] ||
23076                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23077
23078         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23079         $LFS setstripe -d $DIR/$tdir
23080         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23081                 error "Can't set directory default striping"
23082
23083         # exceed maximum stripe size
23084         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23085                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23086         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23087                 error "Able to create DoM component size more than LOD limit"
23088
23089         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23090         dom_current=$(do_facet mds1 $LCTL get_param -n \
23091                                                 lod.$mdtname.dom_stripesize)
23092         [ 0 -eq ${dom_current} ] ||
23093                 error "Can't set zero DoM stripe limit"
23094         rm $dom
23095
23096         # attempt to create DoM file on server with disabled DoM should
23097         # remove DoM entry from layout and be succeed
23098         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23099                 error "Can't create DoM file (DoM is disabled)"
23100         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23101                 error "File has DoM component while DoM is disabled"
23102         rm $dom
23103
23104         # attempt to create DoM file with only DoM stripe should return error
23105         $LFS setstripe -E $dom_limit -L mdt $dom &&
23106                 error "Able to create DoM-only file while DoM is disabled"
23107
23108         # too low values to be aligned with smallest stripe size 64K
23109         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23110         dom_current=$(do_facet mds1 $LCTL get_param -n \
23111                                                 lod.$mdtname.dom_stripesize)
23112         [ 30000 -eq ${dom_current} ] &&
23113                 error "Can set too small DoM stripe limit"
23114
23115         # 64K is a minimal stripe size in Lustre, expect limit of that size
23116         [ 65536 -eq ${dom_current} ] ||
23117                 error "Limit is not set to 64K but ${dom_current}"
23118
23119         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23120         dom_current=$(do_facet mds1 $LCTL get_param -n \
23121                                                 lod.$mdtname.dom_stripesize)
23122         echo $dom_current
23123         [ 2147483648 -eq ${dom_current} ] &&
23124                 error "Can set too large DoM stripe limit"
23125
23126         do_facet mds1 $LCTL set_param -n \
23127                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23128         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23129                 error "Can't create DoM component size after limit change"
23130         do_facet mds1 $LCTL set_param -n \
23131                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23132         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23133                 error "Can't create DoM file after limit decrease"
23134         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23135                 error "Can create big DoM component after limit decrease"
23136         touch ${dom}_def ||
23137                 error "Can't create file with old default layout"
23138
23139         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23140         return 0
23141 }
23142 run_test 270f "DoM: maximum DoM stripe size checks"
23143
23144 test_270g() {
23145         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23146                 skip "Need MDS version at least 2.13.52"
23147         local dom=$DIR/$tdir/$tfile
23148
23149         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23150         local lodname=${FSNAME}-MDT0000-mdtlov
23151
23152         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23153         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23154         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23155         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23156
23157         local dom_limit=1024
23158         local dom_threshold="50%"
23159
23160         $LFS setstripe -d $DIR/$tdir
23161         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23162                 error "Can't set directory default striping"
23163
23164         do_facet mds1 $LCTL set_param -n \
23165                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23166         # set 0 threshold and create DOM file to change tunable stripesize
23167         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23168         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23169                 error "Failed to create $dom file"
23170         # now tunable dom_cur_stripesize should reach maximum
23171         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23172                                         lod.${lodname}.dom_stripesize_cur_kb)
23173         [[ $dom_current == $dom_limit ]] ||
23174                 error "Current DOM stripesize is not maximum"
23175         rm $dom
23176
23177         # set threshold for further tests
23178         do_facet mds1 $LCTL set_param -n \
23179                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23180         echo "DOM threshold is $dom_threshold free space"
23181         local dom_def
23182         local dom_set
23183         # Spoof bfree to exceed threshold
23184         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23185         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23186         for spfree in 40 20 0 15 30 55; do
23187                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23188                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23189                         error "Failed to create $dom file"
23190                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23191                                         lod.${lodname}.dom_stripesize_cur_kb)
23192                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23193                 [[ $dom_def != $dom_current ]] ||
23194                         error "Default stripe size was not changed"
23195                 if (( spfree > 0 )) ; then
23196                         dom_set=$($LFS getstripe -S $dom)
23197                         (( dom_set == dom_def * 1024 )) ||
23198                                 error "DOM component size is still old"
23199                 else
23200                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23201                                 error "DoM component is set with no free space"
23202                 fi
23203                 rm $dom
23204                 dom_current=$dom_def
23205         done
23206 }
23207 run_test 270g "DoM: default DoM stripe size depends on free space"
23208
23209 test_270h() {
23210         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23211                 skip "Need MDS version at least 2.13.53"
23212
23213         local mdtname=${FSNAME}-MDT0000-mdtlov
23214         local dom=$DIR/$tdir/$tfile
23215         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23216
23217         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23218         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23219
23220         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23221         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23222                 error "can't create OST file"
23223         # mirrored file with DOM entry in the second mirror
23224         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23225                 error "can't create mirror with DoM component"
23226
23227         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23228
23229         # DOM component in the middle and has other enries in the same mirror,
23230         # should succeed but lost DoM component
23231         $LFS setstripe --copy=${dom}_1 $dom ||
23232                 error "Can't create file from OST|DOM mirror layout"
23233         # check new file has no DoM layout after all
23234         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23235                 error "File has DoM component while DoM is disabled"
23236 }
23237 run_test 270h "DoM: DoM stripe removal when disabled on server"
23238
23239 test_270i() {
23240         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23241                 skip "Need MDS version at least 2.14.54"
23242
23243         mkdir $DIR/$tdir
23244         # DoM with plain layout
23245         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23246                 error "default plain layout with DoM must fail"
23247         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23248                 error "setstripe plain file layout with DoM must fail"
23249         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23250                 error "default DoM layout with bad striping must fail"
23251         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23252                 error "setstripe to DoM layout with bad striping must fail"
23253         return 0
23254 }
23255 run_test 270i "DoM: setting invalid DoM striping should fail"
23256
23257 test_271a() {
23258         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23259                 skip "Need MDS version at least 2.10.55"
23260
23261         local dom=$DIR/$tdir/dom
23262
23263         mkdir -p $DIR/$tdir
23264
23265         $LFS setstripe -E 1024K -L mdt $dom
23266
23267         lctl set_param -n mdc.*.stats=clear
23268         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23269         cat $dom > /dev/null
23270         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23271         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23272         ls $dom
23273         rm -f $dom
23274 }
23275 run_test 271a "DoM: data is cached for read after write"
23276
23277 test_271b() {
23278         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23279                 skip "Need MDS version at least 2.10.55"
23280
23281         local dom=$DIR/$tdir/dom
23282
23283         mkdir -p $DIR/$tdir
23284
23285         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23286
23287         lctl set_param -n mdc.*.stats=clear
23288         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23289         cancel_lru_locks mdc
23290         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23291         # second stat to check size is cached on client
23292         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23293         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23294         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23295         rm -f $dom
23296 }
23297 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23298
23299 test_271ba() {
23300         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23301                 skip "Need MDS version at least 2.10.55"
23302
23303         local dom=$DIR/$tdir/dom
23304
23305         mkdir -p $DIR/$tdir
23306
23307         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23308
23309         lctl set_param -n mdc.*.stats=clear
23310         lctl set_param -n osc.*.stats=clear
23311         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23312         cancel_lru_locks mdc
23313         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23314         # second stat to check size is cached on client
23315         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23316         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23317         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23318         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23319         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23320         rm -f $dom
23321 }
23322 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23323
23324
23325 get_mdc_stats() {
23326         local mdtidx=$1
23327         local param=$2
23328         local mdt=MDT$(printf %04x $mdtidx)
23329
23330         if [ -z $param ]; then
23331                 lctl get_param -n mdc.*$mdt*.stats
23332         else
23333                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23334         fi
23335 }
23336
23337 test_271c() {
23338         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23339                 skip "Need MDS version at least 2.10.55"
23340
23341         local dom=$DIR/$tdir/dom
23342
23343         mkdir -p $DIR/$tdir
23344
23345         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23346
23347         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23348         local facet=mds$((mdtidx + 1))
23349
23350         cancel_lru_locks mdc
23351         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23352         createmany -o $dom 1000
23353         lctl set_param -n mdc.*.stats=clear
23354         smalliomany -w $dom 1000 200
23355         get_mdc_stats $mdtidx
23356         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23357         # Each file has 1 open, 1 IO enqueues, total 2000
23358         # but now we have also +1 getxattr for security.capability, total 3000
23359         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23360         unlinkmany $dom 1000
23361
23362         cancel_lru_locks mdc
23363         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23364         createmany -o $dom 1000
23365         lctl set_param -n mdc.*.stats=clear
23366         smalliomany -w $dom 1000 200
23367         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23368         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23369         # for OPEN and IO lock.
23370         [ $((enq - enq_2)) -ge 1000 ] ||
23371                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23372         unlinkmany $dom 1000
23373         return 0
23374 }
23375 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23376
23377 cleanup_271def_tests() {
23378         trap 0
23379         rm -f $1
23380 }
23381
23382 test_271d() {
23383         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23384                 skip "Need MDS version at least 2.10.57"
23385
23386         local dom=$DIR/$tdir/dom
23387         local tmp=$TMP/$tfile
23388         trap "cleanup_271def_tests $tmp" EXIT
23389
23390         mkdir -p $DIR/$tdir
23391
23392         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23393
23394         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23395
23396         cancel_lru_locks mdc
23397         dd if=/dev/urandom of=$tmp bs=1000 count=1
23398         dd if=$tmp of=$dom bs=1000 count=1
23399         cancel_lru_locks mdc
23400
23401         cat /etc/hosts >> $tmp
23402         lctl set_param -n mdc.*.stats=clear
23403
23404         # append data to the same file it should update local page
23405         echo "Append to the same page"
23406         cat /etc/hosts >> $dom
23407         local num=$(get_mdc_stats $mdtidx ost_read)
23408         local ra=$(get_mdc_stats $mdtidx req_active)
23409         local rw=$(get_mdc_stats $mdtidx req_waittime)
23410
23411         [ -z $num ] || error "$num READ RPC occured"
23412         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23413         echo "... DONE"
23414
23415         # compare content
23416         cmp $tmp $dom || error "file miscompare"
23417
23418         cancel_lru_locks mdc
23419         lctl set_param -n mdc.*.stats=clear
23420
23421         echo "Open and read file"
23422         cat $dom > /dev/null
23423         local num=$(get_mdc_stats $mdtidx ost_read)
23424         local ra=$(get_mdc_stats $mdtidx req_active)
23425         local rw=$(get_mdc_stats $mdtidx req_waittime)
23426
23427         [ -z $num ] || error "$num READ RPC occured"
23428         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23429         echo "... DONE"
23430
23431         # compare content
23432         cmp $tmp $dom || error "file miscompare"
23433
23434         return 0
23435 }
23436 run_test 271d "DoM: read on open (1K file in reply buffer)"
23437
23438 test_271f() {
23439         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23440                 skip "Need MDS version at least 2.10.57"
23441
23442         local dom=$DIR/$tdir/dom
23443         local tmp=$TMP/$tfile
23444         trap "cleanup_271def_tests $tmp" EXIT
23445
23446         mkdir -p $DIR/$tdir
23447
23448         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23449
23450         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23451
23452         cancel_lru_locks mdc
23453         dd if=/dev/urandom of=$tmp bs=265000 count=1
23454         dd if=$tmp of=$dom bs=265000 count=1
23455         cancel_lru_locks mdc
23456         cat /etc/hosts >> $tmp
23457         lctl set_param -n mdc.*.stats=clear
23458
23459         echo "Append to the same page"
23460         cat /etc/hosts >> $dom
23461         local num=$(get_mdc_stats $mdtidx ost_read)
23462         local ra=$(get_mdc_stats $mdtidx req_active)
23463         local rw=$(get_mdc_stats $mdtidx req_waittime)
23464
23465         [ -z $num ] || error "$num READ RPC occured"
23466         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23467         echo "... DONE"
23468
23469         # compare content
23470         cmp $tmp $dom || error "file miscompare"
23471
23472         cancel_lru_locks mdc
23473         lctl set_param -n mdc.*.stats=clear
23474
23475         echo "Open and read file"
23476         cat $dom > /dev/null
23477         local num=$(get_mdc_stats $mdtidx ost_read)
23478         local ra=$(get_mdc_stats $mdtidx req_active)
23479         local rw=$(get_mdc_stats $mdtidx req_waittime)
23480
23481         [ -z $num ] && num=0
23482         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23483         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23484         echo "... DONE"
23485
23486         # compare content
23487         cmp $tmp $dom || error "file miscompare"
23488
23489         return 0
23490 }
23491 run_test 271f "DoM: read on open (200K file and read tail)"
23492
23493 test_271g() {
23494         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23495                 skip "Skipping due to old client or server version"
23496
23497         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23498         # to get layout
23499         $CHECKSTAT -t file $DIR1/$tfile
23500
23501         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23502         MULTIOP_PID=$!
23503         sleep 1
23504         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23505         $LCTL set_param fail_loc=0x80000314
23506         rm $DIR1/$tfile || error "Unlink fails"
23507         RC=$?
23508         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23509         [ $RC -eq 0 ] || error "Failed write to stale object"
23510 }
23511 run_test 271g "Discard DoM data vs client flush race"
23512
23513 test_272a() {
23514         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23515                 skip "Need MDS version at least 2.11.50"
23516
23517         local dom=$DIR/$tdir/dom
23518         mkdir -p $DIR/$tdir
23519
23520         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23521         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23522                 error "failed to write data into $dom"
23523         local old_md5=$(md5sum $dom)
23524
23525         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23526                 error "failed to migrate to the same DoM component"
23527
23528         local new_md5=$(md5sum $dom)
23529
23530         [ "$old_md5" == "$new_md5" ] ||
23531                 error "md5sum differ: $old_md5, $new_md5"
23532
23533         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23534                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23535 }
23536 run_test 272a "DoM migration: new layout with the same DOM component"
23537
23538 test_272b() {
23539         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23540                 skip "Need MDS version at least 2.11.50"
23541
23542         local dom=$DIR/$tdir/dom
23543         mkdir -p $DIR/$tdir
23544         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23545
23546         local mdtidx=$($LFS getstripe -m $dom)
23547         local mdtname=MDT$(printf %04x $mdtidx)
23548         local facet=mds$((mdtidx + 1))
23549
23550         local mdtfree1=$(do_facet $facet \
23551                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23552         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23553                 error "failed to write data into $dom"
23554         local old_md5=$(md5sum $dom)
23555         cancel_lru_locks mdc
23556         local mdtfree1=$(do_facet $facet \
23557                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23558
23559         $LFS migrate -c2 $dom ||
23560                 error "failed to migrate to the new composite layout"
23561         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23562                 error "MDT stripe was not removed"
23563
23564         cancel_lru_locks mdc
23565         local new_md5=$(md5sum $dom)
23566         [ "$old_md5" == "$new_md5" ] ||
23567                 error "$old_md5 != $new_md5"
23568
23569         # Skip free space checks with ZFS
23570         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23571                 local mdtfree2=$(do_facet $facet \
23572                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23573                 [ $mdtfree2 -gt $mdtfree1 ] ||
23574                         error "MDT space is not freed after migration"
23575         fi
23576         return 0
23577 }
23578 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23579
23580 test_272c() {
23581         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23582                 skip "Need MDS version at least 2.11.50"
23583
23584         local dom=$DIR/$tdir/$tfile
23585         mkdir -p $DIR/$tdir
23586         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23587
23588         local mdtidx=$($LFS getstripe -m $dom)
23589         local mdtname=MDT$(printf %04x $mdtidx)
23590         local facet=mds$((mdtidx + 1))
23591
23592         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23593                 error "failed to write data into $dom"
23594         local old_md5=$(md5sum $dom)
23595         cancel_lru_locks mdc
23596         local mdtfree1=$(do_facet $facet \
23597                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23598
23599         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23600                 error "failed to migrate to the new composite layout"
23601         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23602                 error "MDT stripe was not removed"
23603
23604         cancel_lru_locks mdc
23605         local new_md5=$(md5sum $dom)
23606         [ "$old_md5" == "$new_md5" ] ||
23607                 error "$old_md5 != $new_md5"
23608
23609         # Skip free space checks with ZFS
23610         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23611                 local mdtfree2=$(do_facet $facet \
23612                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23613                 [ $mdtfree2 -gt $mdtfree1 ] ||
23614                         error "MDS space is not freed after migration"
23615         fi
23616         return 0
23617 }
23618 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23619
23620 test_272d() {
23621         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23622                 skip "Need MDS version at least 2.12.55"
23623
23624         local dom=$DIR/$tdir/$tfile
23625         mkdir -p $DIR/$tdir
23626         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23627
23628         local mdtidx=$($LFS getstripe -m $dom)
23629         local mdtname=MDT$(printf %04x $mdtidx)
23630         local facet=mds$((mdtidx + 1))
23631
23632         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23633                 error "failed to write data into $dom"
23634         local old_md5=$(md5sum $dom)
23635         cancel_lru_locks mdc
23636         local mdtfree1=$(do_facet $facet \
23637                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23638
23639         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23640                 error "failed mirroring to the new composite layout"
23641         $LFS mirror resync $dom ||
23642                 error "failed mirror resync"
23643         $LFS mirror split --mirror-id 1 -d $dom ||
23644                 error "failed mirror split"
23645
23646         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23647                 error "MDT stripe was not removed"
23648
23649         cancel_lru_locks mdc
23650         local new_md5=$(md5sum $dom)
23651         [ "$old_md5" == "$new_md5" ] ||
23652                 error "$old_md5 != $new_md5"
23653
23654         # Skip free space checks with ZFS
23655         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23656                 local mdtfree2=$(do_facet $facet \
23657                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23658                 [ $mdtfree2 -gt $mdtfree1 ] ||
23659                         error "MDS space is not freed after DOM mirror deletion"
23660         fi
23661         return 0
23662 }
23663 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23664
23665 test_272e() {
23666         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23667                 skip "Need MDS version at least 2.12.55"
23668
23669         local dom=$DIR/$tdir/$tfile
23670         mkdir -p $DIR/$tdir
23671         $LFS setstripe -c 2 $dom
23672
23673         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23674                 error "failed to write data into $dom"
23675         local old_md5=$(md5sum $dom)
23676         cancel_lru_locks
23677
23678         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23679                 error "failed mirroring to the DOM layout"
23680         $LFS mirror resync $dom ||
23681                 error "failed mirror resync"
23682         $LFS mirror split --mirror-id 1 -d $dom ||
23683                 error "failed mirror split"
23684
23685         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23686                 error "MDT stripe wasn't set"
23687
23688         cancel_lru_locks
23689         local new_md5=$(md5sum $dom)
23690         [ "$old_md5" == "$new_md5" ] ||
23691                 error "$old_md5 != $new_md5"
23692
23693         return 0
23694 }
23695 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
23696
23697 test_272f() {
23698         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23699                 skip "Need MDS version at least 2.12.55"
23700
23701         local dom=$DIR/$tdir/$tfile
23702         mkdir -p $DIR/$tdir
23703         $LFS setstripe -c 2 $dom
23704
23705         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23706                 error "failed to write data into $dom"
23707         local old_md5=$(md5sum $dom)
23708         cancel_lru_locks
23709
23710         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
23711                 error "failed migrating to the DOM file"
23712
23713         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23714                 error "MDT stripe wasn't set"
23715
23716         cancel_lru_locks
23717         local new_md5=$(md5sum $dom)
23718         [ "$old_md5" != "$new_md5" ] &&
23719                 error "$old_md5 != $new_md5"
23720
23721         return 0
23722 }
23723 run_test 272f "DoM migration: OST-striped file to DOM file"
23724
23725 test_273a() {
23726         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23727                 skip "Need MDS version at least 2.11.50"
23728
23729         # Layout swap cannot be done if either file has DOM component,
23730         # this will never be supported, migration should be used instead
23731
23732         local dom=$DIR/$tdir/$tfile
23733         mkdir -p $DIR/$tdir
23734
23735         $LFS setstripe -c2 ${dom}_plain
23736         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
23737         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
23738                 error "can swap layout with DoM component"
23739         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
23740                 error "can swap layout with DoM component"
23741
23742         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
23743         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
23744                 error "can swap layout with DoM component"
23745         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
23746                 error "can swap layout with DoM component"
23747         return 0
23748 }
23749 run_test 273a "DoM: layout swapping should fail with DOM"
23750
23751 test_273b() {
23752         mkdir -p $DIR/$tdir
23753         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
23754
23755 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
23756         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
23757
23758         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
23759 }
23760 run_test 273b "DoM: race writeback and object destroy"
23761
23762 test_275() {
23763         remote_ost_nodsh && skip "remote OST with nodsh"
23764         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
23765                 skip "Need OST version >= 2.10.57"
23766
23767         local file=$DIR/$tfile
23768         local oss
23769
23770         oss=$(comma_list $(osts_nodes))
23771
23772         dd if=/dev/urandom of=$file bs=1M count=2 ||
23773                 error "failed to create a file"
23774         cancel_lru_locks osc
23775
23776         #lock 1
23777         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23778                 error "failed to read a file"
23779
23780 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
23781         $LCTL set_param fail_loc=0x8000031f
23782
23783         cancel_lru_locks osc &
23784         sleep 1
23785
23786 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
23787         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
23788         #IO takes another lock, but matches the PENDING one
23789         #and places it to the IO RPC
23790         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
23791                 error "failed to read a file with PENDING lock"
23792 }
23793 run_test 275 "Read on a canceled duplicate lock"
23794
23795 test_276() {
23796         remote_ost_nodsh && skip "remote OST with nodsh"
23797         local pid
23798
23799         do_facet ost1 "(while true; do \
23800                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
23801                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
23802         pid=$!
23803
23804         for LOOP in $(seq 20); do
23805                 stop ost1
23806                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
23807         done
23808         kill -9 $pid
23809         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
23810                 rm $TMP/sanity_276_pid"
23811 }
23812 run_test 276 "Race between mount and obd_statfs"
23813
23814 test_277() {
23815         $LCTL set_param ldlm.namespaces.*.lru_size=0
23816         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23817         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23818                         grep ^used_mb | awk '{print $2}')
23819         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
23820         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
23821                 oflag=direct conv=notrunc
23822         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
23823                         grep ^used_mb | awk '{print $2}')
23824         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
23825 }
23826 run_test 277 "Direct IO shall drop page cache"
23827
23828 test_278() {
23829         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23830         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23831         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
23832                 skip "needs the same host for mdt1 mdt2" && return
23833
23834         local pid1
23835         local pid2
23836
23837 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
23838         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
23839         stop mds2 &
23840         pid2=$!
23841
23842         stop mds1
23843
23844         echo "Starting MDTs"
23845         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
23846         wait $pid2
23847 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
23848 #will return NULL
23849         do_facet mds2 $LCTL set_param fail_loc=0
23850
23851         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
23852         wait_recovery_complete mds2
23853 }
23854 run_test 278 "Race starting MDS between MDTs stop/start"
23855
23856 test_280() {
23857         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
23858                 skip "Need MGS version at least 2.13.52"
23859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23860         combined_mgs_mds || skip "needs combined MGS/MDT"
23861
23862         umount_client $MOUNT
23863 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
23864         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
23865
23866         mount_client $MOUNT &
23867         sleep 1
23868         stop mgs || error "stop mgs failed"
23869         #for a race mgs would crash
23870         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
23871         # make sure we unmount client before remounting
23872         wait
23873         umount_client $MOUNT
23874         mount_client $MOUNT || error "mount client failed"
23875 }
23876 run_test 280 "Race between MGS umount and client llog processing"
23877
23878 cleanup_test_300() {
23879         trap 0
23880         umask $SAVE_UMASK
23881 }
23882 test_striped_dir() {
23883         local mdt_index=$1
23884         local stripe_count
23885         local stripe_index
23886
23887         mkdir -p $DIR/$tdir
23888
23889         SAVE_UMASK=$(umask)
23890         trap cleanup_test_300 RETURN EXIT
23891
23892         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
23893                                                 $DIR/$tdir/striped_dir ||
23894                 error "set striped dir error"
23895
23896         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
23897         [ "$mode" = "755" ] || error "expect 755 got $mode"
23898
23899         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
23900                 error "getdirstripe failed"
23901         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
23902         if [ "$stripe_count" != "2" ]; then
23903                 error "1:stripe_count is $stripe_count, expect 2"
23904         fi
23905         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
23906         if [ "$stripe_count" != "2" ]; then
23907                 error "2:stripe_count is $stripe_count, expect 2"
23908         fi
23909
23910         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
23911         if [ "$stripe_index" != "$mdt_index" ]; then
23912                 error "stripe_index is $stripe_index, expect $mdt_index"
23913         fi
23914
23915         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23916                 error "nlink error after create striped dir"
23917
23918         mkdir $DIR/$tdir/striped_dir/a
23919         mkdir $DIR/$tdir/striped_dir/b
23920
23921         stat $DIR/$tdir/striped_dir/a ||
23922                 error "create dir under striped dir failed"
23923         stat $DIR/$tdir/striped_dir/b ||
23924                 error "create dir under striped dir failed"
23925
23926         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
23927                 error "nlink error after mkdir"
23928
23929         rmdir $DIR/$tdir/striped_dir/a
23930         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
23931                 error "nlink error after rmdir"
23932
23933         rmdir $DIR/$tdir/striped_dir/b
23934         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23935                 error "nlink error after rmdir"
23936
23937         chattr +i $DIR/$tdir/striped_dir
23938         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23939                 error "immutable flags not working under striped dir!"
23940         chattr -i $DIR/$tdir/striped_dir
23941
23942         rmdir $DIR/$tdir/striped_dir ||
23943                 error "rmdir striped dir error"
23944
23945         cleanup_test_300
23946
23947         true
23948 }
23949
23950 test_300a() {
23951         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23952                 skip "skipped for lustre < 2.7.0"
23953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23955
23956         test_striped_dir 0 || error "failed on striped dir on MDT0"
23957         test_striped_dir 1 || error "failed on striped dir on MDT0"
23958 }
23959 run_test 300a "basic striped dir sanity test"
23960
23961 test_300b() {
23962         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23963                 skip "skipped for lustre < 2.7.0"
23964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23965         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23966
23967         local i
23968         local mtime1
23969         local mtime2
23970         local mtime3
23971
23972         test_mkdir $DIR/$tdir || error "mkdir fail"
23973         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23974                 error "set striped dir error"
23975         for i in {0..9}; do
23976                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23977                 sleep 1
23978                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23979                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23980                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23981                 sleep 1
23982                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23983                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23984                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23985         done
23986         true
23987 }
23988 run_test 300b "check ctime/mtime for striped dir"
23989
23990 test_300c() {
23991         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23992                 skip "skipped for lustre < 2.7.0"
23993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23994         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23995
23996         local file_count
23997
23998         mkdir_on_mdt0 $DIR/$tdir
23999         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24000                 error "set striped dir error"
24001
24002         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24003                 error "chown striped dir failed"
24004
24005         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24006                 error "create 5k files failed"
24007
24008         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24009
24010         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24011
24012         rm -rf $DIR/$tdir
24013 }
24014 run_test 300c "chown && check ls under striped directory"
24015
24016 test_300d() {
24017         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24018                 skip "skipped for lustre < 2.7.0"
24019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24021
24022         local stripe_count
24023         local file
24024
24025         mkdir -p $DIR/$tdir
24026         $LFS setstripe -c 2 $DIR/$tdir
24027
24028         #local striped directory
24029         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24030                 error "set striped dir error"
24031         #look at the directories for debug purposes
24032         ls -l $DIR/$tdir
24033         $LFS getdirstripe $DIR/$tdir
24034         ls -l $DIR/$tdir/striped_dir
24035         $LFS getdirstripe $DIR/$tdir/striped_dir
24036         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24037                 error "create 10 files failed"
24038
24039         #remote striped directory
24040         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24041                 error "set striped dir error"
24042         #look at the directories for debug purposes
24043         ls -l $DIR/$tdir
24044         $LFS getdirstripe $DIR/$tdir
24045         ls -l $DIR/$tdir/remote_striped_dir
24046         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24047         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24048                 error "create 10 files failed"
24049
24050         for file in $(find $DIR/$tdir); do
24051                 stripe_count=$($LFS getstripe -c $file)
24052                 [ $stripe_count -eq 2 ] ||
24053                         error "wrong stripe $stripe_count for $file"
24054         done
24055
24056         rm -rf $DIR/$tdir
24057 }
24058 run_test 300d "check default stripe under striped directory"
24059
24060 test_300e() {
24061         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24062                 skip "Need MDS version at least 2.7.55"
24063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24064         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24065
24066         local stripe_count
24067         local file
24068
24069         mkdir -p $DIR/$tdir
24070
24071         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24072                 error "set striped dir error"
24073
24074         touch $DIR/$tdir/striped_dir/a
24075         touch $DIR/$tdir/striped_dir/b
24076         touch $DIR/$tdir/striped_dir/c
24077
24078         mkdir $DIR/$tdir/striped_dir/dir_a
24079         mkdir $DIR/$tdir/striped_dir/dir_b
24080         mkdir $DIR/$tdir/striped_dir/dir_c
24081
24082         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24083                 error "set striped adir under striped dir error"
24084
24085         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24086                 error "set striped bdir under striped dir error"
24087
24088         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24089                 error "set striped cdir under striped dir error"
24090
24091         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24092                 error "rename dir under striped dir fails"
24093
24094         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24095                 error "rename dir under different stripes fails"
24096
24097         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24098                 error "rename file under striped dir should succeed"
24099
24100         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24101                 error "rename dir under striped dir should succeed"
24102
24103         rm -rf $DIR/$tdir
24104 }
24105 run_test 300e "check rename under striped directory"
24106
24107 test_300f() {
24108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24110         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24111                 skip "Need MDS version at least 2.7.55"
24112
24113         local stripe_count
24114         local file
24115
24116         rm -rf $DIR/$tdir
24117         mkdir -p $DIR/$tdir
24118
24119         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24120                 error "set striped dir error"
24121
24122         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24123                 error "set striped dir error"
24124
24125         touch $DIR/$tdir/striped_dir/a
24126         mkdir $DIR/$tdir/striped_dir/dir_a
24127         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24128                 error "create striped dir under striped dir fails"
24129
24130         touch $DIR/$tdir/striped_dir1/b
24131         mkdir $DIR/$tdir/striped_dir1/dir_b
24132         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24133                 error "create striped dir under striped dir fails"
24134
24135         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24136                 error "rename dir under different striped dir should fail"
24137
24138         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24139                 error "rename striped dir under diff striped dir should fail"
24140
24141         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24142                 error "rename file under diff striped dirs fails"
24143
24144         rm -rf $DIR/$tdir
24145 }
24146 run_test 300f "check rename cross striped directory"
24147
24148 test_300_check_default_striped_dir()
24149 {
24150         local dirname=$1
24151         local default_count=$2
24152         local default_index=$3
24153         local stripe_count
24154         local stripe_index
24155         local dir_stripe_index
24156         local dir
24157
24158         echo "checking $dirname $default_count $default_index"
24159         $LFS setdirstripe -D -c $default_count -i $default_index \
24160                                 -H all_char $DIR/$tdir/$dirname ||
24161                 error "set default stripe on striped dir error"
24162         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24163         [ $stripe_count -eq $default_count ] ||
24164                 error "expect $default_count get $stripe_count for $dirname"
24165
24166         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24167         [ $stripe_index -eq $default_index ] ||
24168                 error "expect $default_index get $stripe_index for $dirname"
24169
24170         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24171                                                 error "create dirs failed"
24172
24173         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24174         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24175         for dir in $(find $DIR/$tdir/$dirname/*); do
24176                 stripe_count=$($LFS getdirstripe -c $dir)
24177                 (( $stripe_count == $default_count )) ||
24178                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24179                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24180                 error "stripe count $default_count != $stripe_count for $dir"
24181
24182                 stripe_index=$($LFS getdirstripe -i $dir)
24183                 [ $default_index -eq -1 ] ||
24184                         [ $stripe_index -eq $default_index ] ||
24185                         error "$stripe_index != $default_index for $dir"
24186
24187                 #check default stripe
24188                 stripe_count=$($LFS getdirstripe -D -c $dir)
24189                 [ $stripe_count -eq $default_count ] ||
24190                 error "default count $default_count != $stripe_count for $dir"
24191
24192                 stripe_index=$($LFS getdirstripe -D -i $dir)
24193                 [ $stripe_index -eq $default_index ] ||
24194                 error "default index $default_index != $stripe_index for $dir"
24195         done
24196         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24197 }
24198
24199 test_300g() {
24200         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24201         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24202                 skip "Need MDS version at least 2.7.55"
24203
24204         local dir
24205         local stripe_count
24206         local stripe_index
24207
24208         mkdir_on_mdt0 $DIR/$tdir
24209         mkdir $DIR/$tdir/normal_dir
24210
24211         #Checking when client cache stripe index
24212         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24213         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24214                 error "create striped_dir failed"
24215
24216         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24217                 error "create dir0 fails"
24218         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24219         [ $stripe_index -eq 0 ] ||
24220                 error "dir0 expect index 0 got $stripe_index"
24221
24222         mkdir $DIR/$tdir/striped_dir/dir1 ||
24223                 error "create dir1 fails"
24224         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24225         [ $stripe_index -eq 1 ] ||
24226                 error "dir1 expect index 1 got $stripe_index"
24227
24228         #check default stripe count/stripe index
24229         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24230         test_300_check_default_striped_dir normal_dir 1 0
24231         test_300_check_default_striped_dir normal_dir -1 1
24232         test_300_check_default_striped_dir normal_dir 2 -1
24233
24234         #delete default stripe information
24235         echo "delete default stripeEA"
24236         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24237                 error "set default stripe on striped dir error"
24238
24239         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24240         for dir in $(find $DIR/$tdir/normal_dir/*); do
24241                 stripe_count=$($LFS getdirstripe -c $dir)
24242                 [ $stripe_count -eq 0 ] ||
24243                         error "expect 1 get $stripe_count for $dir"
24244         done
24245 }
24246 run_test 300g "check default striped directory for normal directory"
24247
24248 test_300h() {
24249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24250         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24251                 skip "Need MDS version at least 2.7.55"
24252
24253         local dir
24254         local stripe_count
24255
24256         mkdir $DIR/$tdir
24257         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24258                 error "set striped dir error"
24259
24260         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24261         test_300_check_default_striped_dir striped_dir 1 0
24262         test_300_check_default_striped_dir striped_dir -1 1
24263         test_300_check_default_striped_dir striped_dir 2 -1
24264
24265         #delete default stripe information
24266         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24267                 error "set default stripe on striped dir error"
24268
24269         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24270         for dir in $(find $DIR/$tdir/striped_dir/*); do
24271                 stripe_count=$($LFS getdirstripe -c $dir)
24272                 [ $stripe_count -eq 0 ] ||
24273                         error "expect 1 get $stripe_count for $dir"
24274         done
24275 }
24276 run_test 300h "check default striped directory for striped directory"
24277
24278 test_300i() {
24279         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24280         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24281         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24282                 skip "Need MDS version at least 2.7.55"
24283
24284         local stripe_count
24285         local file
24286
24287         mkdir $DIR/$tdir
24288
24289         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24290                 error "set striped dir error"
24291
24292         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24293                 error "create files under striped dir failed"
24294
24295         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24296                 error "set striped hashdir error"
24297
24298         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24299                 error "create dir0 under hash dir failed"
24300         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24301                 error "create dir1 under hash dir failed"
24302         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24303                 error "create dir2 under hash dir failed"
24304
24305         # unfortunately, we need to umount to clear dir layout cache for now
24306         # once we fully implement dir layout, we can drop this
24307         umount_client $MOUNT || error "umount failed"
24308         mount_client $MOUNT || error "mount failed"
24309
24310         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24311         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24312         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24313
24314         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24315                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24316                         error "create crush2 dir $tdir/hashdir/d3 failed"
24317                 $LFS find -H crush2 $DIR/$tdir/hashdir
24318                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24319                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24320
24321                 # mkdir with an invalid hash type (hash=fail_val) from client
24322                 # should be replaced on MDS with a valid (default) hash type
24323                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24324                 $LCTL set_param fail_loc=0x1901 fail_val=99
24325                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24326
24327                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24328                 local expect=$(do_facet mds1 \
24329                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24330                 [[ $hash == $expect ]] ||
24331                         error "d99 hash '$hash' != expected hash '$expect'"
24332         fi
24333
24334         #set the stripe to be unknown hash type on read
24335         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24336         $LCTL set_param fail_loc=0x1901 fail_val=99
24337         for ((i = 0; i < 10; i++)); do
24338                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24339                         error "stat f-$i failed"
24340                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24341         done
24342
24343         touch $DIR/$tdir/striped_dir/f0 &&
24344                 error "create under striped dir with unknown hash should fail"
24345
24346         $LCTL set_param fail_loc=0
24347
24348         umount_client $MOUNT || error "umount failed"
24349         mount_client $MOUNT || error "mount failed"
24350
24351         return 0
24352 }
24353 run_test 300i "client handle unknown hash type striped directory"
24354
24355 test_300j() {
24356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24358         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24359                 skip "Need MDS version at least 2.7.55"
24360
24361         local stripe_count
24362         local file
24363
24364         mkdir $DIR/$tdir
24365
24366         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24367         $LCTL set_param fail_loc=0x1702
24368         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24369                 error "set striped dir error"
24370
24371         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24372                 error "create files under striped dir failed"
24373
24374         $LCTL set_param fail_loc=0
24375
24376         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24377
24378         return 0
24379 }
24380 run_test 300j "test large update record"
24381
24382 test_300k() {
24383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24385         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24386                 skip "Need MDS version at least 2.7.55"
24387
24388         # this test needs a huge transaction
24389         local kb
24390         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24391              osd*.$FSNAME-MDT0000.kbytestotal")
24392         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24393
24394         local stripe_count
24395         local file
24396
24397         mkdir $DIR/$tdir
24398
24399         #define OBD_FAIL_LARGE_STRIPE   0x1703
24400         $LCTL set_param fail_loc=0x1703
24401         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24402                 error "set striped dir error"
24403         $LCTL set_param fail_loc=0
24404
24405         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24406                 error "getstripeddir fails"
24407         rm -rf $DIR/$tdir/striped_dir ||
24408                 error "unlink striped dir fails"
24409
24410         return 0
24411 }
24412 run_test 300k "test large striped directory"
24413
24414 test_300l() {
24415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24417         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24418                 skip "Need MDS version at least 2.7.55"
24419
24420         local stripe_index
24421
24422         test_mkdir -p $DIR/$tdir/striped_dir
24423         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24424                         error "chown $RUNAS_ID failed"
24425         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24426                 error "set default striped dir failed"
24427
24428         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24429         $LCTL set_param fail_loc=0x80000158
24430         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24431
24432         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24433         [ $stripe_index -eq 1 ] ||
24434                 error "expect 1 get $stripe_index for $dir"
24435 }
24436 run_test 300l "non-root user to create dir under striped dir with stale layout"
24437
24438 test_300m() {
24439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24440         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24442                 skip "Need MDS version at least 2.7.55"
24443
24444         mkdir -p $DIR/$tdir/striped_dir
24445         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24446                 error "set default stripes dir error"
24447
24448         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24449
24450         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24451         [ $stripe_count -eq 0 ] ||
24452                         error "expect 0 get $stripe_count for a"
24453
24454         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24455                 error "set default stripes dir error"
24456
24457         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24458
24459         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24460         [ $stripe_count -eq 0 ] ||
24461                         error "expect 0 get $stripe_count for b"
24462
24463         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24464                 error "set default stripes dir error"
24465
24466         mkdir $DIR/$tdir/striped_dir/c &&
24467                 error "default stripe_index is invalid, mkdir c should fails"
24468
24469         rm -rf $DIR/$tdir || error "rmdir fails"
24470 }
24471 run_test 300m "setstriped directory on single MDT FS"
24472
24473 cleanup_300n() {
24474         local list=$(comma_list $(mdts_nodes))
24475
24476         trap 0
24477         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24478 }
24479
24480 test_300n() {
24481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24483         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24484                 skip "Need MDS version at least 2.7.55"
24485         remote_mds_nodsh && skip "remote MDS with nodsh"
24486
24487         local stripe_index
24488         local list=$(comma_list $(mdts_nodes))
24489
24490         trap cleanup_300n RETURN EXIT
24491         mkdir -p $DIR/$tdir
24492         chmod 777 $DIR/$tdir
24493         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24494                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24495                 error "create striped dir succeeds with gid=0"
24496
24497         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24498         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24499                 error "create striped dir fails with gid=-1"
24500
24501         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24502         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24503                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24504                 error "set default striped dir succeeds with gid=0"
24505
24506
24507         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24508         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24509                 error "set default striped dir fails with gid=-1"
24510
24511
24512         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24513         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24514                                         error "create test_dir fails"
24515         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24516                                         error "create test_dir1 fails"
24517         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24518                                         error "create test_dir2 fails"
24519         cleanup_300n
24520 }
24521 run_test 300n "non-root user to create dir under striped dir with default EA"
24522
24523 test_300o() {
24524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24526         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24527                 skip "Need MDS version at least 2.7.55"
24528
24529         local numfree1
24530         local numfree2
24531
24532         mkdir -p $DIR/$tdir
24533
24534         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24535         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24536         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24537                 skip "not enough free inodes $numfree1 $numfree2"
24538         fi
24539
24540         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24541         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24542         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24543                 skip "not enough free space $numfree1 $numfree2"
24544         fi
24545
24546         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24547                 error "setdirstripe fails"
24548
24549         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24550                 error "create dirs fails"
24551
24552         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24553         ls $DIR/$tdir/striped_dir > /dev/null ||
24554                 error "ls striped dir fails"
24555         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24556                 error "unlink big striped dir fails"
24557 }
24558 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24559
24560 test_300p() {
24561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24563         remote_mds_nodsh && skip "remote MDS with nodsh"
24564
24565         mkdir_on_mdt0 $DIR/$tdir
24566
24567         #define OBD_FAIL_OUT_ENOSPC     0x1704
24568         do_facet mds2 lctl set_param fail_loc=0x80001704
24569         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24570                  && error "create striped directory should fail"
24571
24572         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24573
24574         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24575         true
24576 }
24577 run_test 300p "create striped directory without space"
24578
24579 test_300q() {
24580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24582
24583         local fd=$(free_fd)
24584         local cmd="exec $fd<$tdir"
24585         cd $DIR
24586         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24587         eval $cmd
24588         cmd="exec $fd<&-"
24589         trap "eval $cmd" EXIT
24590         cd $tdir || error "cd $tdir fails"
24591         rmdir  ../$tdir || error "rmdir $tdir fails"
24592         mkdir local_dir && error "create dir succeeds"
24593         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24594         eval $cmd
24595         return 0
24596 }
24597 run_test 300q "create remote directory under orphan directory"
24598
24599 test_300r() {
24600         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24601                 skip "Need MDS version at least 2.7.55" && return
24602         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24603
24604         mkdir $DIR/$tdir
24605
24606         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24607                 error "set striped dir error"
24608
24609         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24610                 error "getstripeddir fails"
24611
24612         local stripe_count
24613         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24614                       awk '/lmv_stripe_count:/ { print $2 }')
24615
24616         [ $MDSCOUNT -ne $stripe_count ] &&
24617                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24618
24619         rm -rf $DIR/$tdir/striped_dir ||
24620                 error "unlink striped dir fails"
24621 }
24622 run_test 300r "test -1 striped directory"
24623
24624 test_300s_helper() {
24625         local count=$1
24626
24627         local stripe_dir=$DIR/$tdir/striped_dir.$count
24628
24629         $LFS mkdir -c $count $stripe_dir ||
24630                 error "lfs mkdir -c error"
24631
24632         $LFS getdirstripe $stripe_dir ||
24633                 error "lfs getdirstripe fails"
24634
24635         local stripe_count
24636         stripe_count=$($LFS getdirstripe $stripe_dir |
24637                       awk '/lmv_stripe_count:/ { print $2 }')
24638
24639         [ $count -ne $stripe_count ] &&
24640                 error_noexit "bad stripe count $stripe_count expected $count"
24641
24642         local dupe_stripes
24643         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24644                 awk '/0x/ {count[$1] += 1}; END {
24645                         for (idx in count) {
24646                                 if (count[idx]>1) {
24647                                         print "index " idx " count " count[idx]
24648                                 }
24649                         }
24650                 }')
24651
24652         if [[ -n "$dupe_stripes" ]] ; then
24653                 lfs getdirstripe $stripe_dir
24654                 error_noexit "Dupe MDT above: $dupe_stripes "
24655         fi
24656
24657         rm -rf $stripe_dir ||
24658                 error_noexit "unlink $stripe_dir fails"
24659 }
24660
24661 test_300s() {
24662         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24663                 skip "Need MDS version at least 2.7.55" && return
24664         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24665
24666         mkdir $DIR/$tdir
24667         for count in $(seq 2 $MDSCOUNT); do
24668                 test_300s_helper $count
24669         done
24670 }
24671 run_test 300s "test lfs mkdir -c without -i"
24672
24673 test_300t() {
24674         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24675                 skip "need MDS 2.14.55 or later"
24676         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
24677
24678         local testdir="$DIR/$tdir/striped_dir"
24679         local dir1=$testdir/dir1
24680         local dir2=$testdir/dir2
24681
24682         mkdir -p $testdir
24683
24684         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
24685                 error "failed to set default stripe count for $testdir"
24686
24687         mkdir $dir1
24688         local stripe_count=$($LFS getdirstripe -c $dir1)
24689
24690         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
24691
24692         local max_count=$((MDSCOUNT - 1))
24693         local mdts=$(comma_list $(mdts_nodes))
24694
24695         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
24696         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
24697
24698         mkdir $dir2
24699         stripe_count=$($LFS getdirstripe -c $dir2)
24700
24701         (( $stripe_count == $max_count )) || error "wrong stripe count"
24702 }
24703 run_test 300t "test max_mdt_stripecount"
24704
24705 prepare_remote_file() {
24706         mkdir $DIR/$tdir/src_dir ||
24707                 error "create remote source failed"
24708
24709         cp /etc/hosts $DIR/$tdir/src_dir/a ||
24710                  error "cp to remote source failed"
24711         touch $DIR/$tdir/src_dir/a
24712
24713         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
24714                 error "create remote target dir failed"
24715
24716         touch $DIR/$tdir/tgt_dir/b
24717
24718         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
24719                 error "rename dir cross MDT failed!"
24720
24721         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
24722                 error "src_child still exists after rename"
24723
24724         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
24725                 error "missing file(a) after rename"
24726
24727         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
24728                 error "diff after rename"
24729 }
24730
24731 test_310a() {
24732         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24734
24735         local remote_file=$DIR/$tdir/tgt_dir/b
24736
24737         mkdir -p $DIR/$tdir
24738
24739         prepare_remote_file || error "prepare remote file failed"
24740
24741         #open-unlink file
24742         $OPENUNLINK $remote_file $remote_file ||
24743                 error "openunlink $remote_file failed"
24744         $CHECKSTAT -a $remote_file || error "$remote_file exists"
24745 }
24746 run_test 310a "open unlink remote file"
24747
24748 test_310b() {
24749         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
24750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24751
24752         local remote_file=$DIR/$tdir/tgt_dir/b
24753
24754         mkdir -p $DIR/$tdir
24755
24756         prepare_remote_file || error "prepare remote file failed"
24757
24758         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24759         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
24760         $CHECKSTAT -t file $remote_file || error "check file failed"
24761 }
24762 run_test 310b "unlink remote file with multiple links while open"
24763
24764 test_310c() {
24765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24766         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
24767
24768         local remote_file=$DIR/$tdir/tgt_dir/b
24769
24770         mkdir -p $DIR/$tdir
24771
24772         prepare_remote_file || error "prepare remote file failed"
24773
24774         ln $remote_file $DIR/$tfile || error "link failed for remote file"
24775         multiop_bg_pause $remote_file O_uc ||
24776                         error "mulitop failed for remote file"
24777         MULTIPID=$!
24778         $MULTIOP $DIR/$tfile Ouc
24779         kill -USR1 $MULTIPID
24780         wait $MULTIPID
24781 }
24782 run_test 310c "open-unlink remote file with multiple links"
24783
24784 #LU-4825
24785 test_311() {
24786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24787         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24788         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
24789                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
24790         remote_mds_nodsh && skip "remote MDS with nodsh"
24791
24792         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24793         local mdts=$(comma_list $(mdts_nodes))
24794
24795         mkdir -p $DIR/$tdir
24796         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24797         createmany -o $DIR/$tdir/$tfile. 1000
24798
24799         # statfs data is not real time, let's just calculate it
24800         old_iused=$((old_iused + 1000))
24801
24802         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24803                         osp.*OST0000*MDT0000.create_count")
24804         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24805                                 osp.*OST0000*MDT0000.max_create_count")
24806         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
24807
24808         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
24809         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
24810         [ $index -ne 0 ] || error "$tfile stripe index is 0"
24811
24812         unlinkmany $DIR/$tdir/$tfile. 1000
24813
24814         do_nodes $mdts "$LCTL set_param -n \
24815                         osp.*OST0000*.max_create_count=$max_count"
24816         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
24817                 do_nodes $mdts "$LCTL set_param -n \
24818                                 osp.*OST0000*.create_count=$count"
24819         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
24820                         grep "=0" && error "create_count is zero"
24821
24822         local new_iused
24823         for i in $(seq 120); do
24824                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
24825                 # system may be too busy to destroy all objs in time, use
24826                 # a somewhat small value to not fail autotest
24827                 [ $((old_iused - new_iused)) -gt 400 ] && break
24828                 sleep 1
24829         done
24830
24831         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
24832         [ $((old_iused - new_iused)) -gt 400 ] ||
24833                 error "objs not destroyed after unlink"
24834 }
24835 run_test 311 "disable OSP precreate, and unlink should destroy objs"
24836
24837 zfs_get_objid()
24838 {
24839         local ost=$1
24840         local tf=$2
24841         local fid=($($LFS getstripe $tf | grep 0x))
24842         local seq=${fid[3]#0x}
24843         local objid=${fid[1]}
24844
24845         local vdevdir=$(dirname $(facet_vdevice $ost))
24846         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
24847         local zfs_zapid=$(do_facet $ost $cmd |
24848                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
24849                           awk '/Object/{getline; print $1}')
24850         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
24851                           awk "/$objid = /"'{printf $3}')
24852
24853         echo $zfs_objid
24854 }
24855
24856 zfs_object_blksz() {
24857         local ost=$1
24858         local objid=$2
24859
24860         local vdevdir=$(dirname $(facet_vdevice $ost))
24861         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
24862         local blksz=$(do_facet $ost $cmd $objid |
24863                       awk '/dblk/{getline; printf $4}')
24864
24865         case "${blksz: -1}" in
24866                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
24867                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
24868                 *) ;;
24869         esac
24870
24871         echo $blksz
24872 }
24873
24874 test_312() { # LU-4856
24875         remote_ost_nodsh && skip "remote OST with nodsh"
24876         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
24877
24878         local max_blksz=$(do_facet ost1 \
24879                           $ZFS get -p recordsize $(facet_device ost1) |
24880                           awk '!/VALUE/{print $3}')
24881         local tf=$DIR/$tfile
24882
24883         $LFS setstripe -c1 $tf
24884         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
24885
24886         # Get ZFS object id
24887         local zfs_objid=$(zfs_get_objid $facet $tf)
24888         # block size change by sequential overwrite
24889         local bs
24890
24891         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
24892                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
24893
24894                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
24895                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
24896         done
24897         rm -f $tf
24898
24899         $LFS setstripe -c1 $tf
24900         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24901
24902         # block size change by sequential append write
24903         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
24904         zfs_objid=$(zfs_get_objid $facet $tf)
24905         local count
24906
24907         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
24908                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
24909                         oflag=sync conv=notrunc
24910
24911                 blksz=$(zfs_object_blksz $facet $zfs_objid)
24912                 (( $blksz == 2 * count * PAGE_SIZE )) ||
24913                         error "blksz error, actual $blksz, " \
24914                                 "expected: 2 * $count * $PAGE_SIZE"
24915         done
24916         rm -f $tf
24917
24918         # random write
24919         $LFS setstripe -c1 $tf
24920         facet="ost$(($($LFS getstripe -i $tf) + 1))"
24921         zfs_objid=$(zfs_get_objid $facet $tf)
24922
24923         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
24924         blksz=$(zfs_object_blksz $facet $zfs_objid)
24925         (( blksz == PAGE_SIZE )) ||
24926                 error "blksz error: $blksz, expected: $PAGE_SIZE"
24927
24928         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
24929         blksz=$(zfs_object_blksz $facet $zfs_objid)
24930         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
24931
24932         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
24933         blksz=$(zfs_object_blksz $facet $zfs_objid)
24934         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
24935 }
24936 run_test 312 "make sure ZFS adjusts its block size by write pattern"
24937
24938 test_313() {
24939         remote_ost_nodsh && skip "remote OST with nodsh"
24940
24941         local file=$DIR/$tfile
24942
24943         rm -f $file
24944         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
24945
24946         # define OBD_FAIL_TGT_RCVD_EIO           0x720
24947         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24948         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
24949                 error "write should failed"
24950         do_facet ost1 "$LCTL set_param fail_loc=0"
24951         rm -f $file
24952 }
24953 run_test 313 "io should fail after last_rcvd update fail"
24954
24955 test_314() {
24956         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
24957
24958         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
24959         do_facet ost1 "$LCTL set_param fail_loc=0x720"
24960         rm -f $DIR/$tfile
24961         wait_delete_completed
24962         do_facet ost1 "$LCTL set_param fail_loc=0"
24963 }
24964 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
24965
24966 test_315() { # LU-618
24967         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
24968
24969         local file=$DIR/$tfile
24970         rm -f $file
24971
24972         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
24973                 error "multiop file write failed"
24974         $MULTIOP $file oO_RDONLY:r4063232_c &
24975         PID=$!
24976
24977         sleep 2
24978
24979         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
24980         kill -USR1 $PID
24981
24982         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
24983         rm -f $file
24984 }
24985 run_test 315 "read should be accounted"
24986
24987 test_316() {
24988         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
24989         large_xattr_enabled || skip "ea_inode feature disabled"
24990
24991         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
24992         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
24993         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
24994         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
24995
24996         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
24997 }
24998 run_test 316 "lfs migrate of file with large_xattr enabled"
24999
25000 test_317() {
25001         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25002                 skip "Need MDS version at least 2.11.53"
25003         if [ "$ost1_FSTYPE" == "zfs" ]; then
25004                 skip "LU-10370: no implementation for ZFS"
25005         fi
25006
25007         local trunc_sz
25008         local grant_blk_size
25009
25010         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25011                         awk '/grant_block_size:/ { print $2; exit; }')
25012         #
25013         # Create File of size 5M. Truncate it to below size's and verify
25014         # blocks count.
25015         #
25016         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25017                 error "Create file $DIR/$tfile failed"
25018         stack_trap "rm -f $DIR/$tfile" EXIT
25019
25020         for trunc_sz in 2097152 4097 4000 509 0; do
25021                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25022                         error "truncate $tfile to $trunc_sz failed"
25023                 local sz=$(stat --format=%s $DIR/$tfile)
25024                 local blk=$(stat --format=%b $DIR/$tfile)
25025                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25026                                      grant_blk_size) * 8))
25027
25028                 if [[ $blk -ne $trunc_blk ]]; then
25029                         $(which stat) $DIR/$tfile
25030                         error "Expected Block $trunc_blk got $blk for $tfile"
25031                 fi
25032
25033                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25034                         error "Expected Size $trunc_sz got $sz for $tfile"
25035         done
25036
25037         #
25038         # sparse file test
25039         # Create file with a hole and write actual 65536 bytes which aligned
25040         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25041         #
25042         local bs=65536
25043         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25044                 error "Create file : $DIR/$tfile"
25045
25046         #
25047         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25048         # blocks. The block count must drop to 8.
25049         #
25050         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25051                 ((bs - grant_blk_size) + 1)))
25052         $TRUNCATE $DIR/$tfile $trunc_sz ||
25053                 error "truncate $tfile to $trunc_sz failed"
25054
25055         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25056         sz=$(stat --format=%s $DIR/$tfile)
25057         blk=$(stat --format=%b $DIR/$tfile)
25058
25059         if [[ $blk -ne $trunc_bsz ]]; then
25060                 $(which stat) $DIR/$tfile
25061                 error "Expected Block $trunc_bsz got $blk for $tfile"
25062         fi
25063
25064         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25065                 error "Expected Size $trunc_sz got $sz for $tfile"
25066 }
25067 run_test 317 "Verify blocks get correctly update after truncate"
25068
25069 test_318() {
25070         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25071         local old_max_active=$($LCTL get_param -n \
25072                             ${llite_name}.max_read_ahead_async_active \
25073                             2>/dev/null)
25074
25075         $LCTL set_param llite.*.max_read_ahead_async_active=256
25076         local max_active=$($LCTL get_param -n \
25077                            ${llite_name}.max_read_ahead_async_active \
25078                            2>/dev/null)
25079         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25080
25081         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25082                 error "set max_read_ahead_async_active should succeed"
25083
25084         $LCTL set_param llite.*.max_read_ahead_async_active=512
25085         max_active=$($LCTL get_param -n \
25086                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25087         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25088
25089         # restore @max_active
25090         [ $old_max_active -ne 0 ] && $LCTL set_param \
25091                 llite.*.max_read_ahead_async_active=$old_max_active
25092
25093         local old_threshold=$($LCTL get_param -n \
25094                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25095         local max_per_file_mb=$($LCTL get_param -n \
25096                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25097
25098         local invalid=$(($max_per_file_mb + 1))
25099         $LCTL set_param \
25100                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25101                         && error "set $invalid should fail"
25102
25103         local valid=$(($invalid - 1))
25104         $LCTL set_param \
25105                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25106                         error "set $valid should succeed"
25107         local threshold=$($LCTL get_param -n \
25108                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25109         [ $threshold -eq $valid ] || error \
25110                 "expect threshold $valid got $threshold"
25111         $LCTL set_param \
25112                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25113 }
25114 run_test 318 "Verify async readahead tunables"
25115
25116 test_319() {
25117         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25118
25119         local before=$(date +%s)
25120         local evict
25121         local mdir=$DIR/$tdir
25122         local file=$mdir/xxx
25123
25124         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25125         touch $file
25126
25127 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25128         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25129         $LFS migrate -m1 $mdir &
25130
25131         sleep 1
25132         dd if=$file of=/dev/null
25133         wait
25134         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25135           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25136
25137         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25138 }
25139 run_test 319 "lost lease lock on migrate error"
25140
25141 test_398a() { # LU-4198
25142         local ost1_imp=$(get_osc_import_name client ost1)
25143         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25144                          cut -d'.' -f2)
25145
25146         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25147         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25148
25149         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25150         # request a new lock on client
25151         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25152
25153         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25154         #local lock_count=$($LCTL get_param -n \
25155         #                  ldlm.namespaces.$imp_name.lru_size)
25156         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25157
25158         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25159
25160         # no lock cached, should use lockless DIO and not enqueue new lock
25161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25162                 conv=notrunc ||
25163                 error "dio write failed"
25164         lock_count=$($LCTL get_param -n \
25165                      ldlm.namespaces.$imp_name.lru_size)
25166         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25167
25168         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25169
25170         # no lock cached, should use locked DIO append
25171         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25172                 conv=notrunc || error "DIO append failed"
25173         lock_count=$($LCTL get_param -n \
25174                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25175         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25176 }
25177 run_test 398a "direct IO should cancel lock otherwise lockless"
25178
25179 test_398b() { # LU-4198
25180         local before=$(date +%s)
25181         local njobs=4
25182         local size=48
25183
25184         which fio || skip_env "no fio installed"
25185         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25186         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25187
25188         # Single page, multiple pages, stripe size, 4*stripe size
25189         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25190                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25191                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25192                         --numjobs=$njobs --fallocate=none \
25193                         --iodepth=16 --allow_file_create=0 \
25194                         --size=$((size/njobs))M \
25195                         --filename=$DIR/$tfile &
25196                 bg_pid=$!
25197
25198                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25199                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25200                         --numjobs=$njobs --fallocate=none \
25201                         --iodepth=16 --allow_file_create=0 \
25202                         --size=$((size/njobs))M \
25203                         --filename=$DIR/$tfile || true
25204                 wait $bg_pid
25205         done
25206
25207         evict=$(do_facet client $LCTL get_param \
25208                 osc.$FSNAME-OST*-osc-*/state |
25209             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25210
25211         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25212                 (do_facet client $LCTL get_param \
25213                         osc.$FSNAME-OST*-osc-*/state;
25214                     error "eviction happened: $evict before:$before")
25215
25216         rm -f $DIR/$tfile
25217 }
25218 run_test 398b "DIO and buffer IO race"
25219
25220 test_398c() { # LU-4198
25221         local ost1_imp=$(get_osc_import_name client ost1)
25222         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25223                          cut -d'.' -f2)
25224
25225         which fio || skip_env "no fio installed"
25226
25227         saved_debug=$($LCTL get_param -n debug)
25228         $LCTL set_param debug=0
25229
25230         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25231         ((size /= 1024)) # by megabytes
25232         ((size /= 2)) # write half of the OST at most
25233         [ $size -gt 40 ] && size=40 #reduce test time anyway
25234
25235         $LFS setstripe -c 1 $DIR/$tfile
25236
25237         # it seems like ldiskfs reserves more space than necessary if the
25238         # writing blocks are not mapped, so it extends the file firstly
25239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25240         cancel_lru_locks osc
25241
25242         # clear and verify rpc_stats later
25243         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25244
25245         local njobs=4
25246         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25247         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25248                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25249                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25250                 --filename=$DIR/$tfile
25251         [ $? -eq 0 ] || error "fio write error"
25252
25253         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25254                 error "Locks were requested while doing AIO"
25255
25256         # get the percentage of 1-page I/O
25257         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25258                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25259                 awk '{print $7}')
25260         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25261
25262         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25263         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25264                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25265                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25266                 --filename=$DIR/$tfile
25267         [ $? -eq 0 ] || error "fio mixed read write error"
25268
25269         echo "AIO with large block size ${size}M"
25270         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25271                 --numjobs=1 --fallocate=none --ioengine=libaio \
25272                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25273                 --filename=$DIR/$tfile
25274         [ $? -eq 0 ] || error "fio large block size failed"
25275
25276         rm -f $DIR/$tfile
25277         $LCTL set_param debug="$saved_debug"
25278 }
25279 run_test 398c "run fio to test AIO"
25280
25281 test_398d() { #  LU-13846
25282         which aiocp || skip_env "no aiocp installed"
25283         local aio_file=$DIR/$tfile.aio
25284
25285         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25286
25287         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25288         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25289         stack_trap "rm -f $DIR/$tfile $aio_file"
25290
25291         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25292
25293         # make sure we don't crash and fail properly
25294         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25295                 error "aio not aligned with PAGE SIZE should fail"
25296
25297         rm -f $DIR/$tfile $aio_file
25298 }
25299 run_test 398d "run aiocp to verify block size > stripe size"
25300
25301 test_398e() {
25302         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25303         touch $DIR/$tfile.new
25304         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25305 }
25306 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25307
25308 test_398f() { #  LU-14687
25309         which aiocp || skip_env "no aiocp installed"
25310         local aio_file=$DIR/$tfile.aio
25311
25312         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25313
25314         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25315         stack_trap "rm -f $DIR/$tfile $aio_file"
25316
25317         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25318         $LCTL set_param fail_loc=0x1418
25319         # make sure we don't crash and fail properly
25320         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25321                 error "aio with page allocation failure succeeded"
25322         $LCTL set_param fail_loc=0
25323         diff $DIR/$tfile $aio_file
25324         [[ $? != 0 ]] || error "no diff after failed aiocp"
25325 }
25326 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25327
25328 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25329 # stripe and i/o size must be > stripe size
25330 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25331 # single RPC in flight.  This test shows async DIO submission is working by
25332 # showing multiple RPCs in flight.
25333 test_398g() { #  LU-13798
25334         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25335
25336         # We need to do some i/o first to acquire enough grant to put our RPCs
25337         # in flight; otherwise a new connection may not have enough grant
25338         # available
25339         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25340                 error "parallel dio failed"
25341         stack_trap "rm -f $DIR/$tfile"
25342
25343         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25344         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25345         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25346         stack_trap "$LCTL set_param -n $pages_per_rpc"
25347
25348         # Recreate file so it's empty
25349         rm -f $DIR/$tfile
25350         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25351         #Pause rpc completion to guarantee we see multiple rpcs in flight
25352         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25353         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25354         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25355
25356         # Clear rpc stats
25357         $LCTL set_param osc.*.rpc_stats=c
25358
25359         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25360                 error "parallel dio failed"
25361         stack_trap "rm -f $DIR/$tfile"
25362
25363         $LCTL get_param osc.*-OST0000-*.rpc_stats
25364         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25365                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25366                 grep "8:" | awk '{print $8}')
25367         # We look at the "8 rpcs in flight" field, and verify A) it is present
25368         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25369         # as expected for an 8M DIO to a file with 1M stripes.
25370         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25371
25372         # Verify turning off parallel dio works as expected
25373         # Clear rpc stats
25374         $LCTL set_param osc.*.rpc_stats=c
25375         $LCTL set_param llite.*.parallel_dio=0
25376         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25377
25378         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25379                 error "dio with parallel dio disabled failed"
25380
25381         # Ideally, we would see only one RPC in flight here, but there is an
25382         # unavoidable race between i/o completion and RPC in flight counting,
25383         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25384         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25385         # So instead we just verify it's always < 8.
25386         $LCTL get_param osc.*-OST0000-*.rpc_stats
25387         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25388                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25389                 grep '^$' -B1 | grep . | awk '{print $1}')
25390         [ $ret != "8:" ] ||
25391                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25392 }
25393 run_test 398g "verify parallel dio async RPC submission"
25394
25395 test_398h() { #  LU-13798
25396         local dio_file=$DIR/$tfile.dio
25397
25398         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25399
25400         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25401         stack_trap "rm -f $DIR/$tfile $dio_file"
25402
25403         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25404                 error "parallel dio failed"
25405         diff $DIR/$tfile $dio_file
25406         [[ $? == 0 ]] || error "file diff after aiocp"
25407 }
25408 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25409
25410 test_398i() { #  LU-13798
25411         local dio_file=$DIR/$tfile.dio
25412
25413         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25414
25415         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25416         stack_trap "rm -f $DIR/$tfile $dio_file"
25417
25418         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25419         $LCTL set_param fail_loc=0x1418
25420         # make sure we don't crash and fail properly
25421         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25422                 error "parallel dio page allocation failure succeeded"
25423         diff $DIR/$tfile $dio_file
25424         [[ $? != 0 ]] || error "no diff after failed aiocp"
25425 }
25426 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25427
25428 test_398j() { #  LU-13798
25429         # Stripe size > RPC size but less than i/o size tests split across
25430         # stripes and RPCs for individual i/o op
25431         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25432
25433         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25434         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25435         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25436         stack_trap "$LCTL set_param -n $pages_per_rpc"
25437
25438         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25439                 error "parallel dio write failed"
25440         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25441
25442         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25443                 error "parallel dio read failed"
25444         diff $DIR/$tfile $DIR/$tfile.2
25445         [[ $? == 0 ]] || error "file diff after parallel dio read"
25446 }
25447 run_test 398j "test parallel dio where stripe size > rpc_size"
25448
25449 test_398k() { #  LU-13798
25450         wait_delete_completed
25451         wait_mds_ost_sync
25452
25453         # 4 stripe file; we will cause out of space on OST0
25454         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25455
25456         # Fill OST0 (if it's not too large)
25457         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25458                    head -n1)
25459         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25460                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25461         fi
25462         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25463         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25464                 error "dd should fill OST0"
25465         stack_trap "rm -f $DIR/$tfile.1"
25466
25467         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25468         err=$?
25469
25470         ls -la $DIR/$tfile
25471         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25472                 error "file is not 0 bytes in size"
25473
25474         # dd above should not succeed, but don't error until here so we can
25475         # get debug info above
25476         [[ $err != 0 ]] ||
25477                 error "parallel dio write with enospc succeeded"
25478         stack_trap "rm -f $DIR/$tfile"
25479 }
25480 run_test 398k "test enospc on first stripe"
25481
25482 test_398l() { #  LU-13798
25483         wait_delete_completed
25484         wait_mds_ost_sync
25485
25486         # 4 stripe file; we will cause out of space on OST0
25487         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25488         # happens on the second i/o chunk we issue
25489         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25490
25491         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25492         stack_trap "rm -f $DIR/$tfile"
25493
25494         # Fill OST0 (if it's not too large)
25495         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25496                    head -n1)
25497         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25498                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25499         fi
25500         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25501         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25502                 error "dd should fill OST0"
25503         stack_trap "rm -f $DIR/$tfile.1"
25504
25505         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25506         err=$?
25507         stack_trap "rm -f $DIR/$tfile.2"
25508
25509         # Check that short write completed as expected
25510         ls -la $DIR/$tfile.2
25511         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25512                 error "file is not 1M in size"
25513
25514         # dd above should not succeed, but don't error until here so we can
25515         # get debug info above
25516         [[ $err != 0 ]] ||
25517                 error "parallel dio write with enospc succeeded"
25518
25519         # Truncate source file to same length as output file and diff them
25520         $TRUNCATE $DIR/$tfile 1048576
25521         diff $DIR/$tfile $DIR/$tfile.2
25522         [[ $? == 0 ]] || error "data incorrect after short write"
25523 }
25524 run_test 398l "test enospc on intermediate stripe/RPC"
25525
25526 test_398m() { #  LU-13798
25527         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25528
25529         # Set up failure on OST0, the first stripe:
25530         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25531         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25532         # OST0 is on ost1, OST1 is on ost2.
25533         # So this fail_val specifies OST0
25534         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25535         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25536
25537         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25538                 error "parallel dio write with failure on first stripe succeeded"
25539         stack_trap "rm -f $DIR/$tfile"
25540         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25541
25542         # Place data in file for read
25543         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25544                 error "parallel dio write failed"
25545
25546         # Fail read on OST0, first stripe
25547         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25548         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25549         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25550                 error "parallel dio read with error on first stripe succeeded"
25551         rm -f $DIR/$tfile.2
25552         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25553
25554         # Switch to testing on OST1, second stripe
25555         # Clear file contents, maintain striping
25556         echo > $DIR/$tfile
25557         # Set up failure on OST1, second stripe:
25558         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25559         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25560
25561         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25562                 error "parallel dio write with failure on second stripe succeeded"
25563         stack_trap "rm -f $DIR/$tfile"
25564         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25565
25566         # Place data in file for read
25567         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25568                 error "parallel dio write failed"
25569
25570         # Fail read on OST1, second stripe
25571         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25572         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25573         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25574                 error "parallel dio read with error on second stripe succeeded"
25575         rm -f $DIR/$tfile.2
25576         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25577 }
25578 run_test 398m "test RPC failures with parallel dio"
25579
25580 # Parallel submission of DIO should not cause problems for append, but it's
25581 # important to verify.
25582 test_398n() { #  LU-13798
25583         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25584
25585         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25586                 error "dd to create source file failed"
25587         stack_trap "rm -f $DIR/$tfile"
25588
25589         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25590                 error "parallel dio write with failure on second stripe succeeded"
25591         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25592         diff $DIR/$tfile $DIR/$tfile.1
25593         [[ $? == 0 ]] || error "data incorrect after append"
25594
25595 }
25596 run_test 398n "test append with parallel DIO"
25597
25598 test_398o() {
25599         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25600 }
25601 run_test 398o "right kms with DIO"
25602
25603 test_fake_rw() {
25604         local read_write=$1
25605         if [ "$read_write" = "write" ]; then
25606                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25607         elif [ "$read_write" = "read" ]; then
25608                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25609         else
25610                 error "argument error"
25611         fi
25612
25613         # turn off debug for performance testing
25614         local saved_debug=$($LCTL get_param -n debug)
25615         $LCTL set_param debug=0
25616
25617         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25618
25619         # get ost1 size - $FSNAME-OST0000
25620         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25621         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25622         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25623
25624         if [ "$read_write" = "read" ]; then
25625                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25626         fi
25627
25628         local start_time=$(date +%s.%N)
25629         $dd_cmd bs=1M count=$blocks oflag=sync ||
25630                 error "real dd $read_write error"
25631         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25632
25633         if [ "$read_write" = "write" ]; then
25634                 rm -f $DIR/$tfile
25635         fi
25636
25637         # define OBD_FAIL_OST_FAKE_RW           0x238
25638         do_facet ost1 $LCTL set_param fail_loc=0x238
25639
25640         local start_time=$(date +%s.%N)
25641         $dd_cmd bs=1M count=$blocks oflag=sync ||
25642                 error "fake dd $read_write error"
25643         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25644
25645         if [ "$read_write" = "write" ]; then
25646                 # verify file size
25647                 cancel_lru_locks osc
25648                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25649                         error "$tfile size not $blocks MB"
25650         fi
25651         do_facet ost1 $LCTL set_param fail_loc=0
25652
25653         echo "fake $read_write $duration_fake vs. normal $read_write" \
25654                 "$duration in seconds"
25655         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25656                 error_not_in_vm "fake write is slower"
25657
25658         $LCTL set_param -n debug="$saved_debug"
25659         rm -f $DIR/$tfile
25660 }
25661 test_399a() { # LU-7655 for OST fake write
25662         remote_ost_nodsh && skip "remote OST with nodsh"
25663
25664         test_fake_rw write
25665 }
25666 run_test 399a "fake write should not be slower than normal write"
25667
25668 test_399b() { # LU-8726 for OST fake read
25669         remote_ost_nodsh && skip "remote OST with nodsh"
25670         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25671                 skip_env "ldiskfs only test"
25672         fi
25673
25674         test_fake_rw read
25675 }
25676 run_test 399b "fake read should not be slower than normal read"
25677
25678 test_400a() { # LU-1606, was conf-sanity test_74
25679         if ! which $CC > /dev/null 2>&1; then
25680                 skip_env "$CC is not installed"
25681         fi
25682
25683         local extra_flags=''
25684         local out=$TMP/$tfile
25685         local prefix=/usr/include/lustre
25686         local prog
25687
25688         # Oleg removes .c files in his test rig so test if any c files exist
25689         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
25690                 skip_env "Needed .c test files are missing"
25691
25692         if ! [[ -d $prefix ]]; then
25693                 # Assume we're running in tree and fixup the include path.
25694                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
25695                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
25696                 extra_flags+=" -L$LUSTRE/utils/.libs"
25697         fi
25698
25699         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
25700                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
25701                         error "client api broken"
25702         done
25703         rm -f $out
25704 }
25705 run_test 400a "Lustre client api program can compile and link"
25706
25707 test_400b() { # LU-1606, LU-5011
25708         local header
25709         local out=$TMP/$tfile
25710         local prefix=/usr/include/linux/lustre
25711
25712         # We use a hard coded prefix so that this test will not fail
25713         # when run in tree. There are headers in lustre/include/lustre/
25714         # that are not packaged (like lustre_idl.h) and have more
25715         # complicated include dependencies (like config.h and lnet/types.h).
25716         # Since this test about correct packaging we just skip them when
25717         # they don't exist (see below) rather than try to fixup cppflags.
25718
25719         if ! which $CC > /dev/null 2>&1; then
25720                 skip_env "$CC is not installed"
25721         fi
25722
25723         for header in $prefix/*.h; do
25724                 if ! [[ -f "$header" ]]; then
25725                         continue
25726                 fi
25727
25728                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
25729                         continue # lustre_ioctl.h is internal header
25730                 fi
25731
25732                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
25733                         error "cannot compile '$header'"
25734         done
25735         rm -f $out
25736 }
25737 run_test 400b "packaged headers can be compiled"
25738
25739 test_401a() { #LU-7437
25740         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
25741         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
25742
25743         #count the number of parameters by "list_param -R"
25744         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
25745         #count the number of parameters by listing proc files
25746         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
25747         echo "proc_dirs='$proc_dirs'"
25748         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
25749         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
25750                       sort -u | wc -l)
25751
25752         [ $params -eq $procs ] ||
25753                 error "found $params parameters vs. $procs proc files"
25754
25755         # test the list_param -D option only returns directories
25756         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
25757         #count the number of parameters by listing proc directories
25758         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
25759                 sort -u | wc -l)
25760
25761         [ $params -eq $procs ] ||
25762                 error "found $params parameters vs. $procs proc files"
25763 }
25764 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
25765
25766 test_401b() {
25767         # jobid_var may not allow arbitrary values, so use jobid_name
25768         # if available
25769         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25770                 local testname=jobid_name tmp='testing%p'
25771         else
25772                 local testname=jobid_var tmp=testing
25773         fi
25774
25775         local save=$($LCTL get_param -n $testname)
25776
25777         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
25778                 error "no error returned when setting bad parameters"
25779
25780         local jobid_new=$($LCTL get_param -n foe $testname baz)
25781         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
25782
25783         $LCTL set_param -n fog=bam $testname=$save bat=fog
25784         local jobid_old=$($LCTL get_param -n foe $testname bag)
25785         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
25786 }
25787 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
25788
25789 test_401c() {
25790         # jobid_var may not allow arbitrary values, so use jobid_name
25791         # if available
25792         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25793                 local testname=jobid_name
25794         else
25795                 local testname=jobid_var
25796         fi
25797
25798         local jobid_var_old=$($LCTL get_param -n $testname)
25799         local jobid_var_new
25800
25801         $LCTL set_param $testname= &&
25802                 error "no error returned for 'set_param a='"
25803
25804         jobid_var_new=$($LCTL get_param -n $testname)
25805         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25806                 error "$testname was changed by setting without value"
25807
25808         $LCTL set_param $testname &&
25809                 error "no error returned for 'set_param a'"
25810
25811         jobid_var_new=$($LCTL get_param -n $testname)
25812         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
25813                 error "$testname was changed by setting without value"
25814 }
25815 run_test 401c "Verify 'lctl set_param' without value fails in either format."
25816
25817 test_401d() {
25818         # jobid_var may not allow arbitrary values, so use jobid_name
25819         # if available
25820         if $LCTL list_param jobid_name > /dev/null 2>&1; then
25821                 local testname=jobid_name new_value='foo=bar%p'
25822         else
25823                 local testname=jobid_var new_valuie=foo=bar
25824         fi
25825
25826         local jobid_var_old=$($LCTL get_param -n $testname)
25827         local jobid_var_new
25828
25829         $LCTL set_param $testname=$new_value ||
25830                 error "'set_param a=b' did not accept a value containing '='"
25831
25832         jobid_var_new=$($LCTL get_param -n $testname)
25833         [[ "$jobid_var_new" == "$new_value" ]] ||
25834                 error "'set_param a=b' failed on a value containing '='"
25835
25836         # Reset the $testname to test the other format
25837         $LCTL set_param $testname=$jobid_var_old
25838         jobid_var_new=$($LCTL get_param -n $testname)
25839         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25840                 error "failed to reset $testname"
25841
25842         $LCTL set_param $testname $new_value ||
25843                 error "'set_param a b' did not accept a value containing '='"
25844
25845         jobid_var_new=$($LCTL get_param -n $testname)
25846         [[ "$jobid_var_new" == "$new_value" ]] ||
25847                 error "'set_param a b' failed on a value containing '='"
25848
25849         $LCTL set_param $testname $jobid_var_old
25850         jobid_var_new=$($LCTL get_param -n $testname)
25851         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
25852                 error "failed to reset $testname"
25853 }
25854 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
25855
25856 test_401e() { # LU-14779
25857         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
25858                 error "lctl list_param MGC* failed"
25859         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
25860         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
25861                 error "lctl get_param lru_size failed"
25862 }
25863 run_test 401e "verify 'lctl get_param' works with NID in parameter"
25864
25865 test_402() {
25866         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
25867         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
25868                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
25869         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
25870                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
25871                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
25872         remote_mds_nodsh && skip "remote MDS with nodsh"
25873
25874         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
25875 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
25876         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
25877         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
25878                 echo "Touch failed - OK"
25879 }
25880 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
25881
25882 test_403() {
25883         local file1=$DIR/$tfile.1
25884         local file2=$DIR/$tfile.2
25885         local tfile=$TMP/$tfile
25886
25887         rm -f $file1 $file2 $tfile
25888
25889         touch $file1
25890         ln $file1 $file2
25891
25892         # 30 sec OBD_TIMEOUT in ll_getattr()
25893         # right before populating st_nlink
25894         $LCTL set_param fail_loc=0x80001409
25895         stat -c %h $file1 > $tfile &
25896
25897         # create an alias, drop all locks and reclaim the dentry
25898         < $file2
25899         cancel_lru_locks mdc
25900         cancel_lru_locks osc
25901         sysctl -w vm.drop_caches=2
25902
25903         wait
25904
25905         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
25906
25907         rm -f $tfile $file1 $file2
25908 }
25909 run_test 403 "i_nlink should not drop to zero due to aliasing"
25910
25911 test_404() { # LU-6601
25912         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
25913                 skip "Need server version newer than 2.8.52"
25914         remote_mds_nodsh && skip "remote MDS with nodsh"
25915
25916         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
25917                 awk '/osp .*-osc-MDT/ { print $4}')
25918
25919         local osp
25920         for osp in $mosps; do
25921                 echo "Deactivate: " $osp
25922                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
25923                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25924                         awk -vp=$osp '$4 == p { print $2 }')
25925                 [ $stat = IN ] || {
25926                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25927                         error "deactivate error"
25928                 }
25929                 echo "Activate: " $osp
25930                 do_facet $SINGLEMDS $LCTL --device %$osp activate
25931                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
25932                         awk -vp=$osp '$4 == p { print $2 }')
25933                 [ $stat = UP ] || {
25934                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
25935                         error "activate error"
25936                 }
25937         done
25938 }
25939 run_test 404 "validate manual {de}activated works properly for OSPs"
25940
25941 test_405() {
25942         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25943         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
25944                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
25945                         skip "Layout swap lock is not supported"
25946
25947         check_swap_layouts_support
25948         check_swap_layout_no_dom $DIR
25949
25950         test_mkdir $DIR/$tdir
25951         swap_lock_test -d $DIR/$tdir ||
25952                 error "One layout swap locked test failed"
25953 }
25954 run_test 405 "Various layout swap lock tests"
25955
25956 test_406() {
25957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25958         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
25959         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
25960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25961         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
25962                 skip "Need MDS version at least 2.8.50"
25963
25964         local def_stripe_size=$($LFS getstripe -S $MOUNT)
25965         local test_pool=$TESTNAME
25966
25967         pool_add $test_pool || error "pool_add failed"
25968         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
25969                 error "pool_add_targets failed"
25970
25971         save_layout_restore_at_exit $MOUNT
25972
25973         # parent set default stripe count only, child will stripe from both
25974         # parent and fs default
25975         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
25976                 error "setstripe $MOUNT failed"
25977         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
25978         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
25979         for i in $(seq 10); do
25980                 local f=$DIR/$tdir/$tfile.$i
25981                 touch $f || error "touch failed"
25982                 local count=$($LFS getstripe -c $f)
25983                 [ $count -eq $OSTCOUNT ] ||
25984                         error "$f stripe count $count != $OSTCOUNT"
25985                 local offset=$($LFS getstripe -i $f)
25986                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
25987                 local size=$($LFS getstripe -S $f)
25988                 [ $size -eq $((def_stripe_size * 2)) ] ||
25989                         error "$f stripe size $size != $((def_stripe_size * 2))"
25990                 local pool=$($LFS getstripe -p $f)
25991                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
25992         done
25993
25994         # change fs default striping, delete parent default striping, now child
25995         # will stripe from new fs default striping only
25996         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
25997                 error "change $MOUNT default stripe failed"
25998         $LFS setstripe -c 0 $DIR/$tdir ||
25999                 error "delete $tdir default stripe failed"
26000         for i in $(seq 11 20); do
26001                 local f=$DIR/$tdir/$tfile.$i
26002                 touch $f || error "touch $f failed"
26003                 local count=$($LFS getstripe -c $f)
26004                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26005                 local offset=$($LFS getstripe -i $f)
26006                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26007                 local size=$($LFS getstripe -S $f)
26008                 [ $size -eq $def_stripe_size ] ||
26009                         error "$f stripe size $size != $def_stripe_size"
26010                 local pool=$($LFS getstripe -p $f)
26011                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26012         done
26013
26014         unlinkmany $DIR/$tdir/$tfile. 1 20
26015
26016         local f=$DIR/$tdir/$tfile
26017         pool_remove_all_targets $test_pool $f
26018         pool_remove $test_pool $f
26019 }
26020 run_test 406 "DNE support fs default striping"
26021
26022 test_407() {
26023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26024         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26025                 skip "Need MDS version at least 2.8.55"
26026         remote_mds_nodsh && skip "remote MDS with nodsh"
26027
26028         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26029                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26030         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26031                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26032         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26033
26034         #define OBD_FAIL_DT_TXN_STOP    0x2019
26035         for idx in $(seq $MDSCOUNT); do
26036                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26037         done
26038         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26039         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26040                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26041         true
26042 }
26043 run_test 407 "transaction fail should cause operation fail"
26044
26045 test_408() {
26046         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26047
26048         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26049         lctl set_param fail_loc=0x8000040a
26050         # let ll_prepare_partial_page() fail
26051         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26052
26053         rm -f $DIR/$tfile
26054
26055         # create at least 100 unused inodes so that
26056         # shrink_icache_memory(0) should not return 0
26057         touch $DIR/$tfile-{0..100}
26058         rm -f $DIR/$tfile-{0..100}
26059         sync
26060
26061         echo 2 > /proc/sys/vm/drop_caches
26062 }
26063 run_test 408 "drop_caches should not hang due to page leaks"
26064
26065 test_409()
26066 {
26067         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26068
26069         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26070         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26071         touch $DIR/$tdir/guard || error "(2) Fail to create"
26072
26073         local PREFIX=$(str_repeat 'A' 128)
26074         echo "Create 1K hard links start at $(date)"
26075         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26076                 error "(3) Fail to hard link"
26077
26078         echo "Links count should be right although linkEA overflow"
26079         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26080         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26081         [ $linkcount -eq 1001 ] ||
26082                 error "(5) Unexpected hard links count: $linkcount"
26083
26084         echo "List all links start at $(date)"
26085         ls -l $DIR/$tdir/foo > /dev/null ||
26086                 error "(6) Fail to list $DIR/$tdir/foo"
26087
26088         echo "Unlink hard links start at $(date)"
26089         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26090                 error "(7) Fail to unlink"
26091         echo "Unlink hard links finished at $(date)"
26092 }
26093 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26094
26095 test_410()
26096 {
26097         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26098                 skip "Need client version at least 2.9.59"
26099         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26100                 skip "Need MODULES build"
26101
26102         # Create a file, and stat it from the kernel
26103         local testfile=$DIR/$tfile
26104         touch $testfile
26105
26106         local run_id=$RANDOM
26107         local my_ino=$(stat --format "%i" $testfile)
26108
26109         # Try to insert the module. This will always fail as the
26110         # module is designed to not be inserted.
26111         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26112             &> /dev/null
26113
26114         # Anything but success is a test failure
26115         dmesg | grep -q \
26116             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26117             error "no inode match"
26118 }
26119 run_test 410 "Test inode number returned from kernel thread"
26120
26121 cleanup_test411_cgroup() {
26122         trap 0
26123         rmdir "$1"
26124 }
26125
26126 test_411() {
26127         local cg_basedir=/sys/fs/cgroup/memory
26128         # LU-9966
26129         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26130                 skip "no setup for cgroup"
26131
26132         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26133                 error "test file creation failed"
26134         cancel_lru_locks osc
26135
26136         # Create a very small memory cgroup to force a slab allocation error
26137         local cgdir=$cg_basedir/osc_slab_alloc
26138         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26139         trap "cleanup_test411_cgroup $cgdir" EXIT
26140         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26141         echo 1M > $cgdir/memory.limit_in_bytes
26142
26143         # Should not LBUG, just be killed by oom-killer
26144         # dd will return 0 even allocation failure in some environment.
26145         # So don't check return value
26146         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26147         cleanup_test411_cgroup $cgdir
26148
26149         return 0
26150 }
26151 run_test 411 "Slab allocation error with cgroup does not LBUG"
26152
26153 test_412() {
26154         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26155         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26156                 skip "Need server version at least 2.10.55"
26157
26158         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26159                 error "mkdir failed"
26160         $LFS getdirstripe $DIR/$tdir
26161         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26162         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26163                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26164         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26165         [ $stripe_count -eq 2 ] ||
26166                 error "expect 2 get $stripe_count"
26167
26168         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26169
26170         local index
26171         local index2
26172
26173         # subdirs should be on the same MDT as parent
26174         for i in $(seq 0 $((MDSCOUNT - 1))); do
26175                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26176                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26177                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26178                 (( index == i )) || error "mdt$i/sub on MDT$index"
26179         done
26180
26181         # stripe offset -1, ditto
26182         for i in {1..10}; do
26183                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26184                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26185                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26186                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26187                 (( index == index2 )) ||
26188                         error "qos$i on MDT$index, sub on MDT$index2"
26189         done
26190
26191         local testdir=$DIR/$tdir/inherit
26192
26193         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26194         # inherit 2 levels
26195         for i in 1 2; do
26196                 testdir=$testdir/s$i
26197                 mkdir $testdir || error "mkdir $testdir failed"
26198                 index=$($LFS getstripe -m $testdir)
26199                 (( index == 1 )) ||
26200                         error "$testdir on MDT$index"
26201         done
26202
26203         # not inherit any more
26204         testdir=$testdir/s3
26205         mkdir $testdir || error "mkdir $testdir failed"
26206         getfattr -d -m dmv $testdir | grep dmv &&
26207                 error "default LMV set on $testdir" || true
26208 }
26209 run_test 412 "mkdir on specific MDTs"
26210
26211 TEST413_COUNT=${TEST413_COUNT:-200}
26212 generate_uneven_mdts() {
26213         local threshold=$1
26214         local lmv_qos_maxage
26215         local lod_qos_maxage
26216         local ffree
26217         local bavail
26218         local max
26219         local min
26220         local max_index
26221         local min_index
26222         local tmp
26223         local i
26224
26225         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26226         $LCTL set_param lmv.*.qos_maxage=1
26227         stack_trap "$LCTL set_param \
26228                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26229         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26230                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26231         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26232                 lod.*.mdt_qos_maxage=1
26233         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26234                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26235
26236         echo
26237         echo "Check for uneven MDTs: "
26238
26239         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26240         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26241         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26242
26243         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26244         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26245         max_index=0
26246         min_index=0
26247         for ((i = 1; i < ${#ffree[@]}; i++)); do
26248                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26249                 if [ $tmp -gt $max ]; then
26250                         max=$tmp
26251                         max_index=$i
26252                 fi
26253                 if [ $tmp -lt $min ]; then
26254                         min=$tmp
26255                         min_index=$i
26256                 fi
26257         done
26258
26259         (( ${ffree[min_index]} > 0 )) ||
26260                 skip "no free files in MDT$min_index"
26261         (( ${ffree[min_index]} < 10000000 )) ||
26262                 skip "too many free files in MDT$min_index"
26263
26264         # Check if we need to generate uneven MDTs
26265         local diff=$(((max - min) * 100 / min))
26266         local testdir=$DIR/$tdir-fillmdt
26267         local start
26268
26269         i=0
26270         while (( diff < threshold )); do
26271                 mkdir -p $testdir
26272                 # generate uneven MDTs, create till $threshold% diff
26273                 echo -n "weight diff=$diff% must be > $threshold% ..."
26274                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26275                 testdir=$DIR/$tdir-fillmdt/$i
26276                 [ -d $testdir ] && continue
26277                 $LFS mkdir -i $min_index $testdir ||
26278                         error "mkdir $testdir failed"
26279                 $LFS setstripe -E 1M -L mdt $testdir ||
26280                         error "setstripe $testdir failed"
26281                 start=$SECONDS
26282                 for ((F=0; F < TEST413_COUNT; F++)); do
26283                         dd if=/dev/zero of=$testdir/f.$F bs=128K count=1 > \
26284                                 /dev/null 2>&1 || error "dd $F failed"
26285                 done
26286                 sync; sleep 1; sync
26287
26288                 # wait for QOS to update
26289                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
26290
26291                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26292                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26293                 max=$(((${ffree[max_index]} >> 8) *
26294                         (${bavail[max_index]} * bsize >> 16)))
26295                 min=$(((${ffree[min_index]} >> 8) *
26296                         (${bavail[min_index]} * bsize >> 16)))
26297                 diff=$(((max - min) * 100 / min))
26298                 i=$((i + 1))
26299         done
26300
26301         echo "MDT filesfree available: ${ffree[*]}"
26302         echo "MDT blocks available: ${bavail[*]}"
26303         echo "weight diff=$diff%"
26304 }
26305
26306 test_qos_mkdir() {
26307         local mkdir_cmd=$1
26308         local stripe_count=$2
26309         local mdts=$(comma_list $(mdts_nodes))
26310
26311         local testdir
26312         local lmv_qos_prio_free
26313         local lmv_qos_threshold_rr
26314         local lmv_qos_maxage
26315         local lod_qos_prio_free
26316         local lod_qos_threshold_rr
26317         local lod_qos_maxage
26318         local count
26319         local i
26320
26321         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26322         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26323         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26324                 head -n1)
26325         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26326         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26327         stack_trap "$LCTL set_param \
26328                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26329         stack_trap "$LCTL set_param \
26330                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26331         stack_trap "$LCTL set_param \
26332                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26333
26334         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26335                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26336         lod_qos_prio_free=${lod_qos_prio_free%%%}
26337         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26338                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26339         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26340         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26341                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26342         stack_trap "do_nodes $mdts $LCTL set_param \
26343                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26344         stack_trap "do_nodes $mdts $LCTL set_param \
26345                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26346         stack_trap "do_nodes $mdts $LCTL set_param \
26347                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26348
26349         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26350         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26351
26352         testdir=$DIR/$tdir-s$stripe_count/rr
26353
26354         local stripe_index=$($LFS getstripe -m $testdir)
26355         local test_mkdir_rr=true
26356
26357         getfattr -d -m dmv -e hex $testdir | grep dmv
26358         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26359                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26360                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26361                         test_mkdir_rr=false
26362         fi
26363
26364         echo
26365         $test_mkdir_rr &&
26366                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26367                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26368
26369         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
26370         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
26371                 eval $mkdir_cmd $testdir/subdir$i ||
26372                         error "$mkdir_cmd subdir$i failed"
26373         done
26374
26375         for (( i = 0; i < $MDSCOUNT; i++ )); do
26376                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26377                 echo "$count directories created on MDT$i"
26378                 if $test_mkdir_rr; then
26379                         (( $count == 100 )) ||
26380                                 error "subdirs are not evenly distributed"
26381                 elif (( $i == $stripe_index )); then
26382                         (( $count == 100 * MDSCOUNT )) ||
26383                                 error "$count subdirs created on MDT$i"
26384                 else
26385                         (( $count == 0 )) ||
26386                                 error "$count subdirs created on MDT$i"
26387                 fi
26388
26389                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26390                         count=$($LFS getdirstripe $testdir/* |
26391                                 grep -c -P "^\s+$i\t")
26392                         echo "$count stripes created on MDT$i"
26393                         # deviation should < 5% of average
26394                         (( $count >= 95 * stripe_count &&
26395                            $count <= 105 * stripe_count)) ||
26396                                 error "stripes are not evenly distributed"
26397                 fi
26398         done
26399
26400         echo
26401         echo "Check for uneven MDTs: "
26402
26403         local ffree
26404         local bavail
26405         local max
26406         local min
26407         local max_index
26408         local min_index
26409         local tmp
26410
26411         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26412         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26413         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26414
26415         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26416         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26417         max_index=0
26418         min_index=0
26419         for ((i = 1; i < ${#ffree[@]}; i++)); do
26420                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26421                 if [ $tmp -gt $max ]; then
26422                         max=$tmp
26423                         max_index=$i
26424                 fi
26425                 if [ $tmp -lt $min ]; then
26426                         min=$tmp
26427                         min_index=$i
26428                 fi
26429         done
26430
26431         (( ${ffree[min_index]} > 0 )) ||
26432                 skip "no free files in MDT$min_index"
26433         (( ${ffree[min_index]} < 10000000 )) ||
26434                 skip "too many free files in MDT$min_index"
26435
26436         echo "MDT filesfree available: ${ffree[*]}"
26437         echo "MDT blocks available: ${bavail[*]}"
26438         echo "weight diff=$(((max - min) * 100 / min))%"
26439         echo
26440         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26441
26442         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26443         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26444         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26445         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26446         # decrease statfs age, so that it can be updated in time
26447         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26448         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26449
26450         sleep 1
26451
26452         testdir=$DIR/$tdir-s$stripe_count/qos
26453         local num=200
26454
26455         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
26456         for (( i = 0; i < num * MDSCOUNT; i++ )); do
26457                 eval $mkdir_cmd $testdir/subdir$i ||
26458                         error "$mkdir_cmd subdir$i failed"
26459         done
26460
26461         max=0
26462         for (( i = 0; i < $MDSCOUNT; i++ )); do
26463                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26464                 (( count > max )) && max=$count
26465                 echo "$count directories created on MDT$i"
26466         done
26467
26468         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26469
26470         # D-value should > 10% of averge
26471         (( max - min > num / 10 )) ||
26472                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
26473
26474         # ditto for stripes
26475         if (( stripe_count > 1 )); then
26476                 max=0
26477                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26478                         count=$($LFS getdirstripe $testdir/* |
26479                                 grep -c -P "^\s+$i\t")
26480                         (( count > max )) && max=$count
26481                         echo "$count stripes created on MDT$i"
26482                 done
26483
26484                 min=$($LFS getdirstripe $testdir/* |
26485                         grep -c -P "^\s+$min_index\t")
26486                 (( max - min > num * stripe_count / 10 )) ||
26487                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
26488         fi
26489 }
26490
26491 most_full_mdt() {
26492         local ffree
26493         local bavail
26494         local bsize
26495         local min
26496         local min_index
26497         local tmp
26498
26499         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26500         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26501         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26502
26503         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26504         min_index=0
26505         for ((i = 1; i < ${#ffree[@]}; i++)); do
26506                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26507                 (( tmp < min )) && min=$tmp && min_index=$i
26508         done
26509
26510         echo -n $min_index
26511 }
26512
26513 test_413a() {
26514         [ $MDSCOUNT -lt 2 ] &&
26515                 skip "We need at least 2 MDTs for this test"
26516
26517         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26518                 skip "Need server version at least 2.12.52"
26519
26520         local stripe_count
26521
26522         generate_uneven_mdts 100
26523         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26524                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26525                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26526                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26527                         error "mkdir failed"
26528                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26529         done
26530 }
26531 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26532
26533 test_413b() {
26534         [ $MDSCOUNT -lt 2 ] &&
26535                 skip "We need at least 2 MDTs for this test"
26536
26537         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26538                 skip "Need server version at least 2.12.52"
26539
26540         local testdir
26541         local stripe_count
26542
26543         generate_uneven_mdts 100
26544         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
26545                 testdir=$DIR/$tdir-s$stripe_count
26546                 mkdir $testdir || error "mkdir $testdir failed"
26547                 mkdir $testdir/rr || error "mkdir rr failed"
26548                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26549                         error "mkdir qos failed"
26550                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26551                         $testdir/rr || error "setdirstripe rr failed"
26552                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26553                         error "setdirstripe failed"
26554                 test_qos_mkdir "mkdir" $stripe_count
26555         done
26556 }
26557 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26558
26559 test_413c() {
26560         (( $MDSCOUNT >= 2 )) ||
26561                 skip "We need at least 2 MDTs for this test"
26562
26563         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26564                 skip "Need server version at least 2.14.51"
26565
26566         local testdir
26567         local inherit
26568         local inherit_rr
26569
26570         testdir=$DIR/${tdir}-s1
26571         mkdir $testdir || error "mkdir $testdir failed"
26572         mkdir $testdir/rr || error "mkdir rr failed"
26573         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26574         # default max_inherit is -1, default max_inherit_rr is 0
26575         $LFS setdirstripe -D -c 1 $testdir/rr ||
26576                 error "setdirstripe rr failed"
26577         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26578                 error "setdirstripe qos failed"
26579         test_qos_mkdir "mkdir" 1
26580
26581         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26582         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26583         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26584         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26585         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26586
26587         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26588         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26589         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26590         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26591         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26592         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26593         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26594                 error "level2 shouldn't have default LMV" || true
26595 }
26596 run_test 413c "mkdir with default LMV max inherit rr"
26597
26598 test_413d() {
26599         (( MDSCOUNT >= 2 )) ||
26600                 skip "We need at least 2 MDTs for this test"
26601
26602         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26603                 skip "Need server version at least 2.14.51"
26604
26605         local lmv_qos_threshold_rr
26606
26607         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26608                 head -n1)
26609         stack_trap "$LCTL set_param \
26610                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26611
26612         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26613         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
26614         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
26615                 error "$tdir shouldn't have default LMV"
26616         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
26617                 error "mkdir sub failed"
26618
26619         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
26620
26621         (( count == 100 )) || error "$count subdirs on MDT0"
26622 }
26623 run_test 413d "inherit ROOT default LMV"
26624
26625 test_413e() {
26626         (( MDSCOUNT >= 2 )) ||
26627                 skip "We need at least 2 MDTs for this test"
26628         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26629                 skip "Need server version at least 2.14.55"
26630
26631         local testdir=$DIR/$tdir
26632         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
26633         local max_inherit
26634         local sub_max_inherit
26635
26636         mkdir -p $testdir || error "failed to create $testdir"
26637
26638         # set default max-inherit to -1 if stripe count is 0 or 1
26639         $LFS setdirstripe -D -c 1 $testdir ||
26640                 error "failed to set default LMV"
26641         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26642         (( max_inherit == -1 )) ||
26643                 error "wrong max_inherit value $max_inherit"
26644
26645         # set default max_inherit to a fixed value if stripe count is not 0 or 1
26646         $LFS setdirstripe -D -c -1 $testdir ||
26647                 error "failed to set default LMV"
26648         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26649         (( max_inherit > 0 )) ||
26650                 error "wrong max_inherit value $max_inherit"
26651
26652         # and the subdir will decrease the max_inherit by 1
26653         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
26654         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
26655         (( sub_max_inherit == max_inherit - 1)) ||
26656                 error "wrong max-inherit of subdir $sub_max_inherit"
26657
26658         # check specified --max-inherit and warning message
26659         stack_trap "rm -f $tmpfile"
26660         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
26661                 error "failed to set default LMV"
26662         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
26663         (( max_inherit == -1 )) ||
26664                 error "wrong max_inherit value $max_inherit"
26665
26666         # check the warning messages
26667         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
26668                 error "failed to detect warning string"
26669         fi
26670 }
26671 run_test 413e "check default max-inherit value"
26672
26673 test_fs_dmv_inherit()
26674 {
26675         local testdir=$DIR/$tdir
26676
26677         local count
26678         local inherit
26679         local inherit_rr
26680
26681         for i in 1 2 3; do
26682                 mkdir $testdir || error "mkdir $testdir failed"
26683                 count=$($LFS getdirstripe -D -c $testdir)
26684                 (( count == 1 )) ||
26685                         error "$testdir default LMV count mismatch $count != 1"
26686                 inherit=$($LFS getdirstripe -D -X $testdir)
26687                 (( inherit == 3 - i )) ||
26688                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
26689                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
26690                 (( inherit_rr == 3 - i )) ||
26691                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
26692                 testdir=$testdir/sub
26693         done
26694
26695         mkdir $testdir || error "mkdir $testdir failed"
26696         count=$($LFS getdirstripe -D -c $testdir)
26697         (( count == 0 )) ||
26698                 error "$testdir default LMV count not zero: $count"
26699 }
26700
26701 test_413f() {
26702         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26703
26704         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
26705                 skip "Need server version at least 2.14.55"
26706
26707         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26708                 error "dump $DIR default LMV failed"
26709         stack_trap "setfattr --restore=$TMP/dmv.ea"
26710
26711         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26712                 error "set $DIR default LMV failed"
26713
26714         test_fs_dmv_inherit
26715 }
26716 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
26717
26718 test_413g() {
26719         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
26720
26721         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
26722         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
26723                 error "dump $DIR default LMV failed"
26724         stack_trap "setfattr --restore=$TMP/dmv.ea"
26725
26726         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
26727                 error "set $DIR default LMV failed"
26728
26729         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
26730                 error "mount $MOUNT2 failed"
26731         stack_trap "umount_client $MOUNT2"
26732
26733         local saved_DIR=$DIR
26734
26735         export DIR=$MOUNT2
26736
26737         stack_trap "export DIR=$saved_DIR"
26738
26739         # first check filesystem-wide default LMV inheritance
26740         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
26741
26742         # then check subdirs are spread to all MDTs
26743         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
26744
26745         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
26746
26747         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
26748 }
26749 run_test 413g "enforce ROOT default LMV on subdir mount"
26750
26751 test_413h() {
26752         (( MDSCOUNT >= 2 )) ||
26753                 skip "We need at least 2 MDTs for this test"
26754
26755         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
26756                 skip "Need server version at least 2.15.50.6"
26757
26758         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26759
26760         stack_trap "$LCTL set_param \
26761                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26762         $LCTL set_param lmv.*.qos_maxage=1
26763
26764         local depth=5
26765         local rr_depth=4
26766         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
26767         local count=$((MDSCOUNT * 20))
26768
26769         generate_uneven_mdts 50
26770
26771         mkdir -p $dir || error "mkdir $dir failed"
26772         stack_trap "rm -rf $dir"
26773         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
26774                 --max-inherit-rr=$rr_depth $dir
26775
26776         for ((d=0; d < depth + 2; d++)); do
26777                 log "dir=$dir:"
26778                 for ((sub=0; sub < count; sub++)); do
26779                         mkdir $dir/d$sub
26780                 done
26781                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
26782                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
26783                 # subdirs within $rr_depth should be created round-robin
26784                 if (( d < rr_depth )); then
26785                         (( ${num[0]} != count )) ||
26786                                 error "all objects created on MDT ${num[1]}"
26787                 fi
26788
26789                 dir=$dir/d0
26790         done
26791 }
26792 run_test 413h "don't stick to parent for round-robin dirs"
26793
26794 test_413z() {
26795         local pids=""
26796         local subdir
26797         local pid
26798
26799         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
26800                 unlinkmany $subdir/f. $TEST413_COUNT &
26801                 pids="$pids $!"
26802         done
26803
26804         for pid in $pids; do
26805                 wait $pid
26806         done
26807 }
26808 run_test 413z "413 test cleanup"
26809
26810 test_414() {
26811 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
26812         $LCTL set_param fail_loc=0x80000521
26813         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26814         rm -f $DIR/$tfile
26815 }
26816 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
26817
26818 test_415() {
26819         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26820         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
26821                 skip "Need server version at least 2.11.52"
26822
26823         # LU-11102
26824         local total=500
26825         local max=120
26826
26827         # this test may be slow on ZFS
26828         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
26829
26830         # though this test is designed for striped directory, let's test normal
26831         # directory too since lock is always saved as CoS lock.
26832         test_mkdir $DIR/$tdir || error "mkdir $tdir"
26833         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
26834         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
26835         # if looping with ONLY_REPEAT, wait for previous deletions to finish
26836         wait_delete_completed_mds
26837
26838         # run a loop without concurrent touch to measure rename duration.
26839         # only for test debug/robustness, NOT part of COS functional test.
26840         local start_time=$SECONDS
26841         for ((i = 0; i < total; i++)); do
26842                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
26843                         > /dev/null
26844         done
26845         local baseline=$((SECONDS - start_time))
26846         echo "rename $total files without 'touch' took $baseline sec"
26847
26848         (
26849                 while true; do
26850                         touch $DIR/$tdir
26851                 done
26852         ) &
26853         local setattr_pid=$!
26854
26855         # rename files back to original name so unlinkmany works
26856         start_time=$SECONDS
26857         for ((i = 0; i < total; i++)); do
26858                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
26859                         > /dev/null
26860         done
26861         local duration=$((SECONDS - start_time))
26862
26863         kill -9 $setattr_pid
26864
26865         echo "rename $total files with 'touch' took $duration sec"
26866         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
26867         (( duration <= max )) || error "rename took $duration > $max sec"
26868 }
26869 run_test 415 "lock revoke is not missing"
26870
26871 test_416() {
26872         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26873                 skip "Need server version at least 2.11.55"
26874
26875         # define OBD_FAIL_OSD_TXN_START    0x19a
26876         do_facet mds1 lctl set_param fail_loc=0x19a
26877
26878         lfs mkdir -c $MDSCOUNT $DIR/$tdir
26879
26880         true
26881 }
26882 run_test 416 "transaction start failure won't cause system hung"
26883
26884 cleanup_417() {
26885         trap 0
26886         do_nodes $(comma_list $(mdts_nodes)) \
26887                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
26888         do_nodes $(comma_list $(mdts_nodes)) \
26889                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
26890         do_nodes $(comma_list $(mdts_nodes)) \
26891                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
26892 }
26893
26894 test_417() {
26895         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26896         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
26897                 skip "Need MDS version at least 2.11.56"
26898
26899         trap cleanup_417 RETURN EXIT
26900
26901         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
26902         do_nodes $(comma_list $(mdts_nodes)) \
26903                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
26904         $LFS migrate -m 0 $DIR/$tdir.1 &&
26905                 error "migrate dir $tdir.1 should fail"
26906
26907         do_nodes $(comma_list $(mdts_nodes)) \
26908                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
26909         $LFS mkdir -i 1 $DIR/$tdir.2 &&
26910                 error "create remote dir $tdir.2 should fail"
26911
26912         do_nodes $(comma_list $(mdts_nodes)) \
26913                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
26914         $LFS mkdir -c 2 $DIR/$tdir.3 &&
26915                 error "create striped dir $tdir.3 should fail"
26916         true
26917 }
26918 run_test 417 "disable remote dir, striped dir and dir migration"
26919
26920 # Checks that the outputs of df [-i] and lfs df [-i] match
26921 #
26922 # usage: check_lfs_df <blocks | inodes> <mountpoint>
26923 check_lfs_df() {
26924         local dir=$2
26925         local inodes
26926         local df_out
26927         local lfs_df_out
26928         local count
26929         local passed=false
26930
26931         # blocks or inodes
26932         [ "$1" == "blocks" ] && inodes= || inodes="-i"
26933
26934         for count in {1..100}; do
26935                 do_nodes "$CLIENTS" \
26936                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26937                 sync; sleep 0.2
26938
26939                 # read the lines of interest
26940                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
26941                         error "df $inodes $dir | tail -n +2 failed"
26942                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
26943                         error "lfs df $inodes $dir | grep summary: failed"
26944
26945                 # skip first substrings of each output as they are different
26946                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
26947                 # compare the two outputs
26948                 passed=true
26949                 #  skip "available" on MDT until LU-13997 is fixed.
26950                 #for i in {1..5}; do
26951                 for i in 1 2 4 5; do
26952                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
26953                 done
26954                 $passed && break
26955         done
26956
26957         if ! $passed; then
26958                 df -P $inodes $dir
26959                 echo
26960                 lfs df $inodes $dir
26961                 error "df and lfs df $1 output mismatch: "      \
26962                       "df ${inodes}: ${df_out[*]}, "            \
26963                       "lfs df ${inodes}: ${lfs_df_out[*]}"
26964         fi
26965 }
26966
26967 test_418() {
26968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26969
26970         local dir=$DIR/$tdir
26971         local numfiles=$((RANDOM % 4096 + 2))
26972         local numblocks=$((RANDOM % 256 + 1))
26973
26974         wait_delete_completed
26975         test_mkdir $dir
26976
26977         # check block output
26978         check_lfs_df blocks $dir
26979         # check inode output
26980         check_lfs_df inodes $dir
26981
26982         # create a single file and retest
26983         echo "Creating a single file and testing"
26984         createmany -o $dir/$tfile- 1 &>/dev/null ||
26985                 error "creating 1 file in $dir failed"
26986         check_lfs_df blocks $dir
26987         check_lfs_df inodes $dir
26988
26989         # create a random number of files
26990         echo "Creating $((numfiles - 1)) files and testing"
26991         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
26992                 error "creating $((numfiles - 1)) files in $dir failed"
26993
26994         # write a random number of blocks to the first test file
26995         echo "Writing $numblocks 4K blocks and testing"
26996         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
26997                 count=$numblocks &>/dev/null ||
26998                 error "dd to $dir/${tfile}-0 failed"
26999
27000         # retest
27001         check_lfs_df blocks $dir
27002         check_lfs_df inodes $dir
27003
27004         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27005                 error "unlinking $numfiles files in $dir failed"
27006 }
27007 run_test 418 "df and lfs df outputs match"
27008
27009 test_419()
27010 {
27011         local dir=$DIR/$tdir
27012
27013         mkdir -p $dir
27014         touch $dir/file
27015
27016         cancel_lru_locks mdc
27017
27018         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27019         $LCTL set_param fail_loc=0x1410
27020         cat $dir/file
27021         $LCTL set_param fail_loc=0
27022         rm -rf $dir
27023 }
27024 run_test 419 "Verify open file by name doesn't crash kernel"
27025
27026 test_420()
27027 {
27028         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27029                 skip "Need MDS version at least 2.12.53"
27030
27031         local SAVE_UMASK=$(umask)
27032         local dir=$DIR/$tdir
27033         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27034
27035         mkdir -p $dir
27036         umask 0000
27037         mkdir -m03777 $dir/testdir
27038         ls -dn $dir/testdir
27039         # Need to remove trailing '.' when SELinux is enabled
27040         local dirperms=$(ls -dn $dir/testdir |
27041                          awk '{ sub(/\.$/, "", $1); print $1}')
27042         [ $dirperms == "drwxrwsrwt" ] ||
27043                 error "incorrect perms on $dir/testdir"
27044
27045         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27046                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27047         ls -n $dir/testdir/testfile
27048         local fileperms=$(ls -n $dir/testdir/testfile |
27049                           awk '{ sub(/\.$/, "", $1); print $1}')
27050         [ $fileperms == "-rwxr-xr-x" ] ||
27051                 error "incorrect perms on $dir/testdir/testfile"
27052
27053         umask $SAVE_UMASK
27054 }
27055 run_test 420 "clear SGID bit on non-directories for non-members"
27056
27057 test_421a() {
27058         local cnt
27059         local fid1
27060         local fid2
27061
27062         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27063                 skip "Need MDS version at least 2.12.54"
27064
27065         test_mkdir $DIR/$tdir
27066         createmany -o $DIR/$tdir/f 3
27067         cnt=$(ls -1 $DIR/$tdir | wc -l)
27068         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27069
27070         fid1=$(lfs path2fid $DIR/$tdir/f1)
27071         fid2=$(lfs path2fid $DIR/$tdir/f2)
27072         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27073
27074         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27075         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27076
27077         cnt=$(ls -1 $DIR/$tdir | wc -l)
27078         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27079
27080         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27081         createmany -o $DIR/$tdir/f 3
27082         cnt=$(ls -1 $DIR/$tdir | wc -l)
27083         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27084
27085         fid1=$(lfs path2fid $DIR/$tdir/f1)
27086         fid2=$(lfs path2fid $DIR/$tdir/f2)
27087         echo "remove using fsname $FSNAME"
27088         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27089
27090         cnt=$(ls -1 $DIR/$tdir | wc -l)
27091         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27092 }
27093 run_test 421a "simple rm by fid"
27094
27095 test_421b() {
27096         local cnt
27097         local FID1
27098         local FID2
27099
27100         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27101                 skip "Need MDS version at least 2.12.54"
27102
27103         test_mkdir $DIR/$tdir
27104         createmany -o $DIR/$tdir/f 3
27105         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27106         MULTIPID=$!
27107
27108         FID1=$(lfs path2fid $DIR/$tdir/f1)
27109         FID2=$(lfs path2fid $DIR/$tdir/f2)
27110         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27111
27112         kill -USR1 $MULTIPID
27113         wait
27114
27115         cnt=$(ls $DIR/$tdir | wc -l)
27116         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27117 }
27118 run_test 421b "rm by fid on open file"
27119
27120 test_421c() {
27121         local cnt
27122         local FIDS
27123
27124         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27125                 skip "Need MDS version at least 2.12.54"
27126
27127         test_mkdir $DIR/$tdir
27128         createmany -o $DIR/$tdir/f 3
27129         touch $DIR/$tdir/$tfile
27130         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27131         cnt=$(ls -1 $DIR/$tdir | wc -l)
27132         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27133
27134         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27135         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27136
27137         cnt=$(ls $DIR/$tdir | wc -l)
27138         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27139 }
27140 run_test 421c "rm by fid against hardlinked files"
27141
27142 test_421d() {
27143         local cnt
27144         local FIDS
27145
27146         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27147                 skip "Need MDS version at least 2.12.54"
27148
27149         test_mkdir $DIR/$tdir
27150         createmany -o $DIR/$tdir/f 4097
27151         cnt=$(ls -1 $DIR/$tdir | wc -l)
27152         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27153
27154         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27155         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27156
27157         cnt=$(ls $DIR/$tdir | wc -l)
27158         rm -rf $DIR/$tdir
27159         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27160 }
27161 run_test 421d "rmfid en masse"
27162
27163 test_421e() {
27164         local cnt
27165         local FID
27166
27167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27168         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27169                 skip "Need MDS version at least 2.12.54"
27170
27171         mkdir -p $DIR/$tdir
27172         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27173         createmany -o $DIR/$tdir/striped_dir/f 512
27174         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27175         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27176
27177         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27178                 sed "s/[/][^:]*://g")
27179         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27180
27181         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27182         rm -rf $DIR/$tdir
27183         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27184 }
27185 run_test 421e "rmfid in DNE"
27186
27187 test_421f() {
27188         local cnt
27189         local FID
27190
27191         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27192                 skip "Need MDS version at least 2.12.54"
27193
27194         test_mkdir $DIR/$tdir
27195         touch $DIR/$tdir/f
27196         cnt=$(ls -1 $DIR/$tdir | wc -l)
27197         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27198
27199         FID=$(lfs path2fid $DIR/$tdir/f)
27200         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27201         # rmfid should fail
27202         cnt=$(ls -1 $DIR/$tdir | wc -l)
27203         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27204
27205         chmod a+rw $DIR/$tdir
27206         ls -la $DIR/$tdir
27207         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27208         # rmfid should fail
27209         cnt=$(ls -1 $DIR/$tdir | wc -l)
27210         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27211
27212         rm -f $DIR/$tdir/f
27213         $RUNAS touch $DIR/$tdir/f
27214         FID=$(lfs path2fid $DIR/$tdir/f)
27215         echo "rmfid as root"
27216         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27217         cnt=$(ls -1 $DIR/$tdir | wc -l)
27218         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27219
27220         rm -f $DIR/$tdir/f
27221         $RUNAS touch $DIR/$tdir/f
27222         cnt=$(ls -1 $DIR/$tdir | wc -l)
27223         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27224         FID=$(lfs path2fid $DIR/$tdir/f)
27225         # rmfid w/o user_fid2path mount option should fail
27226         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27227         cnt=$(ls -1 $DIR/$tdir | wc -l)
27228         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27229
27230         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27231         stack_trap "rmdir $tmpdir"
27232         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27233                 error "failed to mount client'"
27234         stack_trap "umount_client $tmpdir"
27235
27236         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27237         # rmfid should succeed
27238         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27239         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27240
27241         # rmfid shouldn't allow to remove files due to dir's permission
27242         chmod a+rwx $tmpdir/$tdir
27243         touch $tmpdir/$tdir/f
27244         ls -la $tmpdir/$tdir
27245         FID=$(lfs path2fid $tmpdir/$tdir/f)
27246         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27247         return 0
27248 }
27249 run_test 421f "rmfid checks permissions"
27250
27251 test_421g() {
27252         local cnt
27253         local FIDS
27254
27255         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27256         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27257                 skip "Need MDS version at least 2.12.54"
27258
27259         mkdir -p $DIR/$tdir
27260         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27261         createmany -o $DIR/$tdir/striped_dir/f 512
27262         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27263         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27264
27265         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27266                 sed "s/[/][^:]*://g")
27267
27268         rm -f $DIR/$tdir/striped_dir/f1*
27269         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27270         removed=$((512 - cnt))
27271
27272         # few files have been just removed, so we expect
27273         # rmfid to fail on their fids
27274         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27275         [ $removed != $errors ] && error "$errors != $removed"
27276
27277         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27278         rm -rf $DIR/$tdir
27279         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27280 }
27281 run_test 421g "rmfid to return errors properly"
27282
27283 test_422() {
27284         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27285         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27286         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27287         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27288         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27289
27290         local amc=$(at_max_get client)
27291         local amo=$(at_max_get mds1)
27292         local timeout=`lctl get_param -n timeout`
27293
27294         at_max_set 0 client
27295         at_max_set 0 mds1
27296
27297 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27298         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27299                         fail_val=$(((2*timeout + 10)*1000))
27300         touch $DIR/$tdir/d3/file &
27301         sleep 2
27302 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27303         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27304                         fail_val=$((2*timeout + 5))
27305         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27306         local pid=$!
27307         sleep 1
27308         kill -9 $pid
27309         sleep $((2 * timeout))
27310         echo kill $pid
27311         kill -9 $pid
27312         lctl mark touch
27313         touch $DIR/$tdir/d2/file3
27314         touch $DIR/$tdir/d2/file4
27315         touch $DIR/$tdir/d2/file5
27316
27317         wait
27318         at_max_set $amc client
27319         at_max_set $amo mds1
27320
27321         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27322         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27323                 error "Watchdog is always throttled"
27324 }
27325 run_test 422 "kill a process with RPC in progress"
27326
27327 stat_test() {
27328     df -h $MOUNT &
27329     df -h $MOUNT &
27330     df -h $MOUNT &
27331     df -h $MOUNT &
27332     df -h $MOUNT &
27333     df -h $MOUNT &
27334 }
27335
27336 test_423() {
27337     local _stats
27338     # ensure statfs cache is expired
27339     sleep 2;
27340
27341     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27342     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27343
27344     return 0
27345 }
27346 run_test 423 "statfs should return a right data"
27347
27348 test_424() {
27349 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27350         $LCTL set_param fail_loc=0x80000522
27351         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27352         rm -f $DIR/$tfile
27353 }
27354 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27355
27356 test_425() {
27357         test_mkdir -c -1 $DIR/$tdir
27358         $LFS setstripe -c -1 $DIR/$tdir
27359
27360         lru_resize_disable "" 100
27361         stack_trap "lru_resize_enable" EXIT
27362
27363         sleep 5
27364
27365         for i in $(seq $((MDSCOUNT * 125))); do
27366                 local t=$DIR/$tdir/$tfile_$i
27367
27368                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27369                         error_noexit "Create file $t"
27370         done
27371         stack_trap "rm -rf $DIR/$tdir" EXIT
27372
27373         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27374                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27375                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27376
27377                 [ $lock_count -le $lru_size ] ||
27378                         error "osc lock count $lock_count > lru size $lru_size"
27379         done
27380
27381         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27382                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27383                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27384
27385                 [ $lock_count -le $lru_size ] ||
27386                         error "mdc lock count $lock_count > lru size $lru_size"
27387         done
27388 }
27389 run_test 425 "lock count should not exceed lru size"
27390
27391 test_426() {
27392         splice-test -r $DIR/$tfile
27393         splice-test -rd $DIR/$tfile
27394         splice-test $DIR/$tfile
27395         splice-test -d $DIR/$tfile
27396 }
27397 run_test 426 "splice test on Lustre"
27398
27399 test_427() {
27400         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27401         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27402                 skip "Need MDS version at least 2.12.4"
27403         local log
27404
27405         mkdir $DIR/$tdir
27406         mkdir $DIR/$tdir/1
27407         mkdir $DIR/$tdir/2
27408         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27409         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27410
27411         $LFS getdirstripe $DIR/$tdir/1/dir
27412
27413         #first setfattr for creating updatelog
27414         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27415
27416 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27417         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27418         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27419         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27420
27421         sleep 2
27422         fail mds2
27423         wait_recovery_complete mds2 $((2*TIMEOUT))
27424
27425         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27426         echo $log | grep "get update log failed" &&
27427                 error "update log corruption is detected" || true
27428 }
27429 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27430
27431 test_428() {
27432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27433         local cache_limit=$CACHE_MAX
27434
27435         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27436         $LCTL set_param -n llite.*.max_cached_mb=64
27437
27438         mkdir $DIR/$tdir
27439         $LFS setstripe -c 1 $DIR/$tdir
27440         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27441         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27442         #test write
27443         for f in $(seq 4); do
27444                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27445         done
27446         wait
27447
27448         cancel_lru_locks osc
27449         # Test read
27450         for f in $(seq 4); do
27451                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27452         done
27453         wait
27454 }
27455 run_test 428 "large block size IO should not hang"
27456
27457 test_429() { # LU-7915 / LU-10948
27458         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27459         local testfile=$DIR/$tfile
27460         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27461         local new_flag=1
27462         local first_rpc
27463         local second_rpc
27464         local third_rpc
27465
27466         $LCTL get_param $ll_opencache_threshold_count ||
27467                 skip "client does not have opencache parameter"
27468
27469         set_opencache $new_flag
27470         stack_trap "restore_opencache"
27471         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27472                 error "enable opencache failed"
27473         touch $testfile
27474         # drop MDC DLM locks
27475         cancel_lru_locks mdc
27476         # clear MDC RPC stats counters
27477         $LCTL set_param $mdc_rpcstats=clear
27478
27479         # According to the current implementation, we need to run 3 times
27480         # open & close file to verify if opencache is enabled correctly.
27481         # 1st, RPCs are sent for lookup/open and open handle is released on
27482         #      close finally.
27483         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27484         #      so open handle won't be released thereafter.
27485         # 3rd, No RPC is sent out.
27486         $MULTIOP $testfile oc || error "multiop failed"
27487         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27488         echo "1st: $first_rpc RPCs in flight"
27489
27490         $MULTIOP $testfile oc || error "multiop failed"
27491         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27492         echo "2nd: $second_rpc RPCs in flight"
27493
27494         $MULTIOP $testfile oc || error "multiop failed"
27495         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
27496         echo "3rd: $third_rpc RPCs in flight"
27497
27498         #verify no MDC RPC is sent
27499         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
27500 }
27501 run_test 429 "verify if opencache flag on client side does work"
27502
27503 lseek_test_430() {
27504         local offset
27505         local file=$1
27506
27507         # data at [200K, 400K)
27508         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
27509                 error "256K->512K dd fails"
27510         # data at [2M, 3M)
27511         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
27512                 error "2M->3M dd fails"
27513         # data at [4M, 5M)
27514         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
27515                 error "4M->5M dd fails"
27516         echo "Data at 256K...512K, 2M...3M and 4M...5M"
27517         # start at first component hole #1
27518         printf "Seeking hole from 1000 ... "
27519         offset=$(lseek_test -l 1000 $file)
27520         echo $offset
27521         [[ $offset == 1000 ]] || error "offset $offset != 1000"
27522         printf "Seeking data from 1000 ... "
27523         offset=$(lseek_test -d 1000 $file)
27524         echo $offset
27525         [[ $offset == 262144 ]] || error "offset $offset != 262144"
27526
27527         # start at first component data block
27528         printf "Seeking hole from 300000 ... "
27529         offset=$(lseek_test -l 300000 $file)
27530         echo $offset
27531         [[ $offset == 524288 ]] || error "offset $offset != 524288"
27532         printf "Seeking data from 300000 ... "
27533         offset=$(lseek_test -d 300000 $file)
27534         echo $offset
27535         [[ $offset == 300000 ]] || error "offset $offset != 300000"
27536
27537         # start at the first component but beyond end of object size
27538         printf "Seeking hole from 1000000 ... "
27539         offset=$(lseek_test -l 1000000 $file)
27540         echo $offset
27541         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27542         printf "Seeking data from 1000000 ... "
27543         offset=$(lseek_test -d 1000000 $file)
27544         echo $offset
27545         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27546
27547         # start at second component stripe 2 (empty file)
27548         printf "Seeking hole from 1500000 ... "
27549         offset=$(lseek_test -l 1500000 $file)
27550         echo $offset
27551         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
27552         printf "Seeking data from 1500000 ... "
27553         offset=$(lseek_test -d 1500000 $file)
27554         echo $offset
27555         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
27556
27557         # start at second component stripe 1 (all data)
27558         printf "Seeking hole from 3000000 ... "
27559         offset=$(lseek_test -l 3000000 $file)
27560         echo $offset
27561         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
27562         printf "Seeking data from 3000000 ... "
27563         offset=$(lseek_test -d 3000000 $file)
27564         echo $offset
27565         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
27566
27567         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
27568                 error "2nd dd fails"
27569         echo "Add data block at 640K...1280K"
27570
27571         # start at before new data block, in hole
27572         printf "Seeking hole from 600000 ... "
27573         offset=$(lseek_test -l 600000 $file)
27574         echo $offset
27575         [[ $offset == 600000 ]] || error "offset $offset != 600000"
27576         printf "Seeking data from 600000 ... "
27577         offset=$(lseek_test -d 600000 $file)
27578         echo $offset
27579         [[ $offset == 655360 ]] || error "offset $offset != 655360"
27580
27581         # start at the first component new data block
27582         printf "Seeking hole from 1000000 ... "
27583         offset=$(lseek_test -l 1000000 $file)
27584         echo $offset
27585         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27586         printf "Seeking data from 1000000 ... "
27587         offset=$(lseek_test -d 1000000 $file)
27588         echo $offset
27589         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27590
27591         # start at second component stripe 2, new data
27592         printf "Seeking hole from 1200000 ... "
27593         offset=$(lseek_test -l 1200000 $file)
27594         echo $offset
27595         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
27596         printf "Seeking data from 1200000 ... "
27597         offset=$(lseek_test -d 1200000 $file)
27598         echo $offset
27599         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
27600
27601         # start beyond file end
27602         printf "Using offset > filesize ... "
27603         lseek_test -l 4000000 $file && error "lseek should fail"
27604         printf "Using offset > filesize ... "
27605         lseek_test -d 4000000 $file && error "lseek should fail"
27606
27607         printf "Done\n\n"
27608 }
27609
27610 test_430a() {
27611         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
27612                 skip "MDT does not support SEEK_HOLE"
27613
27614         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27615                 skip "OST does not support SEEK_HOLE"
27616
27617         local file=$DIR/$tdir/$tfile
27618
27619         mkdir -p $DIR/$tdir
27620
27621         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
27622         # OST stripe #1 will have continuous data at [1M, 3M)
27623         # OST stripe #2 is empty
27624         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
27625         lseek_test_430 $file
27626         rm $file
27627         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
27628         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
27629         lseek_test_430 $file
27630         rm $file
27631         $LFS setstripe -c2 -S 512K $file
27632         echo "Two stripes, stripe size 512K"
27633         lseek_test_430 $file
27634         rm $file
27635         # FLR with stale mirror
27636         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
27637                        -N -c2 -S 1M $file
27638         echo "Mirrored file:"
27639         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
27640         echo "Plain 2 stripes 1M"
27641         lseek_test_430 $file
27642         rm $file
27643 }
27644 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
27645
27646 test_430b() {
27647         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27648                 skip "OST does not support SEEK_HOLE"
27649
27650         local offset
27651         local file=$DIR/$tdir/$tfile
27652
27653         mkdir -p $DIR/$tdir
27654         # Empty layout lseek should fail
27655         $MCREATE $file
27656         # seek from 0
27657         printf "Seeking hole from 0 ... "
27658         lseek_test -l 0 $file && error "lseek should fail"
27659         printf "Seeking data from 0 ... "
27660         lseek_test -d 0 $file && error "lseek should fail"
27661         rm $file
27662
27663         # 1M-hole file
27664         $LFS setstripe -E 1M -c2 -E eof $file
27665         $TRUNCATE $file 1048576
27666         printf "Seeking hole from 1000000 ... "
27667         offset=$(lseek_test -l 1000000 $file)
27668         echo $offset
27669         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
27670         printf "Seeking data from 1000000 ... "
27671         lseek_test -d 1000000 $file && error "lseek should fail"
27672         rm $file
27673
27674         # full component followed by non-inited one
27675         $LFS setstripe -E 1M -c2 -E eof $file
27676         dd if=/dev/urandom of=$file bs=1M count=1
27677         printf "Seeking hole from 1000000 ... "
27678         offset=$(lseek_test -l 1000000 $file)
27679         echo $offset
27680         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27681         printf "Seeking hole from 1048576 ... "
27682         lseek_test -l 1048576 $file && error "lseek should fail"
27683         # init second component and truncate back
27684         echo "123" >> $file
27685         $TRUNCATE $file 1048576
27686         printf "Seeking hole from 1000000 ... "
27687         offset=$(lseek_test -l 1000000 $file)
27688         echo $offset
27689         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
27690         printf "Seeking hole from 1048576 ... "
27691         lseek_test -l 1048576 $file && error "lseek should fail"
27692         # boundary checks for big values
27693         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
27694         offset=$(lseek_test -d 0 $file.10g)
27695         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
27696         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
27697         offset=$(lseek_test -d 0 $file.100g)
27698         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
27699         return 0
27700 }
27701 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
27702
27703 test_430c() {
27704         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
27705                 skip "OST does not support SEEK_HOLE"
27706
27707         local file=$DIR/$tdir/$tfile
27708         local start
27709
27710         mkdir -p $DIR/$tdir
27711         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
27712
27713         # cp version 8.33+ prefers lseek over fiemap
27714         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
27715                 start=$SECONDS
27716                 time cp $file /dev/null
27717                 (( SECONDS - start < 5 )) ||
27718                         error "cp: too long runtime $((SECONDS - start))"
27719
27720         fi
27721         # tar version 1.29+ supports SEEK_HOLE/DATA
27722         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
27723                 start=$SECONDS
27724                 time tar cS $file - | cat > /dev/null
27725                 (( SECONDS - start < 5 )) ||
27726                         error "tar: too long runtime $((SECONDS - start))"
27727         fi
27728 }
27729 run_test 430c "lseek: external tools check"
27730
27731 test_431() { # LU-14187
27732         local file=$DIR/$tdir/$tfile
27733
27734         mkdir -p $DIR/$tdir
27735         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
27736         dd if=/dev/urandom of=$file bs=4k count=1
27737         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
27738         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
27739         #define OBD_FAIL_OST_RESTART_IO 0x251
27740         do_facet ost1 "$LCTL set_param fail_loc=0x251"
27741         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
27742         cp $file $file.0
27743         cancel_lru_locks
27744         sync_all_data
27745         echo 3 > /proc/sys/vm/drop_caches
27746         diff  $file $file.0 || error "data diff"
27747 }
27748 run_test 431 "Restart transaction for IO"
27749
27750 cleanup_test_432() {
27751         do_facet mgs $LCTL nodemap_activate 0
27752         wait_nm_sync active
27753 }
27754
27755 test_432() {
27756         local tmpdir=$TMP/dir432
27757
27758         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
27759                 skip "Need MDS version at least 2.14.52"
27760
27761         stack_trap cleanup_test_432 EXIT
27762         mkdir $DIR/$tdir
27763         mkdir $tmpdir
27764
27765         do_facet mgs $LCTL nodemap_activate 1
27766         wait_nm_sync active
27767         do_facet mgs $LCTL nodemap_modify --name default \
27768                 --property admin --value 1
27769         do_facet mgs $LCTL nodemap_modify --name default \
27770                 --property trusted --value 1
27771         cancel_lru_locks mdc
27772         wait_nm_sync default admin_nodemap
27773         wait_nm_sync default trusted_nodemap
27774
27775         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
27776                grep -ci "Operation not permitted") -ne 0 ]; then
27777                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
27778         fi
27779 }
27780 run_test 432 "mv dir from outside Lustre"
27781
27782 test_433() {
27783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27784
27785         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
27786                 skip "inode cache not supported"
27787
27788         $LCTL set_param llite.*.inode_cache=0
27789         stack_trap "$LCTL set_param llite.*.inode_cache=1"
27790
27791         local count=256
27792         local before
27793         local after
27794
27795         cancel_lru_locks mdc
27796         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27797         createmany -m $DIR/$tdir/f $count
27798         createmany -d $DIR/$tdir/d $count
27799         ls -l $DIR/$tdir > /dev/null
27800         stack_trap "rm -rf $DIR/$tdir"
27801
27802         before=$(num_objects)
27803         cancel_lru_locks mdc
27804         after=$(num_objects)
27805
27806         # sometimes even @before is less than 2 * count
27807         while (( before - after < count )); do
27808                 sleep 1
27809                 after=$(num_objects)
27810                 wait=$((wait + 1))
27811                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
27812                 if (( wait > 60 )); then
27813                         error "inode slab grew from $before to $after"
27814                 fi
27815         done
27816
27817         echo "lustre_inode_cache $before objs before lock cancel, $after after"
27818 }
27819 run_test 433 "ldlm lock cancel releases dentries and inodes"
27820
27821 test_434() {
27822         local file
27823         local getxattr_count
27824         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
27825         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27826
27827         [[ $(getenforce) == "Disabled" ]] ||
27828                 skip "lsm selinux module have to be disabled for this test"
27829
27830         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
27831                 error "fail to create $DIR/$tdir/ on MDT0000"
27832
27833         touch $DIR/$tdir/$tfile-{001..100}
27834
27835         # disable the xattr cache
27836         save_lustre_params client "llite.*.xattr_cache" > $p
27837         lctl set_param llite.*.xattr_cache=0
27838         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
27839
27840         # clear clients mdc stats
27841         clear_stats $mdc_stat_param ||
27842                 error "fail to clear stats on mdc MDT0000"
27843
27844         for file in $DIR/$tdir/$tfile-{001..100}; do
27845                 getfattr -n security.selinux $file |&
27846                         grep -q "Operation not supported" ||
27847                         error "getxattr on security.selinux should return EOPNOTSUPP"
27848         done
27849
27850         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
27851         (( getxattr_count < 100 )) ||
27852                 error "client sent $getxattr_count getxattr RPCs to the MDS"
27853 }
27854 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
27855
27856 test_440() {
27857         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
27858                 source $LUSTRE/scripts/bash-completion/lustre
27859         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
27860                 source /usr/share/bash-completion/completions/lustre
27861         else
27862                 skip "bash completion scripts not found"
27863         fi
27864
27865         local lctl_completions
27866         local lfs_completions
27867
27868         lctl_completions=$(_lustre_cmds lctl)
27869         if [[ ! $lctl_completions =~ "get_param" ]]; then
27870                 error "lctl bash completion failed"
27871         fi
27872
27873         lfs_completions=$(_lustre_cmds lfs)
27874         if [[ ! $lfs_completions =~ "setstripe" ]]; then
27875                 error "lfs bash completion failed"
27876         fi
27877 }
27878 run_test 440 "bash completion for lfs, lctl"
27879
27880 prep_801() {
27881         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
27882         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
27883                 skip "Need server version at least 2.9.55"
27884
27885         start_full_debug_logging
27886 }
27887
27888 post_801() {
27889         stop_full_debug_logging
27890 }
27891
27892 barrier_stat() {
27893         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27894                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27895                            awk '/The barrier for/ { print $7 }')
27896                 echo $st
27897         else
27898                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
27899                 echo \'$st\'
27900         fi
27901 }
27902
27903 barrier_expired() {
27904         local expired
27905
27906         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
27907                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
27908                           awk '/will be expired/ { print $7 }')
27909         else
27910                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
27911         fi
27912
27913         echo $expired
27914 }
27915
27916 test_801a() {
27917         prep_801
27918
27919         echo "Start barrier_freeze at: $(date)"
27920         #define OBD_FAIL_BARRIER_DELAY          0x2202
27921         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27922         # Do not reduce barrier time - See LU-11873
27923         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
27924
27925         sleep 2
27926         local b_status=$(barrier_stat)
27927         echo "Got barrier status at: $(date)"
27928         [ "$b_status" = "'freezing_p1'" ] ||
27929                 error "(1) unexpected barrier status $b_status"
27930
27931         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27932         wait
27933         b_status=$(barrier_stat)
27934         [ "$b_status" = "'frozen'" ] ||
27935                 error "(2) unexpected barrier status $b_status"
27936
27937         local expired=$(barrier_expired)
27938         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
27939         sleep $((expired + 3))
27940
27941         b_status=$(barrier_stat)
27942         [ "$b_status" = "'expired'" ] ||
27943                 error "(3) unexpected barrier status $b_status"
27944
27945         # Do not reduce barrier time - See LU-11873
27946         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
27947                 error "(4) fail to freeze barrier"
27948
27949         b_status=$(barrier_stat)
27950         [ "$b_status" = "'frozen'" ] ||
27951                 error "(5) unexpected barrier status $b_status"
27952
27953         echo "Start barrier_thaw at: $(date)"
27954         #define OBD_FAIL_BARRIER_DELAY          0x2202
27955         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
27956         do_facet mgs $LCTL barrier_thaw $FSNAME &
27957
27958         sleep 2
27959         b_status=$(barrier_stat)
27960         echo "Got barrier status at: $(date)"
27961         [ "$b_status" = "'thawing'" ] ||
27962                 error "(6) unexpected barrier status $b_status"
27963
27964         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
27965         wait
27966         b_status=$(barrier_stat)
27967         [ "$b_status" = "'thawed'" ] ||
27968                 error "(7) unexpected barrier status $b_status"
27969
27970         #define OBD_FAIL_BARRIER_FAILURE        0x2203
27971         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
27972         do_facet mgs $LCTL barrier_freeze $FSNAME
27973
27974         b_status=$(barrier_stat)
27975         [ "$b_status" = "'failed'" ] ||
27976                 error "(8) unexpected barrier status $b_status"
27977
27978         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
27979         do_facet mgs $LCTL barrier_thaw $FSNAME
27980
27981         post_801
27982 }
27983 run_test 801a "write barrier user interfaces and stat machine"
27984
27985 test_801b() {
27986         prep_801
27987
27988         mkdir $DIR/$tdir || error "(1) fail to mkdir"
27989         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
27990         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
27991         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
27992         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
27993
27994         cancel_lru_locks mdc
27995
27996         # 180 seconds should be long enough
27997         do_facet mgs $LCTL barrier_freeze $FSNAME 180
27998
27999         local b_status=$(barrier_stat)
28000         [ "$b_status" = "'frozen'" ] ||
28001                 error "(6) unexpected barrier status $b_status"
28002
28003         mkdir $DIR/$tdir/d0/d10 &
28004         mkdir_pid=$!
28005
28006         touch $DIR/$tdir/d1/f13 &
28007         touch_pid=$!
28008
28009         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28010         ln_pid=$!
28011
28012         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28013         mv_pid=$!
28014
28015         rm -f $DIR/$tdir/d4/f12 &
28016         rm_pid=$!
28017
28018         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28019
28020         # To guarantee taht the 'stat' is not blocked
28021         b_status=$(barrier_stat)
28022         [ "$b_status" = "'frozen'" ] ||
28023                 error "(8) unexpected barrier status $b_status"
28024
28025         # let above commands to run at background
28026         sleep 5
28027
28028         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28029         ps -p $touch_pid || error "(10) touch should be blocked"
28030         ps -p $ln_pid || error "(11) link should be blocked"
28031         ps -p $mv_pid || error "(12) rename should be blocked"
28032         ps -p $rm_pid || error "(13) unlink should be blocked"
28033
28034         b_status=$(barrier_stat)
28035         [ "$b_status" = "'frozen'" ] ||
28036                 error "(14) unexpected barrier status $b_status"
28037
28038         do_facet mgs $LCTL barrier_thaw $FSNAME
28039         b_status=$(barrier_stat)
28040         [ "$b_status" = "'thawed'" ] ||
28041                 error "(15) unexpected barrier status $b_status"
28042
28043         wait $mkdir_pid || error "(16) mkdir should succeed"
28044         wait $touch_pid || error "(17) touch should succeed"
28045         wait $ln_pid || error "(18) link should succeed"
28046         wait $mv_pid || error "(19) rename should succeed"
28047         wait $rm_pid || error "(20) unlink should succeed"
28048
28049         post_801
28050 }
28051 run_test 801b "modification will be blocked by write barrier"
28052
28053 test_801c() {
28054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28055
28056         prep_801
28057
28058         stop mds2 || error "(1) Fail to stop mds2"
28059
28060         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28061
28062         local b_status=$(barrier_stat)
28063         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28064                 do_facet mgs $LCTL barrier_thaw $FSNAME
28065                 error "(2) unexpected barrier status $b_status"
28066         }
28067
28068         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28069                 error "(3) Fail to rescan barrier bitmap"
28070
28071         # Do not reduce barrier time - See LU-11873
28072         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28073
28074         b_status=$(barrier_stat)
28075         [ "$b_status" = "'frozen'" ] ||
28076                 error "(4) unexpected barrier status $b_status"
28077
28078         do_facet mgs $LCTL barrier_thaw $FSNAME
28079         b_status=$(barrier_stat)
28080         [ "$b_status" = "'thawed'" ] ||
28081                 error "(5) unexpected barrier status $b_status"
28082
28083         local devname=$(mdsdevname 2)
28084
28085         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28086
28087         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28088                 error "(7) Fail to rescan barrier bitmap"
28089
28090         post_801
28091 }
28092 run_test 801c "rescan barrier bitmap"
28093
28094 test_802b() {
28095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28096         remote_mds_nodsh && skip "remote MDS with nodsh"
28097
28098         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28099                 skip "readonly option not available"
28100
28101         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28102
28103         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28104                 error "(2) Fail to copy"
28105
28106         # write back all cached data before setting MDT to readonly
28107         cancel_lru_locks
28108         sync_all_data
28109
28110         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28111         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28112
28113         echo "Modify should be refused"
28114         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28115
28116         echo "Read should be allowed"
28117         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28118                 error "(7) Read should succeed under ro mode"
28119
28120         # disable readonly
28121         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28122 }
28123 run_test 802b "be able to set MDTs to readonly"
28124
28125 test_803a() {
28126         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28127         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28128                 skip "MDS needs to be newer than 2.10.54"
28129
28130         mkdir_on_mdt0 $DIR/$tdir
28131         # Create some objects on all MDTs to trigger related logs objects
28132         for idx in $(seq $MDSCOUNT); do
28133                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28134                         $DIR/$tdir/dir${idx} ||
28135                         error "Fail to create $DIR/$tdir/dir${idx}"
28136         done
28137
28138         wait_delete_completed # ensure old test cleanups are finished
28139         sleep 3
28140         echo "before create:"
28141         $LFS df -i $MOUNT
28142         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28143
28144         for i in {1..10}; do
28145                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28146                         error "Fail to create $DIR/$tdir/foo$i"
28147         done
28148
28149         # sync ZFS-on-MDS to refresh statfs data
28150         wait_zfs_commit mds1
28151         sleep 3
28152         echo "after create:"
28153         $LFS df -i $MOUNT
28154         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28155
28156         # allow for an llog to be cleaned up during the test
28157         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28158                 error "before ($before_used) + 10 > after ($after_used)"
28159
28160         for i in {1..10}; do
28161                 rm -rf $DIR/$tdir/foo$i ||
28162                         error "Fail to remove $DIR/$tdir/foo$i"
28163         done
28164
28165         # sync ZFS-on-MDS to refresh statfs data
28166         wait_zfs_commit mds1
28167         wait_delete_completed
28168         sleep 3 # avoid MDT return cached statfs
28169         echo "after unlink:"
28170         $LFS df -i $MOUNT
28171         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28172
28173         # allow for an llog to be created during the test
28174         [ $after_used -le $((before_used + 1)) ] ||
28175                 error "after ($after_used) > before ($before_used) + 1"
28176 }
28177 run_test 803a "verify agent object for remote object"
28178
28179 test_803b() {
28180         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28181         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28182                 skip "MDS needs to be newer than 2.13.56"
28183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28184
28185         for i in $(seq 0 $((MDSCOUNT - 1))); do
28186                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28187         done
28188
28189         local before=0
28190         local after=0
28191
28192         local tmp
28193
28194         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28195         for i in $(seq 0 $((MDSCOUNT - 1))); do
28196                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28197                         awk '/getattr/ { print $2 }')
28198                 before=$((before + tmp))
28199         done
28200         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28201         for i in $(seq 0 $((MDSCOUNT - 1))); do
28202                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28203                         awk '/getattr/ { print $2 }')
28204                 after=$((after + tmp))
28205         done
28206
28207         [ $before -eq $after ] || error "getattr count $before != $after"
28208 }
28209 run_test 803b "remote object can getattr from cache"
28210
28211 test_804() {
28212         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28213         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28214                 skip "MDS needs to be newer than 2.10.54"
28215         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28216
28217         mkdir -p $DIR/$tdir
28218         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28219                 error "Fail to create $DIR/$tdir/dir0"
28220
28221         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28222         local dev=$(mdsdevname 2)
28223
28224         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28225                 grep ${fid} || error "NOT found agent entry for dir0"
28226
28227         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28228                 error "Fail to create $DIR/$tdir/dir1"
28229
28230         touch $DIR/$tdir/dir1/foo0 ||
28231                 error "Fail to create $DIR/$tdir/dir1/foo0"
28232         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28233         local rc=0
28234
28235         for idx in $(seq $MDSCOUNT); do
28236                 dev=$(mdsdevname $idx)
28237                 do_facet mds${idx} \
28238                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28239                         grep ${fid} && rc=$idx
28240         done
28241
28242         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28243                 error "Fail to rename foo0 to foo1"
28244         if [ $rc -eq 0 ]; then
28245                 for idx in $(seq $MDSCOUNT); do
28246                         dev=$(mdsdevname $idx)
28247                         do_facet mds${idx} \
28248                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28249                         grep ${fid} && rc=$idx
28250                 done
28251         fi
28252
28253         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28254                 error "Fail to rename foo1 to foo2"
28255         if [ $rc -eq 0 ]; then
28256                 for idx in $(seq $MDSCOUNT); do
28257                         dev=$(mdsdevname $idx)
28258                         do_facet mds${idx} \
28259                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28260                         grep ${fid} && rc=$idx
28261                 done
28262         fi
28263
28264         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28265
28266         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28267                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28268         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28269                 error "Fail to rename foo2 to foo0"
28270         unlink $DIR/$tdir/dir1/foo0 ||
28271                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28272         rm -rf $DIR/$tdir/dir0 ||
28273                 error "Fail to rm $DIR/$tdir/dir0"
28274
28275         for idx in $(seq $MDSCOUNT); do
28276                 rc=0
28277
28278                 stop mds${idx}
28279                 dev=$(mdsdevname $idx)
28280                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28281                         rc=$?
28282                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28283                         error "mount mds$idx failed"
28284                 df $MOUNT > /dev/null 2>&1
28285
28286                 # e2fsck should not return error
28287                 [ $rc -eq 0 ] ||
28288                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28289         done
28290 }
28291 run_test 804 "verify agent entry for remote entry"
28292
28293 cleanup_805() {
28294         do_facet $SINGLEMDS zfs set quota=$old $fsset
28295         unlinkmany $DIR/$tdir/f- 1000000
28296         trap 0
28297 }
28298
28299 test_805() {
28300         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28301         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28302         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28303                 skip "netfree not implemented before 0.7"
28304         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28305                 skip "Need MDS version at least 2.10.57"
28306
28307         local fsset
28308         local freekb
28309         local usedkb
28310         local old
28311         local quota
28312         local pref="osd-zfs.$FSNAME-MDT0000."
28313
28314         # limit available space on MDS dataset to meet nospace issue
28315         # quickly. then ZFS 0.7.2 can use reserved space if asked
28316         # properly (using netfree flag in osd_declare_destroy()
28317         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28318         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28319                 gawk '{print $3}')
28320         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28321         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28322         let "usedkb=usedkb-freekb"
28323         let "freekb=freekb/2"
28324         if let "freekb > 5000"; then
28325                 let "freekb=5000"
28326         fi
28327         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28328         trap cleanup_805 EXIT
28329         mkdir_on_mdt0 $DIR/$tdir
28330         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28331                 error "Can't set PFL layout"
28332         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28333         rm -rf $DIR/$tdir || error "not able to remove"
28334         do_facet $SINGLEMDS zfs set quota=$old $fsset
28335         trap 0
28336 }
28337 run_test 805 "ZFS can remove from full fs"
28338
28339 # Size-on-MDS test
28340 check_lsom_data()
28341 {
28342         local file=$1
28343         local expect=$(stat -c %s $file)
28344
28345         check_lsom_size $1 $expect
28346
28347         local blocks=$($LFS getsom -b $file)
28348         expect=$(stat -c %b $file)
28349         [[ $blocks == $expect ]] ||
28350                 error "$file expected blocks: $expect, got: $blocks"
28351 }
28352
28353 check_lsom_size()
28354 {
28355         local size
28356         local expect=$2
28357
28358         cancel_lru_locks mdc
28359
28360         size=$($LFS getsom -s $1)
28361         [[ $size == $expect ]] ||
28362                 error "$file expected size: $expect, got: $size"
28363 }
28364
28365 test_806() {
28366         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28367                 skip "Need MDS version at least 2.11.52"
28368
28369         local bs=1048576
28370
28371         touch $DIR/$tfile || error "touch $tfile failed"
28372
28373         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28374         save_lustre_params client "llite.*.xattr_cache" > $save
28375         lctl set_param llite.*.xattr_cache=0
28376         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28377
28378         # single-threaded write
28379         echo "Test SOM for single-threaded write"
28380         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28381                 error "write $tfile failed"
28382         check_lsom_size $DIR/$tfile $bs
28383
28384         local num=32
28385         local size=$(($num * $bs))
28386         local offset=0
28387         local i
28388
28389         echo "Test SOM for single client multi-threaded($num) write"
28390         $TRUNCATE $DIR/$tfile 0
28391         for ((i = 0; i < $num; i++)); do
28392                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28393                 local pids[$i]=$!
28394                 offset=$((offset + $bs))
28395         done
28396         for (( i=0; i < $num; i++ )); do
28397                 wait ${pids[$i]}
28398         done
28399         check_lsom_size $DIR/$tfile $size
28400
28401         $TRUNCATE $DIR/$tfile 0
28402         for ((i = 0; i < $num; i++)); do
28403                 offset=$((offset - $bs))
28404                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28405                 local pids[$i]=$!
28406         done
28407         for (( i=0; i < $num; i++ )); do
28408                 wait ${pids[$i]}
28409         done
28410         check_lsom_size $DIR/$tfile $size
28411
28412         # multi-client writes
28413         num=$(get_node_count ${CLIENTS//,/ })
28414         size=$(($num * $bs))
28415         offset=0
28416         i=0
28417
28418         echo "Test SOM for multi-client ($num) writes"
28419         $TRUNCATE $DIR/$tfile 0
28420         for client in ${CLIENTS//,/ }; do
28421                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28422                 local pids[$i]=$!
28423                 i=$((i + 1))
28424                 offset=$((offset + $bs))
28425         done
28426         for (( i=0; i < $num; i++ )); do
28427                 wait ${pids[$i]}
28428         done
28429         check_lsom_size $DIR/$tfile $offset
28430
28431         i=0
28432         $TRUNCATE $DIR/$tfile 0
28433         for client in ${CLIENTS//,/ }; do
28434                 offset=$((offset - $bs))
28435                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28436                 local pids[$i]=$!
28437                 i=$((i + 1))
28438         done
28439         for (( i=0; i < $num; i++ )); do
28440                 wait ${pids[$i]}
28441         done
28442         check_lsom_size $DIR/$tfile $size
28443
28444         # verify truncate
28445         echo "Test SOM for truncate"
28446         $TRUNCATE $DIR/$tfile 1048576
28447         check_lsom_size $DIR/$tfile 1048576
28448         $TRUNCATE $DIR/$tfile 1234
28449         check_lsom_size $DIR/$tfile 1234
28450
28451         # verify SOM blocks count
28452         echo "Verify SOM block count"
28453         $TRUNCATE $DIR/$tfile 0
28454         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
28455                 error "failed to write file $tfile"
28456         check_lsom_data $DIR/$tfile
28457 }
28458 run_test 806 "Verify Lazy Size on MDS"
28459
28460 test_807() {
28461         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28462         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28463                 skip "Need MDS version at least 2.11.52"
28464
28465         # Registration step
28466         changelog_register || error "changelog_register failed"
28467         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
28468         changelog_users $SINGLEMDS | grep -q $cl_user ||
28469                 error "User $cl_user not found in changelog_users"
28470
28471         rm -rf $DIR/$tdir || error "rm $tdir failed"
28472         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
28473         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
28474         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
28475         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
28476                 error "truncate $tdir/trunc failed"
28477
28478         local bs=1048576
28479         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
28480                 error "write $tfile failed"
28481
28482         # multi-client wirtes
28483         local num=$(get_node_count ${CLIENTS//,/ })
28484         local offset=0
28485         local i=0
28486
28487         echo "Test SOM for multi-client ($num) writes"
28488         touch $DIR/$tfile || error "touch $tfile failed"
28489         $TRUNCATE $DIR/$tfile 0
28490         for client in ${CLIENTS//,/ }; do
28491                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28492                 local pids[$i]=$!
28493                 i=$((i + 1))
28494                 offset=$((offset + $bs))
28495         done
28496         for (( i=0; i < $num; i++ )); do
28497                 wait ${pids[$i]}
28498         done
28499
28500         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
28501         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
28502         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
28503         check_lsom_data $DIR/$tdir/trunc
28504         check_lsom_data $DIR/$tdir/single_dd
28505         check_lsom_data $DIR/$tfile
28506
28507         rm -rf $DIR/$tdir
28508         # Deregistration step
28509         changelog_deregister || error "changelog_deregister failed"
28510 }
28511 run_test 807 "verify LSOM syncing tool"
28512
28513 check_som_nologged()
28514 {
28515         local lines=$($LFS changelog $FSNAME-MDT0000 |
28516                 grep 'x=trusted.som' | wc -l)
28517         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
28518 }
28519
28520 test_808() {
28521         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28522                 skip "Need MDS version at least 2.11.55"
28523
28524         # Registration step
28525         changelog_register || error "changelog_register failed"
28526
28527         touch $DIR/$tfile || error "touch $tfile failed"
28528         check_som_nologged
28529
28530         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
28531                 error "write $tfile failed"
28532         check_som_nologged
28533
28534         $TRUNCATE $DIR/$tfile 1234
28535         check_som_nologged
28536
28537         $TRUNCATE $DIR/$tfile 1048576
28538         check_som_nologged
28539
28540         # Deregistration step
28541         changelog_deregister || error "changelog_deregister failed"
28542 }
28543 run_test 808 "Check trusted.som xattr not logged in Changelogs"
28544
28545 check_som_nodata()
28546 {
28547         $LFS getsom $1
28548         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
28549 }
28550
28551 test_809() {
28552         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
28553                 skip "Need MDS version at least 2.11.56"
28554
28555         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
28556                 error "failed to create DoM-only file $DIR/$tfile"
28557         touch $DIR/$tfile || error "touch $tfile failed"
28558         check_som_nodata $DIR/$tfile
28559
28560         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
28561                 error "write $tfile failed"
28562         check_som_nodata $DIR/$tfile
28563
28564         $TRUNCATE $DIR/$tfile 1234
28565         check_som_nodata $DIR/$tfile
28566
28567         $TRUNCATE $DIR/$tfile 4097
28568         check_som_nodata $DIR/$file
28569 }
28570 run_test 809 "Verify no SOM xattr store for DoM-only files"
28571
28572 test_810() {
28573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28574         $GSS && skip_env "could not run with gss"
28575         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
28576                 skip "OST < 2.12.58 doesn't align checksum"
28577
28578         set_checksums 1
28579         stack_trap "set_checksums $ORIG_CSUM" EXIT
28580         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
28581
28582         local csum
28583         local before
28584         local after
28585         for csum in $CKSUM_TYPES; do
28586                 #define OBD_FAIL_OSC_NO_GRANT   0x411
28587                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
28588                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
28589                         eval set -- $i
28590                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
28591                         before=$(md5sum $DIR/$tfile)
28592                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
28593                         after=$(md5sum $DIR/$tfile)
28594                         [ "$before" == "$after" ] ||
28595                                 error "$csum: $before != $after bs=$1 seek=$2"
28596                 done
28597         done
28598 }
28599 run_test 810 "partial page writes on ZFS (LU-11663)"
28600
28601 test_812a() {
28602         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28603                 skip "OST < 2.12.51 doesn't support this fail_loc"
28604
28605         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28606         # ensure ost1 is connected
28607         stat $DIR/$tfile >/dev/null || error "can't stat"
28608         wait_osc_import_state client ost1 FULL
28609         # no locks, no reqs to let the connection idle
28610         cancel_lru_locks osc
28611
28612         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28613 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28614         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28615         wait_osc_import_state client ost1 CONNECTING
28616         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28617
28618         stat $DIR/$tfile >/dev/null || error "can't stat file"
28619 }
28620 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
28621
28622 test_812b() { # LU-12378
28623         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
28624                 skip "OST < 2.12.51 doesn't support this fail_loc"
28625
28626         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
28627         # ensure ost1 is connected
28628         stat $DIR/$tfile >/dev/null || error "can't stat"
28629         wait_osc_import_state client ost1 FULL
28630         # no locks, no reqs to let the connection idle
28631         cancel_lru_locks osc
28632
28633         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
28634 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
28635         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
28636         wait_osc_import_state client ost1 CONNECTING
28637         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
28638
28639         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
28640         wait_osc_import_state client ost1 IDLE
28641 }
28642 run_test 812b "do not drop no resend request for idle connect"
28643
28644 test_812c() {
28645         local old
28646
28647         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
28648
28649         $LFS setstripe -c 1 -o 0 $DIR/$tfile
28650         $LFS getstripe $DIR/$tfile
28651         $LCTL set_param osc.*.idle_timeout=10
28652         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
28653         # ensure ost1 is connected
28654         stat $DIR/$tfile >/dev/null || error "can't stat"
28655         wait_osc_import_state client ost1 FULL
28656         # no locks, no reqs to let the connection idle
28657         cancel_lru_locks osc
28658
28659 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
28660         $LCTL set_param fail_loc=0x80000533
28661         sleep 15
28662         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
28663 }
28664 run_test 812c "idle import vs lock enqueue race"
28665
28666 test_813() {
28667         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
28668         [ -z "$file_heat_sav" ] && skip "no file heat support"
28669
28670         local readsample
28671         local writesample
28672         local readbyte
28673         local writebyte
28674         local readsample1
28675         local writesample1
28676         local readbyte1
28677         local writebyte1
28678
28679         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
28680         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
28681
28682         $LCTL set_param -n llite.*.file_heat=1
28683         echo "Turn on file heat"
28684         echo "Period second: $period_second, Decay percentage: $decay_pct"
28685
28686         echo "QQQQ" > $DIR/$tfile
28687         echo "QQQQ" > $DIR/$tfile
28688         echo "QQQQ" > $DIR/$tfile
28689         cat $DIR/$tfile > /dev/null
28690         cat $DIR/$tfile > /dev/null
28691         cat $DIR/$tfile > /dev/null
28692         cat $DIR/$tfile > /dev/null
28693
28694         local out=$($LFS heat_get $DIR/$tfile)
28695
28696         $LFS heat_get $DIR/$tfile
28697         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28698         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28699         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28700         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28701
28702         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
28703         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
28704         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
28705         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
28706
28707         sleep $((period_second + 3))
28708         echo "Sleep $((period_second + 3)) seconds..."
28709         # The recursion formula to calculate the heat of the file f is as
28710         # follow:
28711         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
28712         # Where Hi is the heat value in the period between time points i*I and
28713         # (i+1)*I; Ci is the access count in the period; the symbol P refers
28714         # to the weight of Ci.
28715         out=$($LFS heat_get $DIR/$tfile)
28716         $LFS heat_get $DIR/$tfile
28717         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28718         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28719         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28720         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28721
28722         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
28723                 error "read sample ($readsample) is wrong"
28724         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
28725                 error "write sample ($writesample) is wrong"
28726         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
28727                 error "read bytes ($readbyte) is wrong"
28728         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
28729                 error "write bytes ($writebyte) is wrong"
28730
28731         echo "QQQQ" > $DIR/$tfile
28732         echo "QQQQ" > $DIR/$tfile
28733         echo "QQQQ" > $DIR/$tfile
28734         cat $DIR/$tfile > /dev/null
28735         cat $DIR/$tfile > /dev/null
28736         cat $DIR/$tfile > /dev/null
28737         cat $DIR/$tfile > /dev/null
28738
28739         sleep $((period_second + 3))
28740         echo "Sleep $((period_second + 3)) seconds..."
28741
28742         out=$($LFS heat_get $DIR/$tfile)
28743         $LFS heat_get $DIR/$tfile
28744         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28745         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28746         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28747         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28748
28749         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
28750                 4 * $decay_pct) / 100") -eq 1 ] ||
28751                 error "read sample ($readsample1) is wrong"
28752         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
28753                 3 * $decay_pct) / 100") -eq 1 ] ||
28754                 error "write sample ($writesample1) is wrong"
28755         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
28756                 20 * $decay_pct) / 100") -eq 1 ] ||
28757                 error "read bytes ($readbyte1) is wrong"
28758         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
28759                 15 * $decay_pct) / 100") -eq 1 ] ||
28760                 error "write bytes ($writebyte1) is wrong"
28761
28762         echo "Turn off file heat for the file $DIR/$tfile"
28763         $LFS heat_set -o $DIR/$tfile
28764
28765         echo "QQQQ" > $DIR/$tfile
28766         echo "QQQQ" > $DIR/$tfile
28767         echo "QQQQ" > $DIR/$tfile
28768         cat $DIR/$tfile > /dev/null
28769         cat $DIR/$tfile > /dev/null
28770         cat $DIR/$tfile > /dev/null
28771         cat $DIR/$tfile > /dev/null
28772
28773         out=$($LFS heat_get $DIR/$tfile)
28774         $LFS heat_get $DIR/$tfile
28775         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28776         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28777         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28778         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28779
28780         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28781         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28782         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28783         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28784
28785         echo "Trun on file heat for the file $DIR/$tfile"
28786         $LFS heat_set -O $DIR/$tfile
28787
28788         echo "QQQQ" > $DIR/$tfile
28789         echo "QQQQ" > $DIR/$tfile
28790         echo "QQQQ" > $DIR/$tfile
28791         cat $DIR/$tfile > /dev/null
28792         cat $DIR/$tfile > /dev/null
28793         cat $DIR/$tfile > /dev/null
28794         cat $DIR/$tfile > /dev/null
28795
28796         out=$($LFS heat_get $DIR/$tfile)
28797         $LFS heat_get $DIR/$tfile
28798         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28799         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28800         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28801         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28802
28803         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
28804         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
28805         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
28806         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
28807
28808         $LFS heat_set -c $DIR/$tfile
28809         $LCTL set_param -n llite.*.file_heat=0
28810         echo "Turn off file heat support for the Lustre filesystem"
28811
28812         echo "QQQQ" > $DIR/$tfile
28813         echo "QQQQ" > $DIR/$tfile
28814         echo "QQQQ" > $DIR/$tfile
28815         cat $DIR/$tfile > /dev/null
28816         cat $DIR/$tfile > /dev/null
28817         cat $DIR/$tfile > /dev/null
28818         cat $DIR/$tfile > /dev/null
28819
28820         out=$($LFS heat_get $DIR/$tfile)
28821         $LFS heat_get $DIR/$tfile
28822         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
28823         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
28824         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
28825         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
28826
28827         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
28828         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
28829         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
28830         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
28831
28832         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
28833         rm -f $DIR/$tfile
28834 }
28835 run_test 813 "File heat verfication"
28836
28837 test_814()
28838 {
28839         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
28840         echo -n y >> $DIR/$tfile
28841         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
28842         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
28843 }
28844 run_test 814 "sparse cp works as expected (LU-12361)"
28845
28846 test_815()
28847 {
28848         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
28849         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
28850 }
28851 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
28852
28853 test_816() {
28854         local ost1_imp=$(get_osc_import_name client ost1)
28855         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
28856                          cut -d'.' -f2)
28857
28858         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28859         # ensure ost1 is connected
28860
28861         stat $DIR/$tfile >/dev/null || error "can't stat"
28862         wait_osc_import_state client ost1 FULL
28863         # no locks, no reqs to let the connection idle
28864         cancel_lru_locks osc
28865         lru_resize_disable osc
28866         local before
28867         local now
28868         before=$($LCTL get_param -n \
28869                  ldlm.namespaces.$imp_name.lru_size)
28870
28871         wait_osc_import_state client ost1 IDLE
28872         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
28873         now=$($LCTL get_param -n \
28874               ldlm.namespaces.$imp_name.lru_size)
28875         [ $before == $now ] || error "lru_size changed $before != $now"
28876 }
28877 run_test 816 "do not reset lru_resize on idle reconnect"
28878
28879 cleanup_817() {
28880         umount $tmpdir
28881         exportfs -u localhost:$DIR/nfsexp
28882         rm -rf $DIR/nfsexp
28883 }
28884
28885 test_817() {
28886         systemctl restart nfs-server.service || skip "failed to restart nfsd"
28887
28888         mkdir -p $DIR/nfsexp
28889         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
28890                 error "failed to export nfs"
28891
28892         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
28893         stack_trap cleanup_817 EXIT
28894
28895         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
28896                 error "failed to mount nfs to $tmpdir"
28897
28898         cp /bin/true $tmpdir
28899         $DIR/nfsexp/true || error "failed to execute 'true' command"
28900 }
28901 run_test 817 "nfsd won't cache write lock for exec file"
28902
28903 test_818() {
28904         test_mkdir -i0 -c1 $DIR/$tdir
28905         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
28906         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
28907         stop $SINGLEMDS
28908
28909         # restore osp-syn threads
28910         stack_trap "fail $SINGLEMDS"
28911
28912         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
28913         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
28914         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
28915                 error "start $SINGLEMDS failed"
28916         rm -rf $DIR/$tdir
28917
28918         local testid=$(echo $TESTNAME | tr '_' ' ')
28919
28920         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
28921                 grep "run LFSCK" || error "run LFSCK is not suggested"
28922 }
28923 run_test 818 "unlink with failed llog"
28924
28925 test_819a() {
28926         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28927         cancel_lru_locks osc
28928         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28929         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28930         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
28931         rm -f $TDIR/$tfile
28932 }
28933 run_test 819a "too big niobuf in read"
28934
28935 test_819b() {
28936         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
28937         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
28938         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
28939         cancel_lru_locks osc
28940         sleep 1
28941         rm -f $TDIR/$tfile
28942 }
28943 run_test 819b "too big niobuf in write"
28944
28945
28946 function test_820_start_ost() {
28947         sleep 5
28948
28949         for num in $(seq $OSTCOUNT); do
28950                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
28951         done
28952 }
28953
28954 test_820() {
28955         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28956
28957         mkdir $DIR/$tdir
28958         umount_client $MOUNT || error "umount failed"
28959         for num in $(seq $OSTCOUNT); do
28960                 stop ost$num
28961         done
28962
28963         # mount client with no active OSTs
28964         # so that the client can't initialize max LOV EA size
28965         # from OSC notifications
28966         mount_client $MOUNT || error "mount failed"
28967         # delay OST starting to keep this 0 max EA size for a while
28968         test_820_start_ost &
28969
28970         # create a directory on MDS2
28971         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
28972                 error "Failed to create directory"
28973         # open intent should update default EA size
28974         # see mdc_update_max_ea_from_body()
28975         # notice this is the very first RPC to MDS2
28976         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
28977         ret=$?
28978         echo $out
28979         # With SSK, this situation can lead to -EPERM being returned.
28980         # In that case, simply retry.
28981         if [ $ret -ne 0 ] && $SHARED_KEY; then
28982                 if echo "$out" | grep -q "not permitted"; then
28983                         cp /etc/services $DIR/$tdir/mds2
28984                         ret=$?
28985                 fi
28986         fi
28987         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
28988 }
28989 run_test 820 "update max EA from open intent"
28990
28991 test_823() {
28992         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28993         local OST_MAX_PRECREATE=20000
28994
28995         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
28996                 skip "Need MDS version at least 2.14.56"
28997
28998         save_lustre_params mds1 \
28999                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29000         do_facet $SINGLEMDS "$LCTL set_param -n \
29001                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29002         do_facet $SINGLEMDS "$LCTL set_param -n \
29003                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29004
29005         stack_trap "restore_lustre_params < $p; rm $p"
29006
29007         do_facet $SINGLEMDS "$LCTL set_param -n \
29008                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29009
29010         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29011                       osp.$FSNAME-OST0000*MDT0000.create_count")
29012         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29013                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29014         local expect_count=$(((($max/2)/256) * 256))
29015
29016         log "setting create_count to 100200:"
29017         log " -result- count: $count with max: $max, expecting: $expect_count"
29018
29019         [[ $count -eq expect_count ]] ||
29020                 error "Create count not set to max precreate."
29021 }
29022 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29023
29024 test_831() {
29025         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29026                 skip "Need MDS version 2.14.56"
29027
29028         local sync_changes=$(do_facet $SINGLEMDS \
29029                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29030
29031         [ "$sync_changes" -gt 100 ] &&
29032                 skip "Sync changes $sync_changes > 100 already"
29033
29034         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29035
29036         $LFS mkdir -i 0 $DIR/$tdir
29037         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29038
29039         save_lustre_params mds1 \
29040                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29041         save_lustre_params mds1 \
29042                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29043
29044         do_facet mds1 "$LCTL set_param -n \
29045                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29046                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29047         stack_trap "restore_lustre_params < $p" EXIT
29048
29049         createmany -o $DIR/$tdir/f- 1000
29050         unlinkmany $DIR/$tdir/f- 1000 &
29051         local UNLINK_PID=$!
29052
29053         while sleep 1; do
29054                 sync_changes=$(do_facet mds1 \
29055                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29056                 # the check in the code is racy, fail the test
29057                 # if the value above the limit by 10.
29058                 [ $sync_changes -gt 110 ] && {
29059                         kill -2 $UNLINK_PID
29060                         wait
29061                         error "osp changes throttling failed, $sync_changes>110"
29062                 }
29063                 kill -0 $UNLINK_PID 2> /dev/null || break
29064         done
29065         wait
29066 }
29067 run_test 831 "throttling unlink/setattr queuing on OSP"
29068
29069 test_832() {
29070         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29071         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29072                 skip "Need MDS version 2.15.52+"
29073         is_rmentry_supported || skip "rm_entry not supported"
29074
29075         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29076         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29077         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29078                 error "mkdir remote_dir failed"
29079         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29080                 error "mkdir striped_dir failed"
29081         touch $DIR/$tdir/file || error "touch file failed"
29082         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29083         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29084 }
29085 run_test 832 "lfs rm_entry"
29086
29087 #
29088 # tests that do cleanup/setup should be run at the end
29089 #
29090
29091 test_900() {
29092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29093         local ls
29094
29095         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29096         $LCTL set_param fail_loc=0x903
29097
29098         cancel_lru_locks MGC
29099
29100         FAIL_ON_ERROR=true cleanup
29101         FAIL_ON_ERROR=true setup
29102 }
29103 run_test 900 "umount should not race with any mgc requeue thread"
29104
29105 # LUS-6253/LU-11185
29106 test_901() {
29107         local old
29108         local count
29109         local oldc
29110         local newc
29111         local olds
29112         local news
29113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29114
29115         # some get_param have a bug to handle dot in param name
29116         cancel_lru_locks MGC
29117         old=$(mount -t lustre | wc -l)
29118         # 1 config+sptlrpc
29119         # 2 params
29120         # 3 nodemap
29121         # 4 IR
29122         old=$((old * 4))
29123         oldc=0
29124         count=0
29125         while [ $old -ne $oldc ]; do
29126                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29127                 sleep 1
29128                 ((count++))
29129                 if [ $count -ge $TIMEOUT ]; then
29130                         error "too large timeout"
29131                 fi
29132         done
29133         umount_client $MOUNT || error "umount failed"
29134         mount_client $MOUNT || error "mount failed"
29135         cancel_lru_locks MGC
29136         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29137
29138         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29139
29140         return 0
29141 }
29142 run_test 901 "don't leak a mgc lock on client umount"
29143
29144 # LU-13377
29145 test_902() {
29146         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29147                 skip "client does not have LU-13377 fix"
29148         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29149         $LCTL set_param fail_loc=0x1415
29150         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29151         cancel_lru_locks osc
29152         rm -f $DIR/$tfile
29153 }
29154 run_test 902 "test short write doesn't hang lustre"
29155
29156 # LU-14711
29157 test_903() {
29158         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29159         echo "blah" > $DIR/${tfile}-2
29160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29161         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29162         $LCTL set_param fail_loc=0x417 fail_val=20
29163
29164         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29165         sleep 1 # To start the destroy
29166         wait_destroy_complete 150 || error "Destroy taking too long"
29167         cat $DIR/$tfile > /dev/null || error "Evicted"
29168 }
29169 run_test 903 "Test long page discard does not cause evictions"
29170
29171 test_904() {
29172         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29173         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29174                 grep -q project || skip "skip project quota not supported"
29175
29176         local testfile="$DIR/$tdir/$tfile"
29177         local xattr="trusted.projid"
29178         local projid
29179         local mdts=$(comma_list $(mdts_nodes))
29180         local saved=$(do_facet mds1 $LCTL get_param -n \
29181                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29182
29183         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29184         stack_trap "do_nodes $mdts $LCTL set_param \
29185                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29186
29187         mkdir -p $DIR/$tdir
29188         touch $testfile
29189         #hide projid xattr on server
29190         $LFS project -p 1 $testfile ||
29191                 error "set $testfile project id failed"
29192         getfattr -m - $testfile | grep $xattr &&
29193                 error "do not show trusted.projid when disabled on server"
29194         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29195         #should be hidden when projid is 0
29196         $LFS project -p 0 $testfile ||
29197                 error "set $testfile project id failed"
29198         getfattr -m - $testfile | grep $xattr &&
29199                 error "do not show trusted.projid with project ID 0"
29200
29201         #still can getxattr explicitly
29202         projid=$(getfattr -n $xattr $testfile |
29203                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29204         [ $projid == "0" ] ||
29205                 error "projid expected 0 not $projid"
29206
29207         #set the projid via setxattr
29208         setfattr -n $xattr -v "1000" $testfile ||
29209                 error "setattr failed with $?"
29210         projid=($($LFS project $testfile))
29211         [ ${projid[0]} == "1000" ] ||
29212                 error "projid expected 1000 not $projid"
29213
29214         #check the new projid via getxattr
29215         $LFS project -p 1001 $testfile ||
29216                 error "set $testfile project id failed"
29217         getfattr -m - $testfile | grep $xattr ||
29218                 error "should show trusted.projid when project ID != 0"
29219         projid=$(getfattr -n $xattr $testfile |
29220                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29221         [ $projid == "1001" ] ||
29222                 error "projid expected 1001 not $projid"
29223
29224         #try to set invalid projid
29225         setfattr -n $xattr -v "4294967295" $testfile &&
29226                 error "set invalid projid should fail"
29227
29228         #remove the xattr means setting projid to 0
29229         setfattr -x $xattr $testfile ||
29230                 error "setfattr failed with $?"
29231         projid=($($LFS project $testfile))
29232         [ ${projid[0]} == "0" ] ||
29233                 error "projid expected 0 not $projid"
29234
29235         #should be hidden when parent has inherit flag and same projid
29236         $LFS project -srp 1002 $DIR/$tdir ||
29237                 error "set $tdir project id failed"
29238         getfattr -m - $testfile | grep $xattr &&
29239                 error "do not show trusted.projid with inherit flag"
29240
29241         #still can getxattr explicitly
29242         projid=$(getfattr -n $xattr $testfile |
29243                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29244         [ $projid == "1002" ] ||
29245                 error "projid expected 1002 not $projid"
29246 }
29247 run_test 904 "virtual project ID xattr"
29248
29249 # LU-8582
29250 test_905() {
29251         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29252                 skip "lustre < 2.8.54 does not support ladvise"
29253
29254         remote_ost_nodsh && skip "remote OST with nodsh"
29255         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29256
29257         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29258
29259         #define OBD_FAIL_OST_OPCODE 0x253
29260         # OST_LADVISE = 21
29261         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29262         $LFS ladvise -a willread $DIR/$tfile &&
29263                 error "unexpected success of ladvise with fault injection"
29264         $LFS ladvise -a willread $DIR/$tfile |&
29265                 grep -q "Operation not supported"
29266         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29267 }
29268 run_test 905 "bad or new opcode should not stuck client"
29269
29270 test_906() {
29271         grep -q io_uring_setup /proc/kallsyms ||
29272                 skip "Client OS does not support io_uring I/O engine"
29273         io_uring_probe || skip "kernel does not support io_uring fully"
29274         which fio || skip_env "no fio installed"
29275         fio --enghelp | grep -q io_uring ||
29276                 skip_env "fio does not support io_uring I/O engine"
29277
29278         local file=$DIR/$tfile
29279         local ioengine="io_uring"
29280         local numjobs=2
29281         local size=50M
29282
29283         fio --name=seqwrite --ioengine=$ioengine        \
29284                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29285                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29286                 error "fio seqwrite $file failed"
29287
29288         fio --name=seqread --ioengine=$ioengine \
29289                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29290                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29291                 error "fio seqread $file failed"
29292
29293         rm -f $file || error "rm -f $file failed"
29294 }
29295 run_test 906 "Simple test for io_uring I/O engine via fio"
29296
29297
29298 complete $SECONDS
29299 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29300 check_and_cleanup_lustre
29301 if [ "$I_MOUNTED" != "yes" ]; then
29302         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29303 fi
29304 exit_status